Browse Source

* removed hana code

master
bergmann 6 years ago
parent
commit
58e2e311ab
69 changed files with 1 additions and 3563 deletions
  1. +0
    -5
      src/cpputils/container.h
  2. +0
    -0
     
  3. +0
    -14
      src/cpputils/misc.h
  4. +1
    -5
      src/cpputils/mp.h
  5. +0
    -34
      src/cpputils/mp/LICENSE.md
  6. +0
    -2
      src/cpputils/mp/README.md
  7. +0
    -6
      src/cpputils/mp/container.h
  8. +0
    -159
      src/cpputils/mp/container/basic_tuple.h
  9. +0
    -36
      src/cpputils/mp/container/map.h
  10. +0
    -239
      src/cpputils/mp/container/pair.h
  11. +0
    -268
      src/cpputils/mp/container/type.h
  12. +0
    -11
      src/cpputils/mp/intern.h
  13. +0
    -39
      src/cpputils/mp/intern/comparable_equal.h
  14. +0
    -36
      src/cpputils/mp/intern/comparable_less.h
  15. +0
    -83
      src/cpputils/mp/intern/ebo.h
  16. +0
    -265
      src/cpputils/mp/intern/fold_left.h
  17. +0
    -244
      src/cpputils/mp/intern/fold_right.h
  18. +0
    -16
      src/cpputils/mp/intern/has_value.h
  19. +0
    -61
      src/cpputils/mp/intern/hash_table.h
  20. +0
    -36
      src/cpputils/mp/intern/operators_comparable.h
  21. +0
    -50
      src/cpputils/mp/intern/operators_orderable.h
  22. +0
    -8
      src/cpputils/mp/misc.h
  23. +0
    -33
      src/cpputils/mp/misc/default.h
  24. +0
    -38
      src/cpputils/mp/misc/is_a.h
  25. +0
    -55
      src/cpputils/mp/misc/make.h
  26. +0
    -35
      src/cpputils/mp/misc/tag_of.h
  27. +0
    -176
      src/cpputils/mp/misc/to.h
  28. +0
    -32
      src/cpputils/mp/misc/when.h
  29. +0
    -15
      src/cpputils/mp/operations.h
  30. +0
    -52
      src/cpputils/mp/operations/at.h
  31. +0
    -4
      src/cpputils/mp/operations/compare.h
  32. +0
    -73
      src/cpputils/mp/operations/compare/equal.h
  33. +0
    -51
      src/cpputils/mp/operations/compare/greater.h
  34. +0
    -51
      src/cpputils/mp/operations/compare/greater_equal.h
  35. +0
    -73
      src/cpputils/mp/operations/compare/less.h
  36. +0
    -51
      src/cpputils/mp/operations/compare/less_equal.h
  37. +0
    -51
      src/cpputils/mp/operations/compare/not_equal.h
  38. +0
    -59
      src/cpputils/mp/operations/eval.h
  39. +0
    -80
      src/cpputils/mp/operations/eval_if.h
  40. +0
    -46
      src/cpputils/mp/operations/first.h
  41. +0
    -28
      src/cpputils/mp/operations/hash.fwd.h
  42. +0
    -104
      src/cpputils/mp/operations/hash.h
  43. +0
    -18
      src/cpputils/mp/operations/if.fwd.h
  44. +0
    -52
      src/cpputils/mp/operations/if.h
  45. +0
    -56
      src/cpputils/mp/operations/length.h
  46. +0
    -4
      src/cpputils/mp/operations/logical.h
  47. +0
    -63
      src/cpputils/mp/operations/logical/and.h
  48. +0
    -55
      src/cpputils/mp/operations/logical/not.h
  49. +0
    -63
      src/cpputils/mp/operations/logical/or.h
  50. +0
    -46
      src/cpputils/mp/operations/second.h
  51. +0
    -68
      src/cpputils/mp/operations/transform.h
  52. +0
    -18
      src/cpputils/mp/operations/unpack.fwd.h
  53. +0
    -61
      src/cpputils/mp/operations/unpack.h
  54. +0
    -54
      src/cpputils/mp/operations/value.h
  55. +0
    -41
      test/mp/container/basic_tuple.cpp
  56. +0
    -61
      test/mp/container/pair.cpp
  57. +0
    -8
      test/mp/intern/comparable_equal.cpp
  58. +0
    -9
      test/mp/intern/ebo.cpp
  59. +0
    -10
      test/mp/intern/has_value.cpp
  60. +0
    -14
      test/mp/misc/default.cpp
  61. +0
    -18
      test/mp/misc/is_a.cpp
  62. +0
    -9
      test/mp/misc/make.cpp
  63. +0
    -27
      test/mp/misc/tag_of.cpp
  64. +0
    -39
      test/mp/misc/to.cpp
  65. +0
    -9
      test/mp/operations/compare/equal.cpp
  66. +0
    -9
      test/mp/operations/compare/less.cpp
  67. +0
    -9
      test/mp/operations/logical/and.cpp
  68. +0
    -9
      test/mp/operations/logical/or.cpp
  69. +0
    -9
      test/mp/operations/value.cpp

+ 0
- 5
src/cpputils/container.h View File

@@ -1,5 +0,0 @@
#pragma once

#include <cpputils/container/handle_manager.h>
#include <cpputils/container/nullable.h>
#include <cpputils/container/smart_ptr.h>

+ 0
- 0
View File


+ 0
- 14
src/cpputils/misc.h View File

@@ -1,14 +0,0 @@
#pragma once

#include <cpputils/misc/convert.h>
#include <cpputils/misc/enum.h>
#include <cpputils/misc/exception.h>
#include <cpputils/misc/flags.h>
#include <cpputils/misc/indent.h>
#include <cpputils/misc/misc.h>
#include <cpputils/misc/stream.h>
#include <cpputils/misc/string.h>
#include <cpputils/misc/time.h>
#include <cpputils/misc/transform_iterator.h>
#include <cpputils/misc/type_helper.h>
#include <cpputils/misc/wrapper.h>

+ 1
- 5
src/cpputils/mp.h View File

@@ -1,7 +1,3 @@
#pragma once

#include <cpputils/mp/core.h>
#include <cpputils/mp/misc.h>
#include <cpputils/mp/intern.h>
#include <cpputils/mp/container.h>
#include <cpputils/mp/operations.h>
#include <cpputils/mp/core.h>

+ 0
- 34
src/cpputils/mp/LICENSE.md View File

@@ -1,34 +0,0 @@
== License of this adaptation ==

Copyright Erik Junghanns.



== Original boost::hana license ==

Copyright Louis Dionne 2013-2017

Boost Software License - Version 1.0 - August 17th, 2003

Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:

The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.


+ 0
- 2
src/cpputils/mp/README.md View File

@@ -1,2 +0,0 @@
This is an adaptation of the boost::hana library.
See https://github.com/boostorg/hana

+ 0
- 6
src/cpputils/mp/container.h View File

@@ -1,6 +0,0 @@
#pragma once

#include <cpputils/mp/container/basic_tuple.h>
#include <cpputils/mp/container/map.h>
#include <cpputils/mp/container/pair.h>
#include <cpputils/mp/container/type.h>

+ 0
- 159
src/cpputils/mp/container/basic_tuple.h View File

@@ -1,159 +0,0 @@
#pragma once

#include <utility>
#include <cpputils/mp/core/modifier.h>
#include <cpputils/mp/core/conditionals.h>
#include <cpputils/mp/misc/make.h>
#include <cpputils/mp/misc/tag_of.h>
#include <cpputils/mp/intern/ebo.h>
#include <cpputils/mp/operations/at.h>
#include <cpputils/mp/operations/unpack.h>
#include <cpputils/mp/operations/transform.h>

namespace utl {
namespace mp {

struct tag_basic_tuple { };

namespace __impl
{
template<size_t>
struct basic_tuple_index;

template<typename Indices, typename... Xn>
struct basic_tuple_impl;

struct basic_tuple_from_other { };

template<size_t... N, typename... Xn>
struct basic_tuple_impl<std::index_sequence<N...>, Xn...>
: intern::ebo<basic_tuple_index<N>, Xn>...
{
static constexpr size_t _size = sizeof...(Xn);

constexpr basic_tuple_impl() = default;

template<typename Other>
explicit constexpr basic_tuple_impl(basic_tuple_from_other, Other&& other)
: intern::ebo<basic_tuple_index<N>, Xn>(intern::ebo_get<basic_tuple_index<N>>(std::forward<Other>(other)))...
{ }

template<typename... Yn>
explicit constexpr basic_tuple_impl(Yn&&... yn)
: intern::ebo<basic_tuple_index<N>, Xn>(std::forward<Yn>(yn))...
{ }
};
}

template<typename... Xn>
struct basic_tuple final
: __impl::basic_tuple_impl<std::make_index_sequence<sizeof...(Xn)>, Xn...>
{
using tag = tag_basic_tuple;
using base_type = __impl::basic_tuple_impl<std::make_index_sequence<sizeof...(Xn)>, Xn...>;

constexpr basic_tuple() = default;

template<typename Other, typename = enable_if<is_same<basic_tuple, decay_type<Other>>>>
constexpr basic_tuple(Other&& other)
: base_type(__impl::basic_tuple_from_other { }, std::forward<Other>(other))
{ }

template<typename... Yn>
explicit constexpr basic_tuple(Yn&&... yn)
: base_type(std::forward<Yn>(yn)...)
{ }

template<typename N>
constexpr auto at(const N& n) const
{ return mp::at(*this, n); }

template<typename F>
constexpr auto unpack(F&& f) const
{ return mp::unpack(*this, std::forward<F>(f)); }
template<typename F>
constexpr auto transform(F&& f) const
{ return mp::transform(*this, std::forward<F>(f)); }
};

constexpr auto make_basic_tuple = make<tag_basic_tuple>;

namespace __impl
{
/* tag_of */
template<typename... Xn>
struct tag_of_impl<basic_tuple<Xn...>>
{ using type = tag_basic_tuple; };

/* make */
template<>
struct make_impl<tag_basic_tuple>
{
template<typename... Xn>
static constexpr auto apply(Xn&&... xn)
{ return basic_tuple<decay_type<Xn>...> { std::forward<Xn>(xn)... }; }
};

/* unpack */
template<>
struct unpack_impl<tag_basic_tuple>
{
template<size_t... I, typename... Xn, typename F>
static constexpr auto apply(const basic_tuple_impl<std::index_sequence<I...>, Xn...>& xs, F&& f)
{
return std::forward<F>(f)(
intern::ebo_get<basic_tuple_index<I>>(
static_cast<const intern::ebo<basic_tuple_index<I>, Xn>&>(xs)
)...
);
}

template<size_t... I, typename... Xn, typename F>
static constexpr auto apply(basic_tuple_impl<std::index_sequence<I...>, Xn...>& xs, F&& f)
{
return std::forward<F>(f)(
intern::ebo_get<basic_tuple_index<I>>(
static_cast<intern::ebo<basic_tuple_index<I>, Xn>&>(xs)
)...
);
}

template<size_t... I, typename... Xn, typename F>
static constexpr auto apply(basic_tuple_impl<std::index_sequence<I...>, Xn...>&& xs, F&& f)
{
return std::forward<F>(f)(
intern::ebo_get<basic_tuple_index<I>>(
static_cast<intern::ebo<basic_tuple_index<I>, Xn>&&>(xs)
)...
);
}
};

/* at */
template<>
struct at_impl<tag_basic_tuple>
{
template<typename Xs, typename N>
static constexpr auto apply(Xs&& xs, const N&)
{
constexpr size_t index = N::value;
return intern::ebo_get<basic_tuple_index<index>>(std::forward<Xs>(xs));
}
};
}

template <size_t N, typename... Xn>
constexpr auto at_c(const basic_tuple<Xn...>& x)
{ return intern::ebo_get<__impl::basic_tuple_index<N>>(x); }

template <size_t N, typename... Xn>
constexpr auto at_c(basic_tuple<Xn...>& x)
{ return intern::ebo_get<__impl::basic_tuple_index<N>>(x); }

template <size_t N, typename... Xn>
constexpr auto at_c(basic_tuple<Xn...>&& x)
{ return intern::ebo_get<__impl::basic_tuple_index<N>>(std::forward<basic_tuple<Xn...>>(x)); }

}
}

+ 0
- 36
src/cpputils/mp/container/map.h View File

@@ -1,36 +0,0 @@
#pragma once

#include <cpputils/mp/misc/to.h>
#include <cpputils/mp/misc/make.h>
#include <cpputils/mp/container/basic_tuple.h>

namespace utl {
namespace mp {

struct tag_map { };

constexpr auto make_map = make<tag_map>;

constexpr auto to_map = make<tag_map>;

namespace __impl /* forward declaration */
{
template<typename... Pairs>
struct make_map_type;
}

template<typename... Pairs>
using map = typename __impl::make_map_type<Pairs...>::type;

namespace __impl /* implementation */
{
template<typename... Pairs>
struct make_map_type
{
using storage_type = basic_tuple<Pairs...>;
};
}

}
}

+ 0
- 239
src/cpputils/mp/container/pair.h View File

@@ -1,239 +0,0 @@
#pragma once

#include <cpputils/mp/core.h>
#include <cpputils/mp/misc/make.h>
#include <cpputils/mp/misc/tag_of.h>
#include <cpputils/mp/intern/ebo.h>
#include <cpputils/mp/intern/operators_orderable.h>
#include <cpputils/mp/intern/operators_comparable.h>
#include <cpputils/mp/operations/first.h>
#include <cpputils/mp/operations/second.h>
#include <cpputils/mp/operations/compare/less.h>
#include <cpputils/mp/operations/compare/less_equal.h>
#include <cpputils/mp/operations/compare/equal.h>
#include <cpputils/mp/operations/logical/or.h>
#include <cpputils/mp/operations/logical/and.h>
#include <cpputils/mp/operations/logical/not.h>

