Browse Source

* implemented mp::basic_tuple

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

+ 4
- 4
src/cpputils/container/smart_ptr.h View File

@@ -16,19 +16,19 @@ namespace utl

template<class X, class Enable = void>
struct __impl_cop_is_value :
public mp::c_true { };
public mp::c_true;

template<class X>
struct __impl_cop_is_value<X*, void> :
public mp::c_false { };
public mp::c_false;

template<template<class> class F, class X>
struct __impl_cop_is_value<F<X>, mp::enable_if<cop_is_base_of<smart_ptr<X>, F<X>>>> :
public mp::c_false { };
public mp::c_false;

template<class X>
struct __impl_cop_is_value<std::reference_wrapper<X>, void> :
public mp::c_false { };
public mp::c_false;

template<class X>
using cop_is_value = __impl_cop_is_value<mp::clean_type<X>>;


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

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

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

+ 4
- 1
src/cpputils/mp/container.h View File

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

#include <cpputils/mp/container/pair.h>
#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>

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

@@ -0,0 +1,159 @@
#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)); }

}
}

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

@@ -0,0 +1,36 @@
#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...>;
};
}

}
}

+ 3
- 2
src/cpputils/mp/container/pair.h View File

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

#include <cpputils/mp/core.h>
#include <cpputils/mp/util/make.h>
#include <cpputils/mp/util/tag_of.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>
@@ -33,6 +33,7 @@ namespace mp {
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


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

@@ -0,0 +1,268 @@
#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; };

}

}
}

+ 15
- 9
src/cpputils/mp/core/checker.h View File

@@ -13,37 +13,43 @@ namespace mp {
}

template<typename T, typename S>
using is_same = c_bool<std::is_same<T, S>::value>;
using is_same = c_bool_t<std::is_same<T, S>::value>;

template<typename Base, typename Derived>
using is_base_of = c_bool<std::is_base_of<Base, Derived>::value>;
using is_base_of = c_bool_t<std::is_base_of<Base, Derived>::value>;

template<typename... T>
using is_constructible = c_bool<std::is_constructible<T...>::value>;
using is_constructible = c_bool_t<std::is_constructible<T...>::value>;

template<typename... T>
using is_empty = c_bool<std::is_empty<T...>::value>;
using is_empty = c_bool_t<std::is_empty<T...>::value>;

template<typename... T>
using is_final = c_bool<std::is_final<T...>::value>;
using is_final = c_bool_t<std::is_final<T...>::value>;

template<typename T, typename U>
using is_convertible = c_bool<std::is_convertible<T, U>::value>;
using is_convertible = c_bool_t<std::is_convertible<T, U>::value>;

template<typename T, typename U>
using is_assignable = c_bool<std::is_assignable<T, U>::value>;
using is_assignable = c_bool_t<std::is_assignable<T, U>::value>;

template<typename... T>
using is_valid = __impl::is_valid_impl<T...>;

template<typename T>
using is_arithmetic = c_bool<std::is_arithmetic<T>::value>;
using is_arithmetic = c_bool_t<std::is_arithmetic<T>::value>;

template<typename T>
using is_signed = c_bool_t<std::is_signed<T>::value>;

template<typename T>
using is_unsigned = c_bool_t<std::is_unsigned<T>::value>;

namespace __impl /* implementation */
{
template<typename...>
struct is_valid_impl :
public c_true
public c_true_t
{ };
}



+ 13
- 6
src/cpputils/mp/core/const.h View File

@@ -7,24 +7,31 @@ namespace utl {
namespace mp {

template<typename T>
struct tag_const { };
struct tag_integral_constant { };

template<typename T, T t>
struct integral_constant :
public std::integral_constant<T, t>
{
using tag = tag_const<T>;
using tag = tag_integral_constant<T>;
};

template<bool B>
using c_bool = integral_constant<bool, B>;
using c_bool_t = integral_constant<bool, B>;

template<size_t S>
using c_size_t = integral_constant<size_t, S>;

using c_true = c_bool<true>;
using c_false = c_bool<false>;
using c_zero = c_size_t<0>;
using c_zero_t = c_size_t<0>;
using c_true_t = c_bool_t<true>;
using c_false_t = c_bool_t<false>;

template<size_t S>
constexpr c_size_t<S> c_size { };

constexpr c_zero_t c_zero { };
constexpr c_true_t c_true { };
constexpr c_false_t c_false { };

}
}

+ 9
- 1
src/cpputils/mp/intern.h View File

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

#include <cpputils/mp/intern/ebo.h>
#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>

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