namespace utl {
namespace mp {

struct tag_pair { };

constexpr auto make_pair = make<tag_pair>;

namespace __impl
{
template<int>
struct pair_index;
}

template<typename First, typename Second>
struct pair :
private intern::ebo<__impl::pair_index<0>, First>,
private intern::ebo<__impl::pair_index<1>, Second>
{
using tag = tag_pair;
using this_type = pair<First, Second>;

// default constructor
template<typename... dummy, typename = enable_if_c<
is_constructible<First, dummy...>::value &&
is_constructible<Second, dummy...>::value>>
constexpr pair()
: intern::ebo<__impl::pair_index<0>, First>()
, intern::ebo<__impl::pair_index<1>, Second>()
{ }

// variadic constructors
template<typename... dummy, typename = enable_if_c<
is_constructible<First, const First&, dummy...>::value &&
is_constructible<Second, const Second&, dummy...>::value>>
constexpr pair(First f, Second s)
: intern::ebo<__impl::pair_index<0>, First>(f)
, intern::ebo<__impl::pair_index<1>, Second>(s)
{ }

template<typename F, typename S, typename = enable_if_c<
is_convertible<F&&, First>::value &&
is_convertible<S&&, Second>::value>>
constexpr pair(F&& f, S&& s)
: intern::ebo<__impl::pair_index<0>, First>(std::forward<F>(f))
, intern::ebo<__impl::pair_index<1>, Second>(std::forward<S>(s))
{ }

// copy and move constructor
template<typename F, typename S, typename = enable_if_c<
is_constructible<First, const F&>::value &&
is_constructible<Second, const S&>::value &&
is_convertible<const F&, First>::value &&
is_convertible<const S&, Second>::value>>
constexpr pair(const pair<F, S>& other)
: intern::ebo<__impl::pair_index<0>, First>(mp::first(other))
, intern::ebo<__impl::pair_index<1>, Second>(mp::second(other))
{ }

template<typename F, typename S, typename = enable_if_c<
is_constructible<First, const F&>::value &&
is_constructible<Second, const S&>::value &&
is_convertible<const F&, First>::value &&
is_convertible<const S&, Second>::value>>
constexpr pair(pair<F, S>&& other)
: intern::ebo<__impl::pair_index<0>, First>(mp::first(std::forward<pair<F, S>>(other)))
, intern::ebo<__impl::pair_index<1>, Second>(mp::second(std::forward<pair<F, S>>(other)))
{ }

// copy and move assignment
template <typename F, typename S, typename = enable_if_c<
is_assignable<First&, const F&>::value &&
is_assignable<Second&, const S&>::value>>
constexpr pair& operator=(const pair<F, S>& other) {
mp::first(*this) = mp::first(other);
mp::second(*this) = mp::second(other);
return *this;
}

template <typename F, typename S, typename = enable_if_c<
is_assignable<First&, const F &>::value &&
is_assignable<Second&, const S &>::value>>
constexpr pair& operator=(pair<F, S>&& other) {
mp::first(*this) = mp::first(std::move<pair<F, S>>(other));
mp::second(*this) = mp::second(std::move<pair<F, S>>(other));
return *this;
}

constexpr auto first() const
{ return mp::first(*this); }

constexpr auto second() const
{ return mp::second(*this); }

// Prevent the compiler from defining the default copy and move
// constructors, which interfere with the SFINAE above.
~pair() = default;

friend struct __impl::first_impl<tag_pair>;
friend struct __impl::second_impl<tag_pair>;
};

namespace intern {

template<>
struct operators_comparable<tag_pair>
{ static constexpr bool value = true; };

template<>
struct operators_orderable<tag_pair>
{ static constexpr bool value = true; };

}

namespace __impl
{
/* tag_of */
template<typename First, typename Second>
struct tag_of_impl<pair<First, Second>>
{ using type = tag_pair; };

/* make */
template<>
struct make_impl<tag_pair>
{
template<typename F, typename S>
static constexpr pair<decay_type<F>, decay_type<S>> apply(F&& f, S&& s)
{ return { static_cast<F&&>(f), static_cast<S&&>(s) }; }
};

/* first */
template<>
struct first_impl<tag_pair>
{
using type = int;

template<typename First, typename Second>
static constexpr auto apply(pair<First, Second>& p)
{
return intern::ebo_get<pair_index<0>>(
static_cast<intern::ebo<pair_index<0>, First>&>(p)
);
}

template<typename First, typename Second>
static constexpr auto apply(pair<First, Second>&& p)
{
return intern::ebo_get<pair_index<0>>(
static_cast<intern::ebo<pair_index<0>, First>&&>(p)
);
}

template<typename First, typename Second>
static constexpr auto apply(const pair<First, Second>& p)
{
return intern::ebo_get<pair_index<0>>(
static_cast<const intern::ebo<pair_index<0>, First>&>(p)
);
}
};

/* second */
template<>
struct second_impl<tag_pair>
{
template<typename First, typename Second>
static constexpr auto apply(pair<First, Second>& p)
{
return intern::ebo_get<pair_index<1>>(
static_cast<intern::ebo<pair_index<1>, Second>&>(p)
);
}

template<typename First, typename Second>
static constexpr auto apply(pair<First, Second>&& p)
{
return intern::ebo_get<pair_index<1>>(
static_cast<intern::ebo<pair_index<1>, Second>&&>(p)
);
}

template<typename First, typename Second>
static constexpr auto apply(const pair<First, Second>& p)
{
return intern::ebo_get<pair_index<1>>(
static_cast<const intern::ebo<pair_index<1>, Second>&>(p)
);
}
};

/* equal */
template<>
struct equal_impl<tag_pair, tag_pair>
{
template<typename L, typename R>
static constexpr auto apply(const L& l, const R& r)
{
return and_(
equal(first(l), first(r)),
equal(second(l), second(r)));
}
};

/* less */
template<>
struct less_impl<tag_pair, tag_pair>
{
template<typename L, typename R>
static constexpr auto apply(const L& l, const R& r)
{
return or_(
less(first(l), first(r)),
and_(
less_equal(first (l), first (r)),
less (second(l), second(r))
)
);
}
};
}

}
}

+ 0
- 268
src/cpputils/mp/container/type.h View File

@@ -1,268 +0,0 @@
#pragma once

#include <utility>
#include <cpputils/mp/misc/make.h>
#include <cpputils/mp/core/const.h>
#include <cpputils/mp/core/modifier.h>
#include <cpputils/mp/operations/hash.fwd.h>
#include <cpputils/mp/intern/operators_comparable.h>

namespace utl {
namespace mp {

namespace __impl /* forward declaration */
{
template<typename T>
struct type_impl;

struct decl_type_t
{
template<typename T>
constexpr auto operator()(T&& t) const;
};

struct type_id_t
{
template <typename T>
constexpr auto operator()(T&&) const;
};

struct size_of_t
{
template <typename T>
constexpr auto operator()(T&&) const;
};

struct align_of_t
{
template <typename T>
constexpr auto operator()(T&&) const;
};

struct is_valid_type_t
{
template <typename F>
constexpr auto operator()(F&&) const;

template <typename F, typename ...Args>
constexpr auto operator()(F&&, Args&&...) const;
};

template <template <typename ...> class F>
struct tmplt_t;

template <template <typename ...> class F>
struct metafunction_t;

template <typename F>
struct metafunction_class_t
: metafunction_t<F::template apply>
{ };

template <typename F>
struct integral_t;

struct make_integral_t
{
template <typename F>
constexpr integral_t<F> operator()(F const&) const
{ return { }; }
};
}

struct tag_type { };

template<typename T>
using type = typename __impl::type_impl<T>::type;

template<typename T>
constexpr type<T> type_c { };

constexpr auto make_mp_type = make<tag_type>;

constexpr __impl::decl_type_t decl_type { };

constexpr __impl::type_id_t type_id { };

constexpr __impl::size_of_t size_of { };

constexpr __impl::align_of_t align_of { };

constexpr __impl::is_valid_type_t is_valid_type { };

template <template <typename ...> class F>
constexpr __impl::tmplt_t<F> tmplt { };

template <template <typename ...> class F>
constexpr __impl::metafunction_t<F> metafunction { };

template <typename F>
constexpr __impl::metafunction_class_t<F> metafunction_class { };

constexpr __impl::make_integral_t integral { };

template <template <typename ...> class F>
constexpr auto trait = integral(metafunction<F>);

namespace __impl /* implementation */
{
/* basic_type */
template<typename T>
struct basic_type
{
using tag = tag_type;
using type = T;

constexpr auto operator+() const
{ return *this; }
};

/* type */
template<typename T>
struct type_impl
{
struct type : basic_type<T>
{ };
};

/* decl_type */
template <typename T, typename = tag_type>
struct decltype_helper
{ using type = remove_ref<T>; };

template <typename T>
struct decltype_helper<T, tag_of<T>>
{ using type = typename remove_ref<T>::type; };

template<typename T>
constexpr auto decl_type_t::operator()(T&& t) const
{ return type_c<typename decltype_helper<T>::type>; }
/* type_id */
template <typename T, typename = tag_type>
struct typeid_helper
{ using type = clean_type<T>; };

template <typename T>
struct typeid_helper<T, tag_of<T>>
{ using type = typename remove_ref<T>::type; };

template <typename T>
constexpr auto type_id_t::operator()(T&&) const
{ return type_c<typename typeid_helper<T>::type>; }

/* make */
template <>
struct make_impl<tag_type>
{
template <typename T>
static constexpr auto apply(T&& t)
{ return type_id(std::forward<T>(t)); }
};

/* size_of */
template <typename T>
constexpr auto size_of_t::operator()(T&&) const
{ return c_size_t<sizeof(typename decltype_helper<T>::type)> { }; }
/* align_of */
template <typename T>
constexpr auto align_of_t::operator()(T&&) const
{ return c_size_t<alignof(typename decltype_helper<T>::type)> { }; }
/* is_valid_type */
template<typename F, typename... Args, typename = decltype(std::declval<F&&>()(std::declval<Args&&>()...))>
constexpr auto is_valid_type_impl(int)
{ return c_true; }

template<typename F, typename... Args>
constexpr auto is_valid_type_impl(...)
{ return c_false; }

template<typename F>
struct is_valid_type_helper
{
template<typename... Args>
constexpr auto operator()(Args&&...) const
{ return is_valid_type_impl<F, Args&&...>(int { }); }
};

template <typename F>
constexpr auto is_valid_type_t::operator()(F&&) const
{ return is_valid_type_helper<F&&> { }; }

template <typename F, typename ...Args>
constexpr auto is_valid_type_t::operator()(F&&, Args&&...) const
{ return is_valid_type_impl<F&&, Args&&...>(int { }); }

/* tmplt */
template <template <typename ...> class F>
struct tmplt_t
{
template<typename... T>
struct apply
{ using type = F<T...>; };
template<typename... T>
constexpr auto operator()(const T&...) const
{ return type<F<typename T::type...>> { }; }
};

/* metafunction */
template <template <typename ...> class F>
struct metafunction_t
{
template<typename... T>
using apply = F<T...>;

template<typename... T>
constexpr type<typename F<typename T::type...>::type> operator()(const T&...) const
{ return { }; }
};

/* integral */
template <typename F>
struct integral_t
{
template<typename... T>
constexpr auto operator()(const T& ...) const
{
using result_type = typename F::template apply<typename T::type...>::type;
return result_type { };
}
};

/* equal */
template <>
struct equal_impl<tag_type, tag_type>
{
template <typename T, typename U>
static constexpr auto apply(const basic_type<T>&, const basic_type<U>&)
{ return c_false; }

template <typename T>
static constexpr auto apply(const basic_type<T>&, const basic_type<T>&)
{ return c_true; }
};

/* hash */
template<>
struct hash_impl<tag_type>
{
template <typename T>
static constexpr T apply(const T& t)
{ return t; }
};

}

namespace intern {

template<>
struct operators_comparable<tag_type>
{ static constexpr bool value = true; };

}

}
}

+ 0
- 11
src/cpputils/mp/intern.h View File

@@ -1,11 +0,0 @@
#pragma once

#include <cpputils/mp/intern/comparable_equal.h>
#include <cpputils/mp/intern/comparable_less.h>
#include <cpputils/mp/intern/ebo.h>
#include <cpputils/mp/intern/fold_left.h>
#include <cpputils/mp/intern/fold_right.h>
#include <cpputils/mp/intern/has_value.h>
#include <cpputils/mp/intern/hash_table.h>
#include <cpputils/mp/intern/operators_comparable.h>
#include <cpputils/mp/intern/operators_orderable.h>

+ 0
- 39
src/cpputils/mp/intern/comparable_equal.h View File

@@ -1,39 +0,0 @@
#pragma once

#include <utility>
#include <cpputils/mp/core.h>

namespace utl {
namespace mp {
namespace intern {

template<typename T, typename U = T, typename = void>
struct comparable_equal
: c_false_t
{ };

template<typename T>
struct comparable_equal<T, T, void_t<
decltype(std::forward<T>(std::declval<T>()) == std::forward<T>(std::declval<T>()) ? 0 : 0),
decltype(std::forward<T>(std::declval<T>()) != std::forward<T>(std::declval<T>()) ? 0 : 0)>>
: c_true_t
{ };

template <typename T, typename U>
struct comparable_equal<T, U, enable_if_c<
!is_same<T, U>::value,
void_t<
decltype(std::forward<T>(std::declval<T>()) == std::forward<U>(std::declval<U>()) ? 0 : 0),
decltype(std::forward<U>(std::declval<U>()) == std::forward<T>(std::declval<T>()) ? 0 : 0),
decltype(std::forward<T>(std::declval<T>()) != std::forward<U>(std::declval<U>()) ? 0 : 0),
decltype(std::forward<U>(std::declval<U>()) != std::forward<T>(std::declval<T>()) ? 0 : 0),
common_type<T, U>>>>
: c_bool_t<
comparable_equal<T>::value &&
comparable_equal<U>::value &&
comparable_equal<common_type<T, U>>::value>
{ };

}
}
}

+ 0
- 36
src/cpputils/mp/intern/comparable_less.h View File

@@ -1,36 +0,0 @@
#pragma once

#include <utility>
#include <cpputils/mp/core.h>

namespace utl {
namespace mp {
namespace intern {

template<typename T, typename U = T, typename = void>
struct comparable_less
: c_false_t
{ };

template<typename T>
struct comparable_less<T, T, void_t<
decltype(std::forward<T>(std::declval<T>()) < std::forward<T>(std::declval<T>()) ? 0 : 0)>>
: c_true_t
{ };

template <typename T, typename U>
struct comparable_less<T, U, enable_if_c<
!is_same<T, U>::value,
void_t<
decltype(std::forward<T>(std::declval<T>()) < std::forward<U>(std::declval<U>()) ? 0 : 0),
decltype(std::forward<U>(std::declval<U>()) < std::forward<T>(std::declval<T>()) ? 0 : 0),
common_type<T, U>>>>
: c_bool_t<
comparable_less<T>::value &&
comparable_less<U>::value &&
comparable_less<common_type<T, U>>::value>
{ };

}
}
}

+ 0
- 83
src/cpputils/mp/intern/ebo.h View File

@@ -1,83 +0,0 @@
#pragma once

#include "../core.h"

namespace utl {
namespace mp {
namespace intern {

template<typename Key, typename Value, bool = is_empty<Value>::value && !is_final<Value>::value>
struct ebo;

template<typename Key, typename Value>
constexpr const Value& ebo_get(const ebo<Key, Value, true>& x)
{ return x; }

template<typename Key, typename Value>
constexpr Value& ebo_get(ebo<Key, Value, true>& x)
{ return x; }

template<typename Key, typename Value>
constexpr Value&& ebo_get(ebo<Key, Value, true>&& x)
{ return x; }

template<typename Key, typename Value>
constexpr const Value& ebo_get(const ebo<Key, Value, false>& x)
{ return x._data; }

template<typename Key, typename Value>
constexpr Value& ebo_get(ebo<Key, Value, false>& x)
{ return x._data; }

template<typename Key, typename Value>
constexpr Value&& ebo_get(ebo<Key, Value, false>&& x)
{ return static_cast<Value&&>(x._data); }

template<typename Key, typename Value>
struct ebo<Key, Value, true> :
public Value
{
constexpr ebo()
{ }

template<typename T>
explicit constexpr ebo(T&& t) :
Value(std::forward<T>(t))
{ }

constexpr auto get() const&
{ return ebo_get(*this); }

constexpr auto get() &
{ return ebo_get(*this); }

constexpr auto get() &&
{ return ebo_get(std::move(*this)); }
};

template<typename Key, typename Value>
struct ebo<Key, Value, false>
{
Value _data;

constexpr ebo()
{ }

template<typename T>
explicit constexpr ebo(T&& t) :
_data(std::forward<T>(t))
{ }

constexpr auto get() const&
{ return ebo_get(*this); }

constexpr auto get() &
{ return ebo_get(*this); }

constexpr auto get() &&
{ return ebo_get(std::move(*this)); }
};

}
}
}

+ 0
- 265
src/cpputils/mp/intern/fold_left.h View File

@@ -1,265 +0,0 @@
#pragma once

#include <utility>
#include <cpputils/mp/misc/when.h>

namespace utl {
namespace mp {
namespace intern {

namespace __impl
{
template <unsigned int n, typename = when<true>>
struct fold_left_impl;

template<>
struct fold_left_impl<1>
{
template<typename F, typename X1>
static constexpr X1 apply(F&&, X1&& x1)
{ return std::forward<X1>(x1); }
};

template<>
struct fold_left_impl<2>
{
template<typename F, typename X1, typename X2>
static constexpr auto apply(F&& f, X1&& x1, X2&& x2)
{
return f(
std::forward<X1>(x1),
std::forward<X2>(x2));
}
};

template<>
struct fold_left_impl<3>
{
template<typename F, typename X1, typename X2, typename X3>
static constexpr auto apply(F&& f, X1&& x1, X2&& x2, X3&& x3)
{
return f(f(
std::forward<X1>(x1),
std::forward<X2>(x2)),
std::forward<X3>(x3));
}
};

template<>
struct fold_left_impl<4>
{
template<typename F, typename X1, typename X2, typename X3, typename X4>
static constexpr auto apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4)
{
return f(f(f(
std::forward<X1>(x1),
std::forward<X2>(x2)),
std::forward<X3>(x3)),
std::forward<X4>(x4));
}
};

template<>
struct fold_left_impl<5>
{
template<typename F, typename X1, typename X2, typename X3, typename X4, typename X5>
static constexpr auto apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5)
{
return f(f(f(f(
std::forward<X1>(x1),
std::forward<X2>(x2)),
std::forward<X3>(x3)),
std::forward<X4>(x4)),
std::forward<X5>(x5));
}
};

template<>
struct fold_left_impl<6>
{
template<typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6>
static constexpr auto apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6)
{
return f(f(f(f(f(
std::forward<X1>(x1),
std::forward<X2>(x2)),
std::forward<X3>(x3)),
std::forward<X4>(x4)),
std::forward<X5>(x5)),
std::forward<X6>(x6));
}
};

template<>
struct fold_left_impl<7>
{
template<typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7>
static constexpr auto apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7)
{
return f(f(f(f(f(f(
std::forward<X1>(x1),
std::forward<X2>(x2)),
std::forward<X3>(x3)),
std::forward<X4>(x4)),
std::forward<X5>(x5)),
std::forward<X6>(x6)),
std::forward<X7>(x7));
}
};

template<>
struct fold_left_impl<8>
{
template<typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7, typename X8>
static constexpr auto apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7, X8&& x8)
{
return f(f(f(f(f(f(f(
std::forward<X1>(x1),
std::forward<X2>(x2)),
std::forward<X3>(x3)),
std::forward<X4>(x4)),
std::forward<X5>(x5)),
std::forward<X6>(x6)),
std::forward<X7>(x7)),
std::forward<X8>(x8));
}
};

template<unsigned int n>
struct fold_left_impl<n, when<(n >= 9) && (n < 18)>>
{
template<typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7, typename X8, typename X9, typename... Xn>
static constexpr auto apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7, X8&& x8, X9&& x9, Xn&&... xn)
{
return fold_left_impl<sizeof...(xn) + 1>::apply(
f,
f(f(f(f(f(f(f(f(
std::forward<X1>(x1),
std::forward<X2>(x2)),
std::forward<X3>(x3)),
std::forward<X4>(x4)),
std::forward<X5>(x5)),
std::forward<X6>(x6)),
std::forward<X7>(x7)),
std::forward<X8>(x8)),
std::forward<X9>(x9)),
std::forward<Xn>(xn)...
);
}
};

template<unsigned int n>
struct fold_left_impl<n, when<(n >= 18) && (n < 36)>>
{
template<
typename F,
typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7, typename X8, typename X9,
typename X10, typename X11, typename X12, typename X13, typename X14, typename X15, typename X16, typename X17, typename X18,
typename... Xn>
static constexpr auto apply(
F&& f,
X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7, X8&& x8, X9&& x9,
X10&& x10, X11&& x11, X12&& x12, X13&& x13, X14&& x14, X15&& x15, X16&& x16, X17&& x17, X18&& x18,
Xn&&... xn)
{
return fold_left_impl<sizeof...(xn) + 1>::apply(
f,
f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(
std::forward<X1> (x1),
std::forward<X2> (x2)),
std::forward<X3> (x3)),
std::forward<X4> (x4)),
std::forward<X5> (x5)),
std::forward<X6> (x6)),
std::forward<X7> (x7)),
std::forward<X8> (x8)),
std::forward<X9> (x9)),
std::forward<X10>(x10)),
std::forward<X11>(x11)),
std::forward<X12>(x12)),
std::forward<X13>(x13)),
std::forward<X14>(x14)),
std::forward<X15>(x15)),
std::forward<X16>(x16)),
std::forward<X17>(x17)),
std::forward<X18>(x18)),
std::forward<Xn>(xn)...
);
}
};

template<unsigned int n>
struct fold_left_impl<n, when<(n >= 36)>>
{
template<
typename F,
typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7, typename X8, typename X9,
typename X10, typename X11, typename X12, typename X13, typename X14, typename X15, typename X16, typename X17, typename X18,
typename X19, typename X20, typename X21, typename X22, typename X23, typename X24, typename X25, typename X26, typename X27,
typename X28, typename X29, typename X30, typename X31, typename X32, typename X33, typename X34, typename X35, typename X36,
typename... Xn>
static constexpr auto apply(
F&& f,
X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7, X8&& x8, X9&& x9,
X10&& x10, X11&& x11, X12&& x12, X13&& x13, X14&& x14, X15&& x15, X16&& x16, X17&& x17, X18&& x18,
X19&& x19, X20&& x20, X21&& x21, X22&& x22, X23&& x23, X24&& x24, X25&& x25, X26&& x26, X27&& x27,
X28&& x28, X29&& x29, X30&& x30, X31&& x31, X32&& x32, X33&& x33, X34&& x34, X35&& x35, X36&& x36,
Xn&&... xn)
{
return fold_left_impl<sizeof...(xn) + 1>::apply(
f,
f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(
std::forward<X1> (x1),
std::forward<X2> (x2)),
std::forward<X3> (x3)),
std::forward<X4> (x4)),
std::forward<X5> (x5)),
std::forward<X6> (x6)),
std::forward<X7> (x7)),
std::forward<X8> (x8)),
std::forward<X9> (x9)),
std::forward<X10>(x10)),
std::forward<X11>(x11)),
std::forward<X12>(x12)),
std::forward<X13>(x13)),
std::forward<X14>(x14)),
std::forward<X15>(x15)),
std::forward<X16>(x16)),
std::forward<X17>(x17)),
std::forward<X18>(x18)),
std::forward<X19>(x19)),
std::forward<X20>(x20)),
std::forward<X21>(x21)),
std::forward<X22>(x22)),
std::forward<X23>(x23)),
std::forward<X24>(x24)),
std::forward<X25>(x25)),
std::forward<X26>(x26)),
std::forward<X27>(x27)),
std::forward<X28>(x28)),
std::forward<X29>(x29)),
std::forward<X30>(x30)),
std::forward<X31>(x31)),
std::forward<X32>(x32)),
std::forward<X33>(x33)),
std::forward<X34>(x34)),
std::forward<X35>(x35)),
std::forward<X36>(x36)),
std::forward<Xn>(xn)...
);
}
};

struct fold_left_t
{
template<typename F, typename X1, typename... Xn>
constexpr auto operator()(F&& f, X1&& x1, Xn&&... xn) const
{ return fold_left_impl<sizeof...(xn) + 1>::apply(std::forward<F>(f), std::forward<X1>(x1), std::forward<Xn>(xn)...); }
};
}

constexpr __impl::fold_left_t fold_left { };

}
}
}

+ 0
- 244
src/cpputils/mp/intern/fold_right.h View File

@@ -1,244 +0,0 @@
#pragma once

#include <utility>
#include <cpputils/mp/misc/when.h>

namespace utl {
namespace mp {
namespace intern {

namespace __impl
{
template <unsigned int n, typename = when<true>>
struct fold_right_impl;

template<>
struct fold_right_impl<1>
{
template<typename F, typename X1>
static constexpr X1 apply(F&&, X1&& x1)
{ return std::forward<X1>(x1); }
};

template<>
struct fold_right_impl<2>
{
template<typename F, typename X1, typename X2>
static constexpr auto apply(F&& f, X1&& x1, X2&& x2)
{
return f(
std::forward<X1>(x1),
std::forward<X2>(x2));
}
};

template<>
struct fold_right_impl<3>
{
template<typename F, typename X1, typename X2, typename X3>
static constexpr auto apply(F&& f, X1&& x1, X2&& x2, X3&& x3)
{
return f(std::forward<X1>(x1),
f(std::forward<X2>(x2),
std::forward<X3>(x3)));
}
};

template<>
struct fold_right_impl<4>
{
template<typename F, typename X1, typename X2, typename X3, typename X4>
static constexpr auto apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4)
{
return f(std::forward<X1>(x1),
f(std::forward<X2>(x2),
f(std::forward<X3>(x3),
std::forward<X4>(x4))));
}
};

template<>
struct fold_right_impl<5>
{
template<typename F, typename X1, typename X2, typename X3, typename X4, typename X5>
static constexpr auto apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5)
{
return f(std::forward<X1>(x1),
f(std::forward<X2>(x2),
f(std::forward<X3>(x3),
f(std::forward<X4>(x4),
std::forward<X5>(x5)))));
}
};

template<>
struct fold_right_impl<6>
{
template<typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6>
static constexpr auto apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6)
{
return f(std::forward<X1>(x1),
f(std::forward<X2>(x2),
f(std::forward<X3>(x3),
f(std::forward<X4>(x4),
f(std::forward<X5>(x5),
std::forward<X6>(x6))))));
}
};

template<>
struct fold_right_impl<7>
{
template<typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7>
static constexpr auto apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7)
{
return f(std::forward<X1>(x1),
f(std::forward<X2>(x2),
f(std::forward<X3>(x3),
f(std::forward<X4>(x4),
f(std::forward<X5>(x5),
f(std::forward<X6>(x6),
std::forward<X7>(x7)))))));
}
};