@@ -9,14 +9,14 @@ namespace intern {

template<typename T, typename U = T, typename = void>
struct comparable_equal
: c_false
: 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
: c_true_t
{ };

template <typename T, typename U>
@@ -28,7 +28,7 @@ namespace intern {
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<
: c_bool_t<
comparable_equal<T>::value &&
comparable_equal<U>::value &&
comparable_equal<common_type<T, U>>::value>


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

@@ -9,13 +9,13 @@ namespace intern {

template<typename T, typename U = T, typename = void>
struct comparable_less
: c_false
: 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
: c_true_t
{ };

template <typename T, typename U>
@@ -25,7 +25,7 @@ namespace intern {
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<
: c_bool_t<
comparable_less<T>::value &&
comparable_less<U>::value &&
comparable_less<common_type<T, U>>::value>


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

@@ -0,0 +1,265 @@
#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 { };

}
}
}

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

@@ -0,0 +1,244 @@
#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 { };

}
}
}

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

@@ -8,9 +8,9 @@ namespace intern {

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

}
}
}
}

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

@@ -0,0 +1,61 @@
#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>...
>;
};

}
}
}

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

@@ -2,7 +2,7 @@

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



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

@@ -2,7 +2,7 @@

#include <utility>
#include <cpputils/mp/core/conditionals.h>
#include <cpputils/mp/util/tag_of.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>


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

@@ -0,0 +1,8 @@
#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>

src/cpputils/mp/util/default.h → src/cpputils/mp/misc/default.h View File

@@ -20,12 +20,12 @@ namespace mp {

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

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


src/cpputils/mp/util/is_a.h → src/cpputils/mp/misc/is_a.h View File

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

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

namespace utl {
namespace mp {

src/cpputils/mp/util/make.h → src/cpputils/mp/misc/make.h View File

@@ -2,8 +2,8 @@
#pragma once

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

namespace utl {
namespace mp {

src/cpputils/mp/util/tag_of.h → src/cpputils/mp/misc/tag_of.h View File

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

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

namespace utl {
namespace mp {

src/cpputils/mp/util/to.h → src/cpputils/mp/misc/to.h View File

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

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

namespace utl {

src/cpputils/mp/util/when.h → src/cpputils/mp/misc/when.h View File

@@ -24,7 +24,7 @@ namespace mp {
{
template<typename...>
struct wrong_impl :
public c_false
public c_false_t
{ };
}


+ 11
- 2
src/cpputils/mp/operations.h View File

@@ -1,6 +1,15 @@
#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/compare.h>
#include <cpputils/mp/operations/logical.h>
#include <cpputils/mp/operations/transform.h>
#include <cpputils/mp/operations/unpack.h>
#include <cpputils/mp/operations/value.h>

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

@@ -0,0 +1,52 @@
#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);
}
}

}
}

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

@@ -1,9 +1,9 @@
#pragma once

#include <cpputils/mp/core/const.h>
#include <cpputils/mp/util/when.h>
#include <cpputils/mp/util/tag_of.h>
#include <cpputils/mp/util/default.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>
@@ -36,7 +36,7 @@ namespace mp {
{
template <typename ...Args>
static constexpr auto apply(Args&& ...)
{ return c_false { }; }
{ return c_false; }
};

template <typename T, typename U>
@@ -55,7 +55,7 @@ namespace mp {
{
constexpr auto eq = equal(value<X>(), value<Y>());
constexpr bool truth_value = if_ (eq, true, false);
return c_bool<truth_value> { };
return c_bool_t<truth_value> { };
}
};



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

@@ -1,9 +1,9 @@
#pragma once

#include <cpputils/mp/core/const.h>
#include <cpputils/mp/util/when.h>
#include <cpputils/mp/util/tag_of.h>
#include <cpputils/mp/util/default.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>



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

@@ -1,9 +1,9 @@
#pragma once

#include <cpputils/mp/core/const.h>
#include <cpputils/mp/util/when.h>
#include <cpputils/mp/util/tag_of.h>
#include <cpputils/mp/util/default.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>



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

@@ -1,9 +1,9 @@
#pragma once

#include <cpputils/mp/core/const.h>
#include <cpputils/mp/util/when.h>
#include <cpputils/mp/util/tag_of.h>
#include <cpputils/mp/util/default.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>
@@ -36,7 +36,7 @@ namespace mp {
{
template <typename ...Args>
static constexpr auto apply(Args&& ...)
{ return c_false { }; }
{ return c_false; }
};

template <typename T, typename U>
@@ -55,7 +55,7 @@ namespace mp {
{
constexpr auto eq = less(value<X>(), value<Y>());
constexpr bool truth_value = if_ (eq, true, false);
return c_bool<truth_value> { };
return c_bool_t<truth_value> { };
}
};



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

@@ -1,9 +1,9 @@
#pragma once

#include <cpputils/mp/core/const.h>
#include <cpputils/mp/util/when.h>
#include <cpputils/mp/util/tag_of.h>
#include <cpputils/mp/util/default.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>



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

@@ -1,9 +1,9 @@
#pragma once

#include <cpputils/mp/core/const.h>
#include <cpputils/mp/util/when.h>
#include <cpputils/mp/util/tag_of.h>
#include <cpputils/mp/util/default.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>



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

@@ -1,9 +1,9 @@
#pragma once

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

namespace utl {
namespace mp {


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

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

#include <cpputils/mp/util/when.h>
#include <cpputils/mp/util/tag_of.h>
#include <cpputils/mp/util/default.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/operations/if.fwd.h>
#include <cpputils/mp/operations/eval.h>
@@ -51,11 +51,11 @@ namespace mp {
struct eval_if_impl<T, when<intern::has_value<T>::value>>
{
template<typename Then, typename Else>
static constexpr auto eval_if_helper(c_true, Then&& t, Else&& e)
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, Then&& t, Else&& e)
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>
@@ -63,7 +63,7 @@ namespace mp {
{
constexpr auto cond = value<Cond>();
constexpr bool truth_value = if_(cond, true, false);
return eval_if_helper(c_bool<truth_value> { }, std::forward<Then>(t), std::forward<Else>(e));
return eval_if_helper(c_bool_t<truth_value> { }, std::forward<Then>(t), std::forward<Else>(e));
}
};



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

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

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

namespace utl {
namespace mp {


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

@@ -0,0 +1,28 @@
#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 { };

}
}

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

@@ -0,0 +1,104 @@
#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);
}
}

}
}

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

@@ -2,9 +2,9 @@

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

#include <cpputils/mp/util/when.h>
#include <cpputils/mp/util/tag_of.h>
#include <cpputils/mp/util/default.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 {


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

@@ -0,0 +1,56 @@
#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);
}
}

}
}

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

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

#include <cpputils/mp/core/const.h>
#include <cpputils/mp/util/when.h>
#include <cpputils/mp/util/tag_of.h>
#include <cpputils/mp/util/default.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 {
@@ -46,17 +47,16 @@ namespace mp {
using and_impl_type = and_impl<tag_type>;
return and_impl_type::apply(std::forward<X>(x), std::forward<Y>(y));
};
/* TODO
template <typename X, typename ...Y>
constexpr auto and_t::operator()(X&& x, Y&& ...y) const
{
return detail::variadic::foldl1(
return intern::fold_left(
*this,
static_cast<X&&>(x),
static_cast<Y&&>(y)...
);
}
*/
}

}

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