template<>
struct fold_right_impl<8>
{
template<typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7, typename X8>
static constexpr auto apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7, X8&& x8)
{
return f(std::forward<X1>(x1),
f(std::forward<X2>(x2),
f(std::forward<X3>(x3),
f(std::forward<X4>(x4),
f(std::forward<X5>(x5),
f(std::forward<X6>(x6),
f(std::forward<X7>(x7),
std::forward<X8>(x8))))))));
}
};

template<unsigned int n>
struct fold_right_impl<n, when<(n >= 9) && (n < 18)>>
{
template<typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7, typename X8, typename X9, typename... Xn>
static constexpr auto apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7, X8&& x8, X9&& x9, Xn&&... xn)
{
return f(std::forward<X1>(x1),
f(std::forward<X2>(x2),
f(std::forward<X3>(x3),
f(std::forward<X4>(x4),
f(std::forward<X5>(x5),
f(std::forward<X6>(x6),
f(std::forward<X7>(x7),
f(std::forward<X8>(x8),
fold_right_impl<sizeof...(xn) + 1>::apply(f, std::forward<X9>(x9), std::forward<Xn>(xn)...)))))))));
}
};

template<unsigned int n>
struct fold_right_impl<n, when<(n >= 18) && (n < 36)>>
{
template<
typename F,
typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7, typename X8, typename X9,
typename X10, typename X11, typename X12, typename X13, typename X14, typename X15, typename X16, typename X17, typename X18,
typename... Xn>
static constexpr auto apply(
F&& f,
X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7, X8&& x8, X9&& x9,
X10&& x10, X11&& x11, X12&& x12, X13&& x13, X14&& x14, X15&& x15, X16&& x16, X17&& x17, X18&& x18,
Xn&&... xn)
{
return f(std::forward<X1> (x1),
f(std::forward<X2> (x2),
f(std::forward<X3> (x3),
f(std::forward<X4> (x4),
f(std::forward<X5> (x5),
f(std::forward<X6> (x6),
f(std::forward<X7> (x7),
f(std::forward<X8> (x8),
f(std::forward<X9> (x9),
f(std::forward<X10>(x10),
f(std::forward<X11>(x11),
f(std::forward<X12>(x12),
f(std::forward<X13>(x13),
f(std::forward<X14>(x14),
f(std::forward<X15>(x15),
f(std::forward<X16>(x16),
f(std::forward<X17>(x17),
fold_right_impl<sizeof...(xn) + 1>::apply(f, std::forward<X18>(x18), std::forward<Xn>(xn)...))))))))))))))))));
}
};

template<unsigned int n>
struct fold_right_impl<n, when<(n >= 36)>>
{
template<
typename F,
typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7, typename X8, typename X9,
typename X10, typename X11, typename X12, typename X13, typename X14, typename X15, typename X16, typename X17, typename X18,
typename X19, typename X20, typename X21, typename X22, typename X23, typename X24, typename X25, typename X26, typename X27,
typename X28, typename X29, typename X30, typename X31, typename X32, typename X33, typename X34, typename X35, typename X36,
typename... Xn>
static constexpr auto apply(
F&& f,
X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7, X8&& x8, X9&& x9,
X10&& x10, X11&& x11, X12&& x12, X13&& x13, X14&& x14, X15&& x15, X16&& x16, X17&& x17, X18&& x18,
X19&& x19, X20&& x20, X21&& x21, X22&& x22, X23&& x23, X24&& x24, X25&& x25, X26&& x26, X27&& x27,
X28&& x28, X29&& x29, X30&& x30, X31&& x31, X32&& x32, X33&& x33, X34&& x34, X35&& x35, X36&& x36,
Xn&&... xn)
{
return f(std::forward<X1> (x1),
f(std::forward<X2> (x2),
f(std::forward<X3> (x3),
f(std::forward<X4> (x4),
f(std::forward<X5> (x5),
f(std::forward<X6> (x6),
f(std::forward<X7> (x7),
f(std::forward<X8> (x8),
f(std::forward<X9> (x9),
f(std::forward<X10>(x10),
f(std::forward<X11>(x11),
f(std::forward<X12>(x12),
f(std::forward<X13>(x13),
f(std::forward<X14>(x14),
f(std::forward<X15>(x15),
f(std::forward<X16>(x16),
f(std::forward<X17>(x17),
f(std::forward<X18>(x18),
f(std::forward<X19>(x19),
f(std::forward<X20>(x20),
f(std::forward<X21>(x21),
f(std::forward<X22>(x22),
f(std::forward<X23>(x23),
f(std::forward<X24>(x24),
f(std::forward<X25>(x25),
f(std::forward<X26>(x26),
f(std::forward<X27>(x27),
f(std::forward<X28>(x28),
f(std::forward<X29>(x29),
f(std::forward<X30>(x30),
f(std::forward<X31>(x31),
f(std::forward<X32>(x32),
f(std::forward<X33>(x33),
f(std::forward<X34>(x34),
f(std::forward<X35>(x35),
fold_right_impl<sizeof...(xn) + 1>::apply(f, std::forward<X36>(x36), std::forward<Xn>(xn)...))))))))))))))))))))))))))))))))))));
}
};

struct fold_right_t
{
template<typename F, typename X1, typename... Xn>
constexpr auto operator()(F&& f, X1&& x1, Xn&&... xn) const
{ return fold_right_impl<sizeof...(xn) + 1>::apply(std::forward<F>(f), std::forward<X1>(x1), std::forward<Xn>(xn)...); }
};
}

constexpr __impl::fold_right_t fold_right { };

}
}
}

+ 0
- 16
src/cpputils/mp/intern/has_value.h View File

@@ -1,16 +0,0 @@
#pragma once

#include <cpputils/mp/operations/value.h>

namespace utl {
namespace mp {
namespace intern {

template<typename C>
struct has_value
: c_bool_t<!is_default<::utl::mp::__impl::value_impl<tag_of<C>>>::value>
{ };

}
}
}

+ 0
- 61
src/cpputils/mp/intern/hash_table.h View File

@@ -1,61 +0,0 @@
#pragma once

#include <cpputils/mp/operations/hash.h>
#include <cpputils/mp/operations/compare/equal.h>

namespace utl {
namespace mp {
namespace intern {

namespace __impl
{
template<typename H, size_t... I>
struct bucket { };

template<typename... Buckets>
struct hash_table
: Buckets...
{ };

/* find indices */
template<typename Hash, size_t... I>
std::index_sequence<I...> find_indices_impl(const bucket<Hash, I...>&);

template<typename Hash>
std::index_sequence<> find_indices_impl(...);

/* find index */
template<template<size_t> class KeyAtIndex, typename Key>
struct find_pred
{
template<typename Index>
auto operator()(const Index&) const ->
decltype(equal(std::declval<KeyAtIndex<Index::value>>(), std::declval<Key>()));
};

template<typename Indices, typename Key, template<size_t> class KeyAtIndex>
struct find_index_impl
{ using type = decltype(find_if(Indices { }, find_pred<KeyAtIndex, Key> { })); };
}

template<typename Map, typename Key>
struct find_indices
{
using hash = typename decltype(hash(std::declval<Key>()))::type;
using type = decltype(__impl::find_indices_impl<hash>(std::declval<Map>()));
};

template<template<size_t> class KeyAtIndex, size_t N, typename Indices = std::make_index_sequence<N>>
struct make_hash_table;

template<template<size_t> class KeyAtIndex, size_t N, size_t... I>
struct make_hash_table<KeyAtIndex, N, std::index_sequence<I...>>
{
using type = __impl::hash_table<
__impl::bucket<typename decltype(hash(std::declval<KeyAtIndex<I>>()))::type, I>...
>;
};

}
}
}

+ 0
- 36
src/cpputils/mp/intern/operators_comparable.h View File

@@ -1,36 +0,0 @@
#pragma once

#include <utility>
#include <cpputils/mp/core/conditionals.h>
#include <cpputils/mp/misc/tag_of.h>
#include <cpputils/mp/operations/compare/equal.h>
#include <cpputils/mp/operations/compare/not_equal.h>

namespace utl {
namespace mp {

namespace intern {

template<typename T>
struct operators_comparable
{ static constexpr bool value = false; };

}

namespace operators
{
template<typename X, typename Y, typename = enable_if_c<
intern::operators_comparable<tag_of<X>>::value &&
intern::operators_comparable<tag_of<Y>>::value>>
constexpr auto operator == (X&& x, Y&& y)
{ return equal(std::forward<X>(x), std::forward<Y>(y)); }

template<typename X, typename Y, typename = enable_if_c<
intern::operators_comparable<tag_of<X>>::value &&
intern::operators_comparable<tag_of<Y>>::value>>
constexpr auto operator != (X&& x, Y&& y)
{ return not_equal(std::forward<X>(x), std::forward<Y>(y)); }
}

}
}

+ 0
- 50
src/cpputils/mp/intern/operators_orderable.h View File

@@ -1,50 +0,0 @@
#pragma once

#include <utility>
#include <cpputils/mp/core/conditionals.h>
#include <cpputils/mp/misc/tag_of.h>
#include <cpputils/mp/operations/compare/less.h>
#include <cpputils/mp/operations/compare/less_equal.h>
#include <cpputils/mp/operations/compare/greater.h>
#include <cpputils/mp/operations/compare/greater_equal.h>

namespace utl {
namespace mp {

namespace intern {

template<typename T>
struct operators_orderable
{ static constexpr bool value = false; };

}

namespace operators
{
template<typename X, typename Y, typename = enable_if_c<
intern::operators_orderable<tag_of<X>>::value &&
intern::operators_orderable<tag_of<Y>>::value>>
constexpr auto operator < (X&& x, Y&& y)
{ return less(std::forward<X>(x), std::forward<Y>(y)); }

template<typename X, typename Y, typename = enable_if_c<
intern::operators_orderable<tag_of<X>>::value &&
intern::operators_orderable<tag_of<Y>>::value>>
constexpr auto operator <= (X&& x, Y&& y)
{ return less_equal(std::forward<X>(x), std::forward<Y>(y)); }

template<typename X, typename Y, typename = enable_if_c<
intern::operators_orderable<tag_of<X>>::value &&
intern::operators_orderable<tag_of<Y>>::value>>
constexpr auto operator > (X&& x, Y&& y)
{ return greater(std::forward<X>(x), std::forward<Y>(y)); }

template<typename X, typename Y, typename = enable_if_c<
intern::operators_orderable<tag_of<X>>::value &&
intern::operators_orderable<tag_of<Y>>::value>>
constexpr auto operator >= (X&& x, Y&& y)
{ return greater_equal(std::forward<X>(x), std::forward<Y>(y)); }
}

}
}

+ 0
- 8
src/cpputils/mp/misc.h View File

@@ -1,8 +0,0 @@
#pragma once

#include <cpputils/mp/misc/default.h>
#include <cpputils/mp/misc/is_a.h>
#include <cpputils/mp/misc/make.h>
#include <cpputils/mp/misc/tag_of.h>
#include <cpputils/mp/misc/when.h>
#include <cpputils/mp/misc/to.h>

+ 0
- 33
src/cpputils/mp/misc/default.h View File

@@ -1,33 +0,0 @@
#pragma once

#include <cpputils/mp/core/const.h>

namespace utl {
namespace mp {

namespace __impl /* forward declaration */
{
template<typename T, typename = void>
struct is_default_impl;
}

template<typename T>
using is_default = __impl::is_default_impl<T>;

namespace __impl /* implementation */
{
struct default_ { };

template<typename T, typename>
struct is_default_impl :
public c_false_t
{ };

template<typename T>
struct is_default_impl<T, decltype((void)static_cast<default_>(std::declval<T>()))> :
public c_true_t
{ };
}

}
}

+ 0
- 38
src/cpputils/mp/misc/is_a.h View File

@@ -1,38 +0,0 @@
#pragma once

#include <cpputils/mp/misc/when.h>
#include <cpputils/mp/misc/tag_of.h>

namespace utl {
namespace mp {

namespace __impl /* forward declaration */
{
template<typename Tag, typename ...T>
struct is_a_impl;
}

template<typename Tag, typename... T>
constexpr __impl::is_a_impl<Tag, T...> is_a { };

template<typename Tag, typename... T>
constexpr __impl::is_a_impl<Tag, T...> is_an { };

namespace __impl /* implementation */
{
template<typename Tag, typename T>
struct is_a_impl<Tag, T> :
public is_same<Tag, tag_of<T>>
{ };

template<typename Tag>
struct is_a_impl<Tag>
{
template<typename T>
constexpr auto operator()(const T&) const noexcept
{ return is_a<Tag, T>; }
};
}

}
}

+ 0
- 55
src/cpputils/mp/misc/make.h View File

@@ -1,55 +0,0 @@

#pragma once

#include <utility>
#include <cpputils/mp/misc/when.h>
#include <cpputils/mp/misc/default.h>