@@ -1,9 +1,9 @@
#pragma once

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

namespace utl {
namespace mp {


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

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

#include <cpputils/mp/core/const.h>
#include <cpputils/mp/util/when.h>
#include <cpputils/mp/util/tag_of.h>
#include <cpputils/mp/util/default.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 {
@@ -46,17 +47,16 @@ namespace mp {
using or_impl_type = or_impl<tag_type>;
return or_impl_type::apply(std::forward<X>(x), std::forward<Y>(y));
};
/* TODO
template <typename X, typename ...Y>
constexpr auto or_t::operator()(X&& x, Y&& ...y) const
{
return detail::variadic::foldl1(
return intern::fold_left(
*this,
static_cast<X&&>(x),
static_cast<Y&&>(y)...
);
}
*/
}

}

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

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

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

namespace utl {
namespace mp {


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

@@ -0,0 +1,68 @@
#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));
}
}

}
}

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

@@ -0,0 +1,18 @@
#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 { };

}
}

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

@@ -0,0 +1,61 @@
#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));
}
}

}
}

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

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

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

namespace utl {
namespace mp {
@@ -42,7 +42,7 @@ namespace mp {
};

template <typename T>
struct value_impl<tag_const<T>>
struct value_impl<tag_integral_constant<T>>
{
template <typename C>
static constexpr auto apply()


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

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

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

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

@@ -0,0 +1,41 @@
#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, "");
}

+ 1
- 1
test/mp/intern/has_value.cpp View File

@@ -5,6 +5,6 @@ using namespace ::utl::mp::intern;

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

test/mp/util/default.cpp → test/mp/misc/default.cpp View File

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

namespace test_mp_util_default
{

test/mp/util/is_a.cpp → test/mp/misc/is_a.cpp View File

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

namespace test_mp_util_is_a
{
@@ -14,5 +14,5 @@ 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_const<int>>(integral_constant<int, 1> { }), "is_a");
static_assert(!is_a<tag_const<int>>(integral_constant<uint8_t, 1> { }), "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");

test/mp/util/make.cpp → test/mp/misc/make.cpp View File

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

using namespace ::utl::mp;


test/mp/util/tag_of.cpp → test/mp/misc/tag_of.cpp View File

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

namespace test_mp_util_tag_of
{

test/mp/util/to.cpp → test/mp/misc/to.cpp View File

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

using namespace ::utl::mp;


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

@@ -0,0 +1,9 @@
#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), "");
}

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

@@ -0,0 +1,9 @@
#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), "");
}

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

@@ -0,0 +1,9 @@
#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