namespace utl {
namespace mp {

namespace __impl /* forward declaration */
{
template<typename Tag>
struct make_t;
}

template<typename Tag>
constexpr __impl::make_t<Tag> make { };

namespace __impl /* implementation */
{
template<typename T, typename = void>
struct make_impl :
public make_impl<T, when<true>>
{ };

template<typename T, bool condition>
struct make_impl<T, when<condition>> :
public default_
{
template<typename... X>
static constexpr auto make_helper(int, X&&... x)
-> decltype(T(std::forward<X>(x)...))
{ return T(std::forward<X>(x)...); }

template<typename... X>
static constexpr auto make_helper(long, X&&... x)
{ static_assert((sizeof...(X), false), "there exists no constructor for the given data type"); }

template <typename... X>
static constexpr auto apply(X&& ...x)
{ return make_helper(int{}, std::forward<X>(x)...); }
};

template<typename T>
struct make_t
{
template<typename... X>
constexpr auto operator()(X&&... x) const noexcept
{ return make_impl<T>::apply(std::forward<X>(x)...); }
};
}

}
}

+ 0
- 35
src/cpputils/mp/misc/tag_of.h View File

@@ -1,35 +0,0 @@
#pragma once

#include <cpputils/mp/core/modifier.h>
#include <cpputils/mp/misc/when.h>

namespace utl {
namespace mp {

namespace __impl /* forward declaration */
{
template<typename T, typename = void>
struct tag_of_impl;
}

template<typename T>
using tag_of = typename __impl::tag_of_impl<clean_type<T>>::type;

namespace __impl /* implementation */
{
template<typename T, typename>
struct tag_of_impl :
public tag_of_impl<T, when<true>>
{ };

template<typename T, bool condition>
struct tag_of_impl<T, when<condition>>
{ using type = T; };

template<typename T>
struct tag_of_impl<T, when_valid<typename clean_type<T>::tag>>
{ using type = typename clean_type<T>::tag; };
}

}
}

+ 0
- 176
src/cpputils/mp/misc/to.h View File

@@ -1,176 +0,0 @@
#pragma once

#include <cpputils/mp/misc/when.h>
#include <cpputils/mp/misc/tag_of.h>
#include <cpputils/mp/core/conditionals.h>

namespace utl {
namespace mp {

namespace __impl /* forward declaration */
{
template<typename To>
struct to_t;

template <typename From, typename To, typename = void>
struct is_mp_convertible_impl;

template <typename From, typename To, typename = void>
struct is_embedded_impl;
}

template<typename To>
constexpr __impl::to_t<To> to { };

template <typename From, typename To>
using is_mp_convertible = __impl::is_mp_convertible_impl<From, To>;

template <typename From, typename To>
using is_embedded = __impl::is_embedded_impl<From, To>;

namespace __impl /* implementation */
{
struct no_conversion { };

template <bool = true>
struct embedding { };

/* to_impl */
template <typename To, typename From, typename = void>
struct to_impl;

template <typename To, typename From, typename>
struct to_impl :
public to_impl<To, From, when<true>>
{ };

template <typename To, typename From, bool condition>
struct to_impl<To, From, when<condition>> :
public no_conversion
{
template <typename X>
static constexpr auto apply(const X&)
{ static_assert(wrong<to_impl<To, From>, X> { }, "no conversion is available between the provided types"); }
};

template <typename To, typename From>
struct to_impl<To, From, when_valid<decltype(static_cast<To>(std::declval<From>()))>>
{
template <typename X>
static constexpr To apply(X&& x)
{ return static_cast<To>(std::forward<X>(x)); }
};

template <typename To>
struct to_impl<To, To> :
public embedding<>
{
template <typename X>
static constexpr X apply(X&& x)
{ return std::forward<X&&>(x); }
};

template <typename T>
struct to_impl<T*, decltype(nullptr)> :
public embedding<>
{
static constexpr T* apply(decltype(nullptr))
{ return nullptr; }
};

/* to_t */
template <typename To>
struct to_t
{
template <typename X>
constexpr auto operator()(X&& x) const
{
using From = tag_of<X>;
return to_impl<To, From>::apply(std::forward<X>(x));
}
};

#define DEFINE_EMBEDDING_IMPL(TO, FROM) \
template <> \
struct to_impl<TO, FROM> : \
public embedding<> \
{ \
static constexpr TO apply(FROM x) \
{ return static_cast<TO>(x); } \
}

DEFINE_EMBEDDING_IMPL(long double, double);
DEFINE_EMBEDDING_IMPL(long double, float);
DEFINE_EMBEDDING_IMPL(double , float);

DEFINE_EMBEDDING_IMPL(signed long long, signed long);
DEFINE_EMBEDDING_IMPL(signed long long, signed int);
DEFINE_EMBEDDING_IMPL(signed long long, signed short);
DEFINE_EMBEDDING_IMPL(signed long long, signed char);
DEFINE_EMBEDDING_IMPL(signed long , signed int);
DEFINE_EMBEDDING_IMPL(signed long , signed short);
DEFINE_EMBEDDING_IMPL(signed long , signed char);
DEFINE_EMBEDDING_IMPL(signed int , signed short);
DEFINE_EMBEDDING_IMPL(signed int , signed char);
DEFINE_EMBEDDING_IMPL(signed short , signed char);

DEFINE_EMBEDDING_IMPL(unsigned long long, unsigned long);
DEFINE_EMBEDDING_IMPL(unsigned long long, unsigned int);
DEFINE_EMBEDDING_IMPL(unsigned long long, unsigned short);
DEFINE_EMBEDDING_IMPL(unsigned long long, unsigned char);
DEFINE_EMBEDDING_IMPL(unsigned long , unsigned int);
DEFINE_EMBEDDING_IMPL(unsigned long , unsigned short);
DEFINE_EMBEDDING_IMPL(unsigned long , unsigned char);
DEFINE_EMBEDDING_IMPL(unsigned int , unsigned short);
DEFINE_EMBEDDING_IMPL(unsigned int , unsigned char);
DEFINE_EMBEDDING_IMPL(unsigned short , unsigned char);

#undef DEFINE_EMBEDDING_IMPL

template<class T>
using copy_char_signedness = if_t<
std::is_signed<char>,
typename std::make_signed<T>::type,
typename std::make_unsigned<T>::type>;

#define DEFINE_CHAR_EMBEDDING_IMPL(TO) \
template <> \
struct to_impl<copy_char_signedness<TO>, char> \
: public embedding<> \
{ \
static constexpr copy_char_signedness<TO> apply(char x) \
{ return static_cast<TO>(x); } \
}

DEFINE_CHAR_EMBEDDING_IMPL(long long);
DEFINE_CHAR_EMBEDDING_IMPL(long);
DEFINE_CHAR_EMBEDDING_IMPL(int);
DEFINE_CHAR_EMBEDDING_IMPL(short);

#undef DEFINE_CHAR_EMBEDDING_IMPL

/* is_mp_convertible_impl */
template <typename From, typename To, typename>
struct is_mp_convertible_impl :
public std::true_type
{ };

template <typename From, typename To>
struct is_mp_convertible_impl<From, To, decltype((void) static_cast<no_conversion>(std::declval<to_impl<To, From>>()))> :
public std::false_type
{ };

/* is_embedded_impl */
template <typename From, typename To, typename>
struct is_embedded_impl :
public std::false_type
{ };

template <typename From, typename To>
struct is_embedded_impl<From, To, decltype((void) static_cast<embedding<true>>(std::declval<to_impl<To, From>>()))> :
public std::true_type
{ };
}

}
}

+ 0
- 32
src/cpputils/mp/misc/when.h View File

@@ -1,32 +0,0 @@
#pragma once

#include <cpputils/mp/core/checker.h>

namespace utl {
namespace mp {

namespace __impl /* forward declaration */
{
template<typename...>
struct wrong_impl;
}

template<bool condition>
struct when;

template<typename... T>
using when_valid = when<is_valid<T...>::value>;

template<typename... T>
using wrong = __impl::wrong_impl<T...>;

namespace __impl /* implementation */
{
template<typename...>
struct wrong_impl :
public c_false_t
{ };
}

}
}

+ 0
- 15
src/cpputils/mp/operations.h View File

@@ -1,15 +0,0 @@
#pragma once

#include <cpputils/mp/operations/at.h>
#include <cpputils/mp/operations/compare.h>
#include <cpputils/mp/operations/eval_if.h>
#include <cpputils/mp/operations/eval.h>
#include <cpputils/mp/operations/first.h>
#include <cpputils/mp/operations/hash.h>
#include <cpputils/mp/operations/if.h>
#include <cpputils/mp/operations/length.h>
#include <cpputils/mp/operations/logical.h>
#include <cpputils/mp/operations/second.h>
#include <cpputils/mp/operations/transform.h>
#include <cpputils/mp/operations/unpack.h>
#include <cpputils/mp/operations/value.h>

+ 0
- 52
src/cpputils/mp/operations/at.h View File

@@ -1,52 +0,0 @@
#pragma once

#include <utility>
#include <cpputils/mp/core/const.h>
#include <cpputils/mp/misc/when.h>
#include <cpputils/mp/misc/tag_of.h>
#include <cpputils/mp/misc/default.h>

namespace utl {
namespace mp {

namespace __impl
{
struct at_t
{
template<typename Xs, typename N>
constexpr auto operator()(Xs&& xs, const N& n) const;
};
}

constexpr __impl::at_t at { };

template<size_t N, typename Xs>
constexpr auto at_c(Xs&& xs)
{ return at(std::forward<Xs>(xs), c_size_t<N> { }); }

namespace __impl
{
template <typename T, typename = void>
struct at_impl
: at_impl<T, when<true>>
{ };

template <typename T, bool condition>
struct at_impl<T, when<condition>>
: default_
{
template <typename ...Args>
static constexpr auto apply(Args&& ...) = delete;
};

template<typename Xs, typename N>
constexpr auto at_t::operator()(Xs&& xs, const N& n) const
{
using tag_type = tag_of<Xs>;
using at_impl_type = at_impl<tag_type>;
return at_impl_type::apply(std::forward<Xs>(xs), n);
}
}

}
}

+ 0
- 4
src/cpputils/mp/operations/compare.h View File

@@ -1,4 +0,0 @@
#pragma once

#include <cpputils/mp/operations/compare/equal.h>
#include <cpputils/mp/operations/compare/not_equal.h>

+ 0
- 73
src/cpputils/mp/operations/compare/equal.h View File

@@ -1,73 +0,0 @@
#pragma once

#include <cpputils/mp/core/const.h>
#include <cpputils/mp/misc/when.h>
#include <cpputils/mp/misc/tag_of.h>
#include <cpputils/mp/misc/default.h>
#include <cpputils/mp/intern/has_value.h>
#include <cpputils/mp/intern/comparable_equal.h>
#include <cpputils/mp/operations/if.h>
#include <cpputils/mp/operations/value.h>

namespace utl {
namespace mp {

namespace __impl
{
struct equal_t
{
template<typename L, typename R>
constexpr auto operator()(const L& l, const R& r) const;
};
}

constexpr __impl::equal_t equal { };

namespace __impl
{
template <typename L, typename R, typename = void>
struct equal_impl
: equal_impl<L, R, when<true>>
{ };

template <typename L, typename R, bool condition>
struct equal_impl<L, R, when<condition>>
: default_
{
template <typename ...Args>
static constexpr auto apply(Args&& ...)
{ return c_false; }
};

template <typename T, typename U>
struct equal_impl<T, U, when<intern::comparable_equal<T, U>::value>>
{
template <typename X, typename Y>
static constexpr auto apply(X&& x, Y&& y)
{ return static_cast<X&&>(x) == static_cast<Y&&>(y); }
};

template <typename C>
struct equal_impl<C, C, when<intern::has_value<C>::value>>
{
template <typename X, typename Y>
static constexpr auto apply(const X&, const Y&)
{
constexpr auto eq = equal(value<X>(), value<Y>());
constexpr bool truth_value = if_ (eq, true, false);
return c_bool_t<truth_value> { };
}
};

template<typename L, typename R>
constexpr auto equal_t::operator()(const L& l, const R& r) const
{
using l_tag_type = tag_of<L>;
using r_tag_type = tag_of<R>;
using equal_type = equal_impl<l_tag_type, r_tag_type>;
return equal_type::apply(l, r);
}
}

}
}

+ 0
- 51
src/cpputils/mp/operations/compare/greater.h View File

@@ -1,51 +0,0 @@
#pragma once

#include <cpputils/mp/core/const.h>
#include <cpputils/mp/misc/when.h>
#include <cpputils/mp/misc/tag_of.h>
#include <cpputils/mp/misc/default.h>
#include <cpputils/mp/operations/logical/not.h>
#include <cpputils/mp/operations/compare/less.h>

namespace utl {
namespace mp {

namespace __impl
{
struct greater_t
{
template<typename L, typename R>
constexpr auto operator()(const L& l, const R& r) const;
};
}

constexpr __impl::greater_t greater { };

namespace __impl
{
template <typename L, typename R, typename = void>
struct greater_impl
: greater_impl<L, R, when<true>>
{ };

template <typename T, typename U, bool condition>
struct greater_impl<T, U, when<condition>>
: default_
{
template <typename X, typename Y>
static constexpr auto apply(X&& x, Y&& y)
{ return less(static_cast<Y&&>(y), static_cast<X&&>(x)); }
};

template<typename L, typename R>
constexpr auto greater_t::operator()(const L& l, const R& r) const
{
using l_tag_type = tag_of<L>;
using r_tag_type = tag_of<R>;
using greater_impl_type = greater_impl<l_tag_type, r_tag_type>;
return greater_impl_type::apply(l, r);
}
}

}
}

+ 0
- 51
src/cpputils/mp/operations/compare/greater_equal.h View File

@@ -1,51 +0,0 @@
#pragma once

#include <cpputils/mp/core/const.h>
#include <cpputils/mp/misc/when.h>
#include <cpputils/mp/misc/tag_of.h>
#include <cpputils/mp/misc/default.h>
#include <cpputils/mp/operations/logical/not.h>
#include <cpputils/mp/operations/compare/less.h>

namespace utl {
namespace mp {

namespace __impl
{
struct greater_equal_t
{
template<typename L, typename R>
constexpr auto operator()(const L& l, const R& r) const;
};
}

constexpr __impl::greater_equal_t greater_equal { };

namespace __impl
{
template <typename L, typename R, typename = void>
struct greater_equal_impl
: greater_equal_impl<L, R, when<true>>
{ };

template <typename T, typename U, bool condition>
struct greater_equal_impl<T, U, when<condition>>
: default_
{
template <typename X, typename Y>
static constexpr auto apply(X&& x, Y&& y)
{ return not_(less(static_cast<X&&>(x), static_cast<Y&&>(y))); }
};

template<typename L, typename R>
constexpr auto greater_equal_t::operator()(const L& l, const R& r) const
{
using l_tag_type = tag_of<L>;
using r_tag_type = tag_of<R>;
using greater_equal_impl_type = greater_equal_impl<l_tag_type, r_tag_type>;
return greater_equal_impl_type::apply(l, r);
}
}

}
}

+ 0
- 73
src/cpputils/mp/operations/compare/less.h View File

@@ -1,73 +0,0 @@
#pragma once

#include <cpputils/mp/core/const.h>
#include <cpputils/mp/misc/when.h>
#include <cpputils/mp/misc/tag_of.h>
#include <cpputils/mp/misc/default.h>
#include <cpputils/mp/intern/has_value.h>
#include <cpputils/mp/intern/comparable_less.h>
#include <cpputils/mp/operations/if.h>
#include <cpputils/mp/operations/value.h>

namespace utl {
namespace mp {

namespace __impl
{
struct less_t
{
template<typename L, typename R>
constexpr auto operator()(const L& l, const R& r) const;
};
}

constexpr __impl::less_t less { };

namespace __impl
{
template <typename L, typename R, typename = void>
struct less_impl
: less_impl<L, R, when<true>>
{ };

template <typename L, typename R, bool condition>
struct less_impl<L, R, when<condition>>
: default_
{
template <typename ...Args>
static constexpr auto apply(Args&& ...)
{ return c_false; }
};

template <typename T, typename U>
struct less_impl<T, U, when<intern::comparable_less<T, U>::value>>
{
template <typename X, typename Y>
static constexpr auto apply(X&& x, Y&& y)
{ return static_cast<X&&>(x) < static_cast<Y&&>(y); }
};

template <typename C>
struct less_impl<C, C, when<intern::has_value<C>::value>>
{
template <typename X, typename Y>
static constexpr auto apply(const X&, const Y&)
{
constexpr auto eq = less(value<X>(), value<Y>());
constexpr bool truth_value = if_ (eq, true, false);
return c_bool_t<truth_value> { };
}
};

template<typename L, typename R>
constexpr auto less_t::operator()(const L& l, const R& r) const
{
using l_tag_type = tag_of<L>;
using r_tag_type = tag_of<R>;
using less_type = less_impl<l_tag_type, r_tag_type>;
return less_type::apply(l, r);
}
}

}
}

+ 0
- 51
src/cpputils/mp/operations/compare/less_equal.h View File

@@ -1,51 +0,0 @@
#pragma once

#include <cpputils/mp/core/const.h>
#include <cpputils/mp/misc/when.h>
#include <cpputils/mp/misc/tag_of.h>
#include <cpputils/mp/misc/default.h>
#include <cpputils/mp/operations/logical/not.h>
#include <cpputils/mp/operations/compare/less.h>

namespace utl {
namespace mp {

namespace __impl
{
struct less_equal_t
{
template<typename L, typename R>
constexpr auto operator()(const L& l, const R& r) const;
};
}

constexpr __impl::less_equal_t less_equal { };

namespace __impl
{
template <typename L, typename R, typename = void>
struct less_equal_impl
: less_equal_impl<L, R, when<true>>
{ };

template <typename T, typename U, bool condition>
struct less_equal_impl<T, U, when<condition>>
: default_
{
template <typename X, typename Y>
static constexpr auto apply(X&& x, Y&& y)
{ return not_(less(static_cast<Y&&>(y), static_cast<X&&>(x))); }
};

template<typename L, typename R>
constexpr auto less_equal_t::operator()(const L& l, const R& r) const
{
using l_tag_type = tag_of<L>;
using r_tag_type = tag_of<R>;
using less_equal_impl_type = less_equal_impl<l_tag_type, r_tag_type>;
return less_equal_impl_type::apply(l, r);
}
}

}
}

+ 0
- 51
src/cpputils/mp/operations/compare/not_equal.h View File

@@ -1,51 +0,0 @@
#pragma once

#include <cpputils/mp/core/const.h>
#include <cpputils/mp/misc/when.h>
#include <cpputils/mp/misc/tag_of.h>
#include <cpputils/mp/misc/default.h>
#include <cpputils/mp/operations/logical/not.h>
#include <cpputils/mp/operations/compare/not_equal.h>

namespace utl {
namespace mp {

namespace __impl
{
struct not_equal_t
{
template<typename L, typename R>
constexpr auto operator()(const L& l, const R& r) const;
};
}

constexpr __impl::not_equal_t not_equal { };

namespace __impl
{
template <typename L, typename R, typename = void>
struct not_equal_impl
: not_equal_impl<L, R, when<true>>
{ };

template <typename L, typename R, bool condition>
struct not_equal_impl<L, R, when<condition>>
: default_
{
template <typename X, typename Y>
static constexpr auto apply(X&& x, Y&& y)
{ return not(equal(std::forward<X>(x), std::forward<Y>(y))); }
};

template<typename L, typename R>
constexpr auto not_equal_t::operator()(const L& l, const R& r) const
{
using l_tag_type = tag_of<L>;
using r_tag_type = tag_of<R>;
using not_equal_type = not_equal_impl<l_tag_type, r_tag_type>;
return not_equal_type::apply(l, r);
}
}

}
}

+ 0
- 59
src/cpputils/mp/operations/eval.h View File

@@ -1,59 +0,0 @@
#pragma once

#include <utility>
#include <cpputils/mp/misc/when.h>
#include <cpputils/mp/misc/tag_of.h>
#include <cpputils/mp/misc/default.h>

namespace utl {
namespace mp {

namespace __impl
{
struct eval_t
{
template <typename Expr>
constexpr auto operator()(Expr&& expr) const;
};
}

constexpr __impl::eval_t eval { };

namespace __impl
{
template <typename T, typename = void>
struct eval_impl
: eval_impl<T, when<true>>
{ };

template <typename T, bool condition>
struct eval_impl<T, when<condition>>
: default_
{
template <typename Expr>
static constexpr auto eval_helper(Expr&& expr, int)
{ return static_cast<Expr&&>(expr)(); }

template <typename Expr>
static constexpr auto eval_helper(Expr&&, ...)
{
static_assert(wrong<Expr> { },
"eval(expr) requires the expression to be a a nullary Callable");
}

template <typename Expr>
static constexpr decltype(auto) apply(Expr&& expr)
{ return eval_helper(static_cast<Expr&&>(expr), int { }); }
};

template <typename Expr>
constexpr auto eval_t::operator()(Expr&& expr) const
{
using tag_type = tag_of<Expr>;
using eval_impl_type = eval_impl<tag_type>;
return eval_impl_type::apply(std::forward<Expr>(expr));;
}
}

}
}

+ 0
- 80
src/cpputils/mp/operations/eval_if.h View File

@@ -1,80 +0,0 @@
#pragma once

#include <cpputils/mp/misc/when.h>
#include <cpputils/mp/misc/tag_of.h>
#include <cpputils/mp/misc/default.h>
#include <cpputils/mp/intern/has_value.h>
#include <cpputils/mp/operations/if.fwd.h>
#include <cpputils/mp/operations/eval.h>

namespace utl {
namespace mp {

namespace __impl
{
struct eval_if_t
{
template <typename Cond, typename Then, typename Else>
constexpr auto operator()(Cond&& c, Then&& t, Else&& e) const;
};
}

constexpr __impl::eval_if_t eval_if { };

namespace __impl
{
template <typename T, typename = void>
struct eval_if_impl
: eval_if_impl<T, when<true>>
{ };

template <typename T, bool condition>
struct eval_if_impl<T, when<condition>>
: default_
{
template <typename ...Args>
static constexpr auto apply(Args&& ...) = delete;
};

template <typename T>
struct eval_if_impl<T, when<is_arithmetic<T>::value>>
{
template <typename Cond, typename Then, typename Else>
static constexpr auto apply(const Cond& cond, Then&& t, Else&& e)
{
return cond ? eval(std::forward<Then>(t))
: eval(std::forward<Else>(e));
}
};

template <typename T>
struct eval_if_impl<T, when<intern::has_value<T>::value>>
{
template<typename Then, typename Else>
static constexpr auto eval_if_helper(c_true_t, Then&& t, Else&& e)
{ return eval(std::forward<Then>(t)); }

template<typename Then, typename Else>
static constexpr auto eval_if_helper(c_false_t, Then&& t, Else&& e)
{ return eval(std::forward<Else>(e)); }

template <typename Cond, typename Then, typename Else>
static constexpr auto apply(const Cond&, Then&& t, Else&& e)
{
constexpr auto cond = value<Cond>();
constexpr bool truth_value = if_(cond, true, false);
return eval_if_helper(c_bool_t<truth_value> { }, std::forward<Then>(t), std::forward<Else>(e));
}
};

template <typename Cond, typename Then, typename Else>
constexpr auto eval_if_t::operator()(Cond&& c, Then&& t, Else&& e) const
{
using tag_type = tag_of<Cond>;
using eval_if_type = eval_if_impl<tag_type>;
return eval_if_type::apply(std::forward<Cond>(c), std::forward<Then>(t), std::forward<Else>(e));
}
}

}
}

+ 0
- 46
src/cpputils/mp/operations/first.h View File

@@ -1,46 +0,0 @@
#pragma once

#include <cpputils/mp/misc/when.h>
#include <cpputils/mp/misc/tag_of.h>
#include <cpputils/mp/misc/default.h>

namespace utl {
namespace mp {

namespace __impl
{
struct first_t
{
template<typename T>
constexpr auto operator()(T&& t) const;
};
}

constexpr __impl::first_t first { };

namespace __impl
{
template <typename T, typename = void>
struct first_impl
: first_impl<T, when<true>>
{ };

template <typename T, bool condition>
struct first_impl<T, when<condition>>
: default_
{
template <typename ...Args>
static constexpr auto apply(Args&& ...) = delete;
};

template<typename T>
constexpr auto first_t::operator()(T&& t) const
{
using tag_type = tag_of<T>;
using first_type = first_impl<tag_type>;
return first_type::apply(std::forward<T>(t));
}
}

}
}

+ 0
- 28
src/cpputils/mp/operations/hash.fwd.h View File

@@ -1,28 +0,0 @@
#pragma once

#include <cpputils/mp/misc/when.h>
#include <cpputils/mp/misc/tag_of.h>
#include <cpputils/mp/misc/default.h>
#include <cpputils/mp/core/const.h>
#include <cpputils/mp/core/modifier.h>
#include <cpputils/mp/container/type.h>

namespace utl {
namespace mp {

namespace __impl /* forward declaration */
{
struct hash_t
{
template<typename X>
constexpr auto operator()(const X& x) const;
};

template <typename T, typename = void>
struct hash_impl;
}

constexpr __impl::hash_t hash { };

}
}

+ 0
- 104
src/cpputils/mp/operations/hash.h View File

@@ -1,104 +0,0 @@
#pragma once

#include <cpputils/mp/misc/when.h>
#include <cpputils/mp/misc/tag_of.h>
#include <cpputils/mp/misc/default.h>
#include <cpputils/mp/core/const.h>
#include <cpputils/mp/core/modifier.h>
#include <cpputils/mp/core/conditionals.h>
#include <cpputils/mp/container/type.h>
#include <cpputils/mp/operations/hash.fwd.h>

namespace utl {
namespace mp {

namespace __impl /* implementation */
{
template <typename T, typename = void>
struct hash_integral_helper;

template <typename Member, typename T>
struct hash_integral_helper<Member T::*>
{
template <typename X>
static constexpr auto apply(X const&)
{ return type_c<integral_constant<Member T::*, X::value>>; }
};

template <typename T>
struct hash_integral_helper<T, enable_if<is_signed<T>>>
{
template <typename X>
static constexpr auto apply(X const&)
{
constexpr signed long long x = X::value;
return type_c<integral_constant<signed long long, x>>;
}
};

template <typename T>
struct hash_integral_helper<T, enable_if<is_unsigned<T>>>
{
template <typename X>
static constexpr auto apply(X const&)
{
constexpr unsigned long long x = X::value;
return type_c<integral_constant<unsigned long long, x>>;
}
};

template <>
struct hash_integral_helper<bool>
{
template <typename X>
static constexpr auto apply(X const&)
{ return type_c<c_bool_t<X::value>>; }
};

template <>
struct hash_integral_helper<char>
{
template <typename X>
static constexpr auto apply(X const&)
{
using T = if_c<is_signed<char>::value, signed long long, unsigned long long>;
constexpr T x = X::value;
return type_c<integral_constant<T, x>>;
}
};

template <typename T, typename>
struct hash_impl
: hash_impl<T, when<true>>
{ };

template <typename Tag, bool condition>
struct hash_impl<Tag, when<condition>>
: default_
{
template <typename X>
static constexpr auto apply(X const&) = delete;
};

template <typename T>
struct hash_impl<tag_integral_constant<T>, when<true>>
{
template<typename X>
static constexpr auto apply(const X& x)
{
using type = remove_cv<decltype(X::value)>;
return hash_integral_helper<type>::apply(x);
}
};

template<typename X>
constexpr auto hash_t::operator()(const X& x) const
{
using tag_type = tag_of<X>;
using hash_impl_type = hash_impl<tag_type>;
return hash_impl_type::apply(x);
}
}

}
}

+ 0
- 18
src/cpputils/mp/operations/if.fwd.h View File

@@ -1,18 +0,0 @@
#pragma once

namespace utl {
namespace mp {

namespace __impl
{
struct if_t
{
template <typename Cond, typename Then, typename Else>
constexpr auto operator()(Cond&& c, Then&& t, Else&& e) const;
};
}

constexpr __impl::if_t if_ { };

}
}

+ 0
- 52
src/cpputils/mp/operations/if.h View File

@@ -1,52 +0,0 @@
#pragma once

#include <cpputils/mp/operations/if.fwd.h>

#include <cpputils/mp/misc/when.h>
#include <cpputils/mp/misc/tag_of.h>
#include <cpputils/mp/misc/default.h>
#include <cpputils/mp/operations/eval_if.h>

namespace utl {
namespace mp {

namespace __impl
{
template <typename T>
struct hold {
T value;
constexpr T&& operator()() &&
{ return static_cast<T&&>(value); }
};

template <typename L, typename = void>
struct if_impl
: if_impl<L, when<true>>
{ };

template <typename L, bool condition>
struct if_impl<L, when<condition>>
: default_
{
template <typename Cond, typename Then, typename Else>
static constexpr auto apply(Cond&& c, Then&& t, Else&& e)
{
return eval_if(
std::forward<Cond>(c),
hold<Then&&> { static_cast<Then&&>(t) },
hold<Else&&> { static_cast<Else&&>(e) }
);
}
};

template <typename Cond, typename Then, typename Else>
constexpr auto if_t::operator()(Cond&& c, Then&& t, Else&& e) const
{
using tag_type = tag_of<Cond>;
using if_type = if_impl<tag_type>;
return if_type::apply(std::forward<Cond>(c), std::forward<Then>(t), std::forward<Else>(e));
}
}

}
}

+ 0
- 56
src/cpputils/mp/operations/length.h View File

@@ -1,56 +0,0 @@
#pragma once

#include <cpputils/mp/core/const.h>
#include <cpputils/mp/misc/when.h>
#include <cpputils/mp/misc/tag_of.h>
#include <cpputils/mp/misc/default.h>
#include <cpputils/mp/operations/unpack.fwd.h>

namespace utl {
namespace mp {

namespace __impl
{
struct length_t
{
template<typename Xs>
constexpr auto operator()(const Xs& xs) const;
};
}

constexpr __impl::length_t length { };

namespace __impl
{
struct length_argn
{
template<typename... Xn>
constexpr c_size_t<sizeof...(Xn)> operator()(const Xn& ...) const
{ return { }; }
};

template <typename T, typename = void>
struct length_impl
: length_impl<T, when<true>>
{ };

template<typename T, bool condition>
struct length_impl<T, when<condition>>
: default_
{
template<typename Xs>
static constexpr auto apply(const Xs& xs)
{ return unpack(xs, length_argn { }); }
};

template<typename Xs>
constexpr auto length_t::operator()(const Xs& xs) const
{
using tag_type = tag_of<Xs>;
using length_impl_type = length_impl<tag_type>;
return length_impl_type::apply(xs);
}
}

}
}

+ 0
- 4
src/cpputils/mp/operations/logical.h View File

@@ -1,4 +0,0 @@
#pragma once

#include <cpputils/mp/operations/logical/not.h>
#include <cpputils/mp/operations/logical/and.h>

+ 0
- 63
src/cpputils/mp/operations/logical/and.h View File

@@ -1,63 +0,0 @@
#pragma once

#include <cpputils/mp/core/const.h>
#include <cpputils/mp/misc/when.h>
#include <cpputils/mp/misc/tag_of.h>
#include <cpputils/mp/misc/default.h>
#include <cpputils/mp/operations/if.h>
#include <cpputils/mp/intern/fold_left.h>

namespace utl {
namespace mp {

namespace __impl
{
struct and_t
{
template<typename X, typename Y>
constexpr auto operator()(X&& x, Y&& y) const;

template<typename X, typename... Y>
constexpr auto operator()(X&& x, Y&&... y) const;
};
}

constexpr __impl::and_t and_ { };

namespace __impl
{
template <typename T, typename = void>
struct and_impl
: and_impl<T, when<true>>
{ };

template <typename T, bool condition>
struct and_impl<T, when<condition>>
: default_
{
template <typename X, typename Y>
static constexpr auto apply(X&& x, Y&& y)
{ return if_(x, static_cast<Y&&>(y), x); }
};

template <typename X, typename Y>
constexpr auto and_t::operator()(X&& x, Y&& y) const
{
using tag_type = tag_of<X>;
using and_impl_type = and_impl<tag_type>;
return and_impl_type::apply(std::forward<X>(x), std::forward<Y>(y));
};
template <typename X, typename ...Y>
constexpr auto and_t::operator()(X&& x, Y&& ...y) const
{
return intern::fold_left(
*this,
static_cast<X&&>(x),
static_cast<Y&&>(y)...
);
}
}

}
}

+ 0
- 55
src/cpputils/mp/operations/logical/not.h View File

@@ -1,55 +0,0 @@
#pragma once

#include <cpputils/mp/core/const.h>
#include <cpputils/mp/misc/when.h>
#include <cpputils/mp/misc/tag_of.h>
#include <cpputils/mp/misc/default.h>

namespace utl {
namespace mp {

namespace __impl
{
struct not_t
{
template<typename X>
constexpr auto operator()(X&& x) const;
};
}

constexpr __impl::not_t not_ { };

namespace __impl
{
template <typename T, typename = void>
struct not_impl
: not_impl<T, when<true>>
{ };

template <typename T, bool condition>
struct not_impl<T, when<condition>>
: default_
{
template <typename ...Args>
static constexpr auto apply(Args&& ...) = delete;
};

template <typename T>
struct not_impl<T, when<is_arithmetic<T>::value>>
{
template <typename X>
static constexpr auto apply(const X& x)
{ return x ? false : true; }
};

template <typename X>
constexpr auto not_t::operator()(X&& x) const
{
using tag_type = tag_of<X>;
using not_impl_type = not_impl<tag_type>;
return not_impl_type::apply(std::forward<X>(x));
};
}

}
}

+ 0
- 63
src/cpputils/mp/operations/logical/or.h View File

@@ -1,63 +0,0 @@
#pragma once

#include <cpputils/mp/core/const.h>
#include <cpputils/mp/misc/when.h>
#include <cpputils/mp/misc/tag_of.h>
#include <cpputils/mp/misc/default.h>
#include <cpputils/mp/operations/if.h>
#include <cpputils/mp/intern/fold_left.h>

namespace utl {
namespace mp {

namespace __impl
{
struct or_t
{
template<typename X, typename Y>
constexpr auto operator()(X&& x, Y&& y) const;

template<typename X, typename... Y>
constexpr auto operator()(X&& x, Y&&... y) const;
};
}

constexpr __impl::or_t or_ { };

namespace __impl
{
template <typename T, typename = void>
struct or_impl
: or_impl<T, when<true>>
{ };

template <typename T, bool condition>
struct or_impl<T, when<condition>>
: default_
{
template <typename X, typename Y>
static constexpr auto apply(X&& x, Y&& y)
{ return if_(x, x, static_cast<Y&&>(y)); }
};

template <typename X, typename Y>
constexpr auto or_t::operator()(X&& x, Y&& y) const
{
using tag_type = tag_of<X>;
using or_impl_type = or_impl<tag_type>;
return or_impl_type::apply(std::forward<X>(x), std::forward<Y>(y));
};

template <typename X, typename ...Y>
constexpr auto or_t::operator()(X&& x, Y&& ...y) const
{
return intern::fold_left(
*this,
static_cast<X&&>(x),
static_cast<Y&&>(y)...
);
}
}

}
}

+ 0
- 46
src/cpputils/mp/operations/second.h View File

@@ -1,46 +0,0 @@
#pragma once

#include <cpputils/mp/misc/when.h>
#include <cpputils/mp/misc/tag_of.h>
#include <cpputils/mp/misc/default.h>

namespace utl {
namespace mp {

namespace __impl
{
struct second_t
{
template<typename T>
constexpr auto operator()(T&& t) const;
};
}

constexpr __impl::second_t second { };

namespace __impl
{
template <typename T, typename = void>
struct second_impl
: second_impl<T, when<true>>
{ };

template <typename T, bool condition>
struct second_impl<T, when<condition>>
: default_
{
template <typename ...Args>
static constexpr auto apply(Args&& ...) = delete;
};

template<typename T>
constexpr auto second_t::operator()(T&& t) const
{
using tag = tag_of<T>;
using second = second_impl<tag>;
return second::apply(std::forward<T>(t));
}
}

}
}

+ 0
- 68
src/cpputils/mp/operations/transform.h View File

@@ -1,68 +0,0 @@
#pragma once

#include <cpputils/mp/misc/when.h>
#include <cpputils/mp/misc/make.h>
#include <cpputils/mp/misc/tag_of.h>
#include <cpputils/mp/misc/default.h>
#include <cpputils/mp/operations/unpack.h>

namespace utl {
namespace mp {

namespace __impl
{
struct transform_t
{
template<typename Xs, typename F>
constexpr auto operator()(Xs&& xs, F&& f) const;
};
}

constexpr __impl::transform_t transform { };

namespace __impl
{
template<typename Xs, typename = void>
struct transform_impl
: transform_impl<Xs, when<true>>
{ };

template<typename T, bool condition>
struct transform_impl<T, when<condition>>
: default_
{
template<typename Xs, typename F>
static constexpr auto apply(Xs&& xs, F&& f) = delete;
};

template<typename T>
struct transform_impl<T, when<!is_default<unpack_impl<tag_of<T>>>::value>>
{
using tag_type = tag_of<T>;

template<typename F>
struct transformer
{
F f;

template<typename... Xn>
constexpr auto operator()(Xn&&... xn) const
{ return make<tag_type>((*f)(std::forward<Xn>(xn))...); }
};

template<typename Xs, typename F>
static constexpr auto apply(Xs&& xs, F&& f)
{ return unpack(std::forward<Xs>(xs), transformer<decltype(&f)> { &f }); }
};

template<typename Xs, typename F>
constexpr auto transform_t::operator()(Xs&& xs, F&& f) const
{
using tag_type = tag_of<Xs>;
using transform_impl_type = transform_impl<tag_type>;
return transform_impl_type::apply(std::forward<Xs>(xs), std::forward<F>(f));
}
}

}
}

+ 0
- 18
src/cpputils/mp/operations/unpack.fwd.h View File

@@ -1,18 +0,0 @@
#pragma once

namespace utl {
namespace mp {

namespace __impl
{
struct unpack_t
{
template<typename Xs, typename F>
constexpr auto operator()(Xs&& xs, F&& f) const;
};
}

constexpr __impl::unpack_t unpack { };

}
}

+ 0
- 61
src/cpputils/mp/operations/unpack.h View File

@@ -1,61 +0,0 @@
#pragma once

#include <utility>
#include <cpputils/mp/misc/tag_of.h>
#include <cpputils/mp/misc/default.h>
#include <cpputils/mp/operations/at.h>
#include <cpputils/mp/operations/length.h>
#include <cpputils/mp/operations/unpack.fwd.h>

namespace utl {
namespace mp {

namespace __impl
{
template<typename T, typename = void>
struct unpack_impl
: unpack_impl<T, when<true>>
{ };

template<typename T>
struct unpack_impl<T, when<
!is_default<length_impl<tag_of<T>>>::value &&
!is_default<at_impl <tag_of<T>>>::value>>
{
template<typename Xs, typename F, size_t... I>
static constexpr auto unpack_helper(Xs&& xs, F&& f, std::index_sequence<I...>)
{ return std::forward<F>(f)(at_c<I>(std::forward<Xs>(xs))...); }

template<typename Xs, typename F>
static constexpr auto apply(Xs&& xs, F&& f)
{
constexpr size_t N = decltype(length(xs))::value;
return unpack_helper(std::forward<Xs>(xs), std::forward<F>(f), std::make_index_sequence<N> { });
}
};

template<typename T, size_t N>
struct unpack_impl<T[N]>
{
template<typename Xs, typename F, size_t... I>
static constexpr auto unpack_helper(Xs&& xs, F&& f, std::index_sequence<I...>)
{ return std::forward<F>(f)(std::forward<Xs>(xs)[I]...); }
template<typename Xs, typename F>
static constexpr auto apply(Xs&& xs, F&& f)
{ return unpack_helper(std::forward<Xs>(xs), std::forward<F>(f), std::make_index_sequence<N> { }); }
};

// TODO: Pair, Struct

template<typename Xs, typename F>
constexpr auto unpack_t::operator()(Xs&& xs, F&& f) const
{
using tag_type = tag_of<Xs>;
using unpack_impl_type = unpack_impl<tag_type>;
return unpack_impl_type::apply(std::forward<Xs>(xs), std::forward<F>(f));
}
}

}
}

+ 0
- 54
src/cpputils/mp/operations/value.h View File

@@ -1,54 +0,0 @@
#pragma once

#include <cpputils/mp/misc/when.h>
#include <cpputils/mp/misc/tag_of.h>
#include <cpputils/mp/misc/default.h>

namespace utl {
namespace mp {

namespace __impl
{
template<typename T, typename = void>
struct value_impl;
}

template <typename T>
constexpr auto value()
{
using t_clean_type = clean_type<T>;
using tag_type = tag_of<T>;
using value_impl_type = __impl::value_impl<tag_type>;
return value_impl_type::template apply<t_clean_type>();
}

template <typename T>
constexpr decltype(auto) value(T const&)
{ return value<T>(); }

namespace __impl
{
template <typename T, typename>
struct value_impl
: value_impl<T, when<true>>
{ };

template <typename T, bool condition>
struct value_impl<T, when<condition>>
: default_
{
template <typename ...Args>
static constexpr auto apply(Args&& ...args) = delete;
};

template <typename T>
struct value_impl<tag_integral_constant<T>>
{
template <typename C>
static constexpr auto apply()
{ return C::value; }
};
}

}
}

+ 0
- 41
test/mp/container/basic_tuple.cpp View File

@@ -1,41 +0,0 @@
#include <cpputils/mp/core/const.h>
#include <cpputils/mp/container/basic_tuple.h>

using namespace ::utl::mp;

namespace test_mp_container_basic_tuple
{
struct op_unpack
{
constexpr auto operator()(const c_bool_t<false>&, const c_size_t<5>&)
{ return true; }
};

template<typename T>
struct Wrapper { };

struct op_transform
{
template<typename T>
constexpr auto operator()(T&& t)
{ return Wrapper<clean_type<T>> { }; }
};

constexpr auto my_tuple = make_basic_tuple(c_bool_t<false> { }, c_size_t<5> { });
constexpr c_size_t<0> index0;
constexpr c_size_t<1> index1;

static_assert(unpack(my_tuple, op_unpack { }), "");
static_assert(my_tuple.unpack(op_unpack { }), "");

static_assert(decltype(at(my_tuple, index0))::value == false, "");
static_assert(decltype(at(my_tuple, index1))::value == 5, "");
static_assert(decltype(my_tuple.at(index0))::value == false, "");
static_assert(decltype(my_tuple.at(index1))::value == 5, "");

constexpr auto transformed = my_tuple.transform(op_transform { });
using transformed_type = clean_type<decltype(transformed)>;
using transformed_expected = basic_tuple<Wrapper<c_bool_t<false>>, Wrapper<c_size_t<5>>>;

static_assert(is_same<transformed_type, transformed_expected>::value, "");
}

+ 0
- 61
test/mp/container/pair.cpp View File

@@ -1,61 +0,0 @@
#include <cpputils/mp/container/pair.h>
#include <cpputils/mp/operations/compare/equal.h>
#include <cpputils/mp/operations/compare/not_equal.h>
#include <cpputils/mp/operations/compare/less.h>
#include <cpputils/mp/operations/compare/less_equal.h>
#include <cpputils/mp/operations/compare/greater.h>
#include <cpputils/mp/operations/compare/greater_equal.h>

using namespace ::utl::mp;
using namespace ::utl::mp::operators;

namespace test_mp_container_pair
{
constexpr auto my_pair = make_pair(1, 'x');
static_assert(first(my_pair) == 1, "");
static_assert(second(my_pair) == 'x', "");
static_assert(my_pair.first() == 1, "");
static_assert(my_pair.second() == 'x', "");

static_assert(equal(make_pair(1, 'x'), make_pair(1, 'x')), "");
static_assert( make_pair(1, 'x') == make_pair(1, 'x'), "");

static_assert(not_equal(make_pair(1, 'x'), make_pair(2, 'x')), "");
static_assert( make_pair(1, 'x') != make_pair(2, 'x'), "");

static_assert(less(make_pair(1, 'x'), make_pair(1, 'y')), "");
static_assert(less(make_pair(1, 'x'), make_pair(2, 'x')), "");
static_assert(less(make_pair(1, 'x'), make_pair(2, 'a')), "");

static_assert(make_pair(1, 'x') < make_pair(1, 'y'), "");
static_assert(make_pair(1, 'x') < make_pair(2, 'x'), "");
static_assert(make_pair(1, 'x') < make_pair(2, 'a'), "");

static_assert(less_equal(make_pair(1, 'x'), make_pair(1, 'x')), "");
static_assert(less_equal(make_pair(1, 'x'), make_pair(1, 'y')), "");
static_assert(less_equal(make_pair(1, 'x'), make_pair(2, 'x')), "");
static_assert(less_equal(make_pair(1, 'x'), make_pair(2, 'a')), "");

static_assert(make_pair(1, 'x') <= make_pair(1, 'x'), "");
static_assert(make_pair(1, 'x') <= make_pair(1, 'y'), "");
static_assert(make_pair(1, 'x') <= make_pair(2, 'x'), "");
static_assert(make_pair(1, 'x') <= make_pair(2, 'a'), "");

static_assert(greater(make_pair(1, 'y'), make_pair(1, 'x')), "");
static_assert(greater(make_pair(2, 'x'), make_pair(1, 'x')), "");
static_assert(greater(make_pair(2, 'a'), make_pair(1, 'x')), "");

static_assert(make_pair(1, 'y') > make_pair(1, 'x'), "");
static_assert(make_pair(2, 'x') > make_pair(1, 'x'), "");
static_assert(make_pair(2, 'a') > make_pair(1, 'x'), "");

static_assert(greater_equal(make_pair(1, 'x'), make_pair(1, 'x')), "");
static_assert(greater_equal(make_pair(1, 'y'), make_pair(1, 'x')), "");
static_assert(greater_equal(make_pair(2, 'x'), make_pair(1, 'x')), "");
static_assert(greater_equal(make_pair(2, 'a'), make_pair(1, 'x')), "");

static_assert(make_pair(1, 'x') >= make_pair(1, 'x'), "");
static_assert(make_pair(1, 'y') >= make_pair(1, 'x'), "");
static_assert(make_pair(2, 'x') >= make_pair(1, 'x'), "");
static_assert(make_pair(2, 'a') >= make_pair(1, 'x'), "");
}

+ 0
- 8
test/mp/intern/comparable_equal.cpp View File

@@ -1,8 +0,0 @@
#include <cpputils/mp/intern/comparable_equal.h>

using namespace ::utl::mp::intern;

namespace test_mp_intern_comparable_equal
{
static_assert(comparable_equal<bool, bool>::value, "");
}

+ 0
- 9
test/mp/intern/ebo.cpp View File

@@ -1,9 +0,0 @@
#include <gtest/gtest.h>
#include <cpputils/mp/intern/ebo.h>

using namespace ::utl::mp::intern;

struct Key { };
using ebo_type = ebo<Key, int>;
constexpr ebo_type myEbo(7);
static_assert(myEbo.get() == 7, "ebo.get");

+ 0
- 10
test/mp/intern/has_value.cpp View File

@@ -1,10 +0,0 @@
#include <cpputils/mp/intern/has_value.h>

using namespace ::utl::mp;
using namespace ::utl::mp::intern;

namespace test_mp_intern_has_value
{
static_assert( has_value<c_true_t>::value, "");
static_assert(!has_value<bool>::value, "");
}

+ 0
- 14
test/mp/misc/default.cpp View File

@@ -1,14 +0,0 @@
#include <cpputils/mp/misc/default.h>

namespace test_mp_util_default
{
struct is_default_true : public ::utl::mp::__impl::default_ { };
struct is_default_false { };
}

using namespace ::utl::mp;
using namespace ::test_mp_util_default;

static_assert( is_default<is_default_true>::value, "");
static_assert(!is_default<is_default_false>::value, "");
static_assert(!is_default<bool>::value, "");

+ 0
- 18
test/mp/misc/is_a.cpp View File

@@ -1,18 +0,0 @@
#include <cstdint>
#include <cpputils/mp/core/const.h>
#include <cpputils/mp/misc/is_a.h>

namespace test_mp_util_is_a
{
struct tagged_int { using tag = int; };
struct tagged_float { using tag = float; };
struct tagged_not { };
}

using namespace ::utl::mp;
using namespace ::test_mp_util_is_a;

static_assert( is_a<int, tagged_int>, "is_a");
static_assert(!is_a<int, tagged_float>, "is_a");
static_assert( is_a<tag_integral_constant<int>>(integral_constant<int, 1> { }), "is_a");
static_assert(!is_a<tag_integral_constant<int>>(integral_constant<uint8_t, 1> { }), "is_a");

+ 0
- 9
test/mp/misc/make.cpp View File

@@ -1,9 +0,0 @@
#include <gtest/gtest.h>
#include <cpputils/mp/misc/make.h>

using namespace ::utl::mp;

TEST(mp_util_test, make)
{
EXPECT_EQ(std::string("fuu"), make<std::string>("fuu"));
}

+ 0
- 27
test/mp/misc/tag_of.cpp View File

@@ -1,27 +0,0 @@
#include <cpputils/mp/misc/tag_of.h>

namespace test_mp_util_tag_of
{
struct tagged_int { using tag = int; };
struct tagged_float { using tag = float; };
struct tagged_not { };
}

using namespace ::utl::mp;
using namespace ::test_mp_util_tag_of;

using tagged_0_expected = int;
using tagged_0_actual = tag_of<tagged_int>;
static_assert(is_same<tagged_0_expected, tagged_0_actual>::value, "");

using tagged_1_expected = float;
using tagged_1_actual = tag_of<tagged_float>;
static_assert(is_same<tagged_1_expected, tagged_1_actual>::value, "");

using not_tagged_expected = tagged_not;
using not_tagged_actual = tag_of<tagged_not>;
static_assert(is_same<not_tagged_expected, not_tagged_actual>::value, "");

using bool_expected = bool;
using bool_actual = tag_of<bool>;
static_assert(is_same<bool_expected, bool_actual>::value, "");

+ 0
- 39
test/mp/misc/to.cpp View File

@@ -1,39 +0,0 @@
#include <gtest/gtest.h>
#include <cpputils/mp/misc/to.h>

using namespace ::utl::mp;

static_assert(is_convertible<int32_t, int8_t>::value, "is_convertible");
static_assert(is_convertible<uint32_t, int8_t>::value, "is_convertible");
static_assert(!is_convertible<std::string, int8_t>::value, "is_convertible");

static_assert(is_embedded<double, long double>::value, "is_embdedded");
static_assert(is_embedded<float, long double>::value, "is_embdedded");
static_assert(is_embedded<float, double >::value, "is_embdedded");

static_assert(is_embedded<signed long, signed long long>::value, "is_embedded");
static_assert(is_embedded<signed int, signed long long>::value, "is_embedded");
static_assert(is_embedded<signed short, signed long long>::value, "is_embedded");
static_assert(is_embedded<signed char, signed long long>::value, "is_embedded");
static_assert(is_embedded<signed int, signed long >::value, "is_embedded");
static_assert(is_embedded<signed short, signed long >::value, "is_embedded");
static_assert(is_embedded<signed char, signed long >::value, "is_embedded");
static_assert(is_embedded<signed short, signed int >::value, "is_embedded");
static_assert(is_embedded<signed char, signed int >::value, "is_embedded");
static_assert(is_embedded<signed char, signed short >::value, "is_embedded");

static_assert(is_embedded<unsigned long, unsigned long long>::value, "is_embedded");
static_assert(is_embedded<unsigned int, unsigned long long>::value, "is_embedded");
static_assert(is_embedded<unsigned short, unsigned long long>::value, "is_embedded");
static_assert(is_embedded<unsigned char, unsigned long long>::value, "is_embedded");
static_assert(is_embedded<unsigned int, unsigned long >::value, "is_embedded");
static_assert(is_embedded<unsigned short, unsigned long >::value, "is_embedded");
static_assert(is_embedded<unsigned char, unsigned long >::value, "is_embedded");
static_assert(is_embedded<unsigned short, unsigned int >::value, "is_embedded");
static_assert(is_embedded<unsigned char, unsigned int >::value, "is_embedded");
static_assert(is_embedded<unsigned char, unsigned short >::value, "is_embedded");

TEST(test_mp_util_to, make)
{
EXPECT_EQ(to<int>(static_cast<uint8_t>(8)), 8);
}

+ 0
- 9
test/mp/operations/compare/equal.cpp View File

@@ -1,9 +0,0 @@
#include <cpputils/mp/operations/compare/equal.h>

using namespace ::utl::mp;

namespace test_mp_operations_compare_equal
{
static_assert(equal(1, 1), "");
static_assert(!equal(1, 2), "");
}

+ 0
- 9
test/mp/operations/compare/less.cpp View File

@@ -1,9 +0,0 @@
#include <cpputils/mp/operations/compare/less.h>

using namespace ::utl::mp;

namespace test_mp_operations_compare_equal
{
static_assert(less(1, 2), "");
static_assert(!less(2, 1), "");
}

+ 0
- 9
test/mp/operations/logical/and.cpp View File

@@ -1,9 +0,0 @@
#include <cpputils/mp/operations/logical/and.h>

using namespace ::utl::mp;

namespace test_mp_operations_logical_and
{
static_assert( and_(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), "");
static_assert(!and_(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), "");
}

+ 0
- 9
test/mp/operations/logical/or.cpp View File

@@ -1,9 +0,0 @@
#include <cpputils/mp/operations/logical/or.h>

using namespace ::utl::mp;

namespace test_mp_operations_logical_or
{
static_assert(!or_(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), "");
static_assert( or_(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), "");
}

+ 0
- 9
test/mp/operations/value.cpp View File

@@ -1,9 +0,0 @@
#include <cpputils/mp/operations/value.h>

using namespace ::utl::mp;

namespace test_mp_operations_value
{
constexpr integral_constant<int, 6> my_const{ };
static_assert(value(my_const) == 6, "");
}

Loading…
Cancel
Save