| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #ifndef METAL_HPP |
| | #define METAL_HPP |
| | #ifndef METAL_CONFIG_HPP |
| | #define METAL_CONFIG_HPP |
| | #ifndef METAL_CONFIG_CONFIG_HPP |
| | #define METAL_CONFIG_CONFIG_HPP |
| | #if !defined(METAL_WORKAROUND) |
| | #if (defined(__GNUC__) && !defined(__clang__) && (__GNUC__ < 5)) || (defined(_MSC_VER) && !defined(__clang__)) |
| | #define METAL_WORKAROUND |
| | #endif |
| | #endif |
| | #endif |
| | #ifndef METAL_CONFIG_VERSION_HPP |
| | #define METAL_CONFIG_VERSION_HPP |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | #define METAL_MAJOR 2 |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | #define METAL_MINOR 1 |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | #define METAL_PATCH 4 |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | #define METAL_SEMVER(MAJOR, MINOR, PATCH) (((MAJOR)*1000000) + ((MINOR)*10000) + (PATCH)) |
| | |
| | |
| | |
| | |
| | |
| | #define METAL_VERSION METAL_SEMVER(METAL_MAJOR, METAL_MINOR, METAL_PATCH) |
| | #endif |
| | |
| | |
| | #endif |
| | #ifndef METAL_LAMBDA_HPP |
| | #define METAL_LAMBDA_HPP |
| | #ifndef METAL_LAMBDA_ALWAYS_HPP |
| | #define METAL_LAMBDA_ALWAYS_HPP |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class val> |
| | struct _always; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class val> |
| | using always = typename detail::_always<val>::type; |
| | } |
| | #ifndef METAL_LAMBDA_LAMBDA_HPP |
| | #define METAL_LAMBDA_LAMBDA_HPP |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class val> |
| | struct _is_lambda; |
| | template <class val> |
| | struct _as_lambda; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class val> |
| | using is_lambda = typename detail::_is_lambda<val>::type; |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class val> |
| | using as_lambda = typename detail::_as_lambda<val>::type; |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <template <class...> class expr> |
| | #if defined(METAL_DOXYGENATING) |
| | using lambda = struct { |
| | }; |
| | #else |
| | struct lambda { |
| | }; |
| | #endif |
| | } |
| | #ifndef METAL_NUMBER_NUMBER_HPP |
| | #define METAL_NUMBER_NUMBER_HPP |
| | #include <cstdint> |
| | #include <type_traits> |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class val> |
| | struct _is_number; |
| | template <class val> |
| | struct _as_number; |
| | using int_ = std::intmax_t; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class val> |
| | using is_number = typename detail::_is_number<val>::type; |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | using int_ = detail::int_; |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <int_ v> |
| | using number = std::integral_constant<metal::int_, v>; |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | using true_ = metal::number<true>; |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | using false_ = metal::number<false>; |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class val> |
| | using as_number = typename detail::_as_number<val>::type; |
| | |
| | namespace detail { |
| | template <class val> |
| | struct _is_number : false_ { |
| | }; |
| | template <int_ value> |
| | struct _is_number<number<value>> : true_ { |
| | }; |
| | template <class val, class = std::true_type> |
| | struct has_enum_value : std::false_type { |
| | }; |
| | template <class val> |
| | struct has_enum_value<val, typename std::is_enum<decltype(val::value)>::type> |
| | : std::true_type { |
| | }; |
| | template <class val> |
| | struct is_pointer_to_const_integral : std::false_type { |
| | }; |
| | template <class val> |
| | struct is_pointer_to_const_integral<val const*> |
| | : std::is_integral<val> { |
| | }; |
| | template <class val, class = std::true_type> |
| | struct has_integral_value_impl : has_enum_value<val> { |
| | }; |
| | template <class val> |
| | struct has_integral_value_impl<val, |
| | typename is_pointer_to_const_integral<decltype(&val::value)>::type> |
| | : std::true_type { |
| | }; |
| | template <class val> |
| | struct has_integral_value_impl< |
| | val, typename std::is_member_pointer<decltype(&val::value)>::type> |
| | : std::false_type { |
| | }; |
| | template <class val, class = std::true_type> |
| | struct has_integral_value : has_integral_value_impl<val> { |
| | }; |
| | template <class val> |
| | struct has_integral_value<val, typename std::is_enum<val>::type> |
| | : has_enum_value<val> { |
| | }; |
| | template <class val, class = std::true_type> |
| | struct _as_number_impl { |
| | }; |
| | template <class val> |
| | struct _as_number_impl<val, typename has_integral_value<val>::type> { |
| | using type = number<val::value>; |
| | }; |
| | template <class val> |
| | struct _as_number : _as_number_impl<val> { |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class val> |
| | struct _is_lambda : false_ { |
| | }; |
| | template <template <class...> class expr> |
| | struct _is_lambda<lambda<expr>> : true_ { |
| | }; |
| | template <class val> |
| | struct _as_lambda { |
| | }; |
| | template <template <class...> class expr, class... vals> |
| | struct _as_lambda<expr<vals...>> { |
| | using type = lambda<expr>; |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | #ifndef METAL_VALUE_IDENTITY_HPP |
| | #define METAL_VALUE_IDENTITY_HPP |
| | #ifndef METAL_VALUE_EVAL_HPP |
| | #define METAL_VALUE_EVAL_HPP |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class val> |
| | using eval = typename val::type; |
| | } |
| | #endif |
| | #ifndef METAL_VALUE_VALUE_HPP |
| | #define METAL_VALUE_VALUE_HPP |
| | namespace metal { |
| | |
| | namespace detail { |
| | struct na; |
| | template <class val> |
| | struct maybe; |
| | #if defined(METAL_WORKAROUND) |
| | template <class val> |
| | struct _is_value; |
| | #endif |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class val> |
| | using is_value = |
| | #if defined(METAL_WORKAROUND) |
| | typename detail::_is_value<val>::type; |
| | #else |
| | metal::true_; |
| | #endif |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class val = detail::na> |
| | #if defined(METAL_DOXYGENATING) |
| | using value = struct { |
| | using type = val; |
| | }; |
| | #else |
| | using value = detail::maybe<val>; |
| | #endif |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | using nil = metal::value<>; |
| | |
| | namespace detail { |
| | template <class val> |
| | struct maybe { |
| | using type = val; |
| | }; |
| | template <> |
| | struct maybe<detail::na> { |
| | }; |
| | #if defined(METAL_WORKAROUND) |
| | template <class val> |
| | struct _is_value { |
| | using type = true_; |
| | }; |
| | #endif |
| | } |
| | |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class val> |
| | using identity = |
| | #if defined(METAL_WORKAROUND) |
| | eval<value<val>>; |
| | #else |
| | val; |
| | #endif |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class val> |
| | struct _always { |
| | template <class...> |
| | using impl = identity<val>; |
| | using type = lambda<impl>; |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | #ifndef METAL_LAMBDA_APPLY_HPP |
| | #define METAL_LAMBDA_APPLY_HPP |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class lbd, class seq> |
| | struct _apply; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class lbd, class seq> |
| | using apply = typename detail::_apply<lbd, seq>::type; |
| | } |
| | #ifndef METAL_DETAIL_SFINAE_HPP |
| | #define METAL_DETAIL_SFINAE_HPP |
| | #ifndef METAL_DETAIL_DECLPTR_HPP |
| | #define METAL_DETAIL_DECLPTR_HPP |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class T> |
| | T* declptr(); |
| | } |
| | |
| | } |
| | #endif |
| | #include <type_traits> |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <template <template <class...> class...> class, template <class...> class...> |
| | struct forwarder; |
| | template <template <template <class...> class...> class tmpl, template <class...> class... exprs, |
| | eval<std::enable_if<is_value<tmpl<exprs...>>::value>>* = nullptr> |
| | value<tmpl<exprs...>> sfinae(forwarder<tmpl, exprs...>*); |
| | template <template <class...> class expr, class... vals> |
| | struct caller; |
| | template <template <class...> class expr, class... vals, |
| | eval<std::enable_if<is_value<expr<vals...>>::value>>* = nullptr> |
| | value<expr<vals...>> sfinae(caller<expr, vals...>*); |
| | value<> sfinae(...); |
| | template <template <template <class...> class...> class tmpl, template <class...> class... exprs> |
| | struct forwarder |
| | : decltype(sfinae(declptr<forwarder<tmpl, exprs...>>())) { |
| | }; |
| | template <template <class...> class expr, class... vals> |
| | struct caller : decltype(sfinae(declptr<caller<expr, vals...>>())) { |
| | }; |
| | #if defined(METAL_WORKAROUND) |
| | template < |
| | template <template <class...> class...> class tmpl, |
| | template <class...> class... exprs> |
| | using forward = typename forwarder<tmpl, exprs...>::type; |
| | template <template <class...> class expr, class... vals> |
| | using call = typename caller<expr, vals...>::type; |
| | #else |
| | template <template <template <class...> class...> class tmpl, template <class...> class... exprs> |
| | using forward = tmpl<exprs...>; |
| | template <template <class...> class expr, class... vals> |
| | using call = expr<vals...>; |
| | #endif |
| | } |
| | |
| | } |
| | #endif |
| | #ifndef METAL_LIST_LIST_HPP |
| | #define METAL_LIST_LIST_HPP |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class val> |
| | struct _is_list; |
| | template <class val> |
| | struct _as_list; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class val> |
| | using is_list = typename detail::_is_list<val>::type; |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class val> |
| | using as_list = typename detail::_as_list<val>::type; |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class... vals> |
| | #if defined(METAL_DOXYGENATING) |
| | using list = struct { |
| | }; |
| | #else |
| | struct list { |
| | }; |
| | #endif |
| | } |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class val> |
| | struct _is_list : false_ { |
| | }; |
| | template <class... vals> |
| | struct _is_list<list<vals...>> : true_ { |
| | }; |
| | template <class val> |
| | struct _as_list { |
| | }; |
| | template <template <class...> class seq, class... vals> |
| | struct _as_list<seq<vals...>> { |
| | using type = list<vals...>; |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class lbd, class seq, class = true_> |
| | struct _apply_impl { |
| | }; |
| | template <template <class...> class expr, class... vals> |
| | struct _apply_impl<lambda<expr>, list<vals...>, is_value<call<expr, vals...>>> { |
| | using type = expr<vals...>; |
| | }; |
| | template <class lbd, class seq> |
| | struct _apply : _apply_impl<lbd, seq> { |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | #ifndef METAL_LAMBDA_ARG_HPP |
| | #define METAL_LAMBDA_ARG_HPP |
| | #include <cstddef> |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <std::size_t n> |
| | struct _arg; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <std::size_t n> |
| | using arg = typename detail::_arg<n>::type; |
| | } |
| | #ifndef METAL_LIST_AT_HPP |
| | #define METAL_LIST_AT_HPP |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class seq> |
| | struct _at; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq, class num> |
| | using at = detail::call<detail::_at<seq>::template type, num>; |
| | } |
| | #if defined(__has_builtin) |
| | #if __has_builtin(__type_pack_element) |
| | #define METAL_USE_BUILTIN_TYPE_PACK_ELEMENT |
| | #endif |
| | #endif |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class... vals> |
| | struct prepender { |
| | template <class... _> |
| | using prepend = prepender<_..., vals...>; |
| | using type = list<vals...>; |
| | }; |
| | template <std::size_t n> |
| | struct grouper |
| | |
| | : grouper<(n > 100) ? 100 : (n > 10) ? 10 : (n > 1)> { |
| | |
| | }; |
| | template <> |
| | struct grouper<100> { |
| | template < |
| | class _00, class _01, class _02, class _03, class _04, |
| | class _05, class _06, class _07, class _08, class _09, |
| | class _10, class _11, class _12, class _13, class _14, |
| | class _15, class _16, class _17, class _18, class _19, |
| | class _20, class _21, class _22, class _23, class _24, |
| | class _25, class _26, class _27, class _28, class _29, |
| | class _30, class _31, class _32, class _33, class _34, |
| | class _35, class _36, class _37, class _38, class _39, |
| | class _40, class _41, class _42, class _43, class _44, |
| | class _45, class _46, class _47, class _48, class _49, |
| | class _50, class _51, class _52, class _53, class _54, |
| | class _55, class _56, class _57, class _58, class _59, |
| | class _60, class _61, class _62, class _63, class _64, |
| | class _65, class _66, class _67, class _68, class _69, |
| | class _70, class _71, class _72, class _73, class _74, |
| | class _75, class _76, class _77, class _78, class _79, |
| | class _80, class _81, class _82, class _83, class _84, |
| | class _85, class _86, class _87, class _88, class _89, |
| | class _90, class _91, class _92, class _93, class _94, |
| | class _95, class _96, class _97, class _98, class _99, |
| | class... tail> |
| | using type = typename grouper<sizeof...(tail)>:: |
| | template type<tail...>:: |
| | template prepend< |
| | _at<list<_00, _01, _02, _03, _04, _05, _06, _07, _08, _09>>, |
| | _at<list<_10, _11, _12, _13, _14, _15, _16, _17, _18, _19>>, |
| | _at<list<_20, _21, _22, _23, _24, _25, _26, _27, _28, _29>>, |
| | _at<list<_30, _31, _32, _33, _34, _35, _36, _37, _38, _39>>, |
| | _at<list<_40, _41, _42, _43, _44, _45, _46, _47, _48, _49>>, |
| | _at<list<_50, _51, _52, _53, _54, _55, _56, _57, _58, _59>>, |
| | _at<list<_60, _61, _62, _63, _64, _65, _66, _67, _68, _69>>, |
| | _at<list<_70, _71, _72, _73, _74, _75, _76, _77, _78, _79>>, |
| | _at<list<_80, _81, _82, _83, _84, _85, _86, _87, _88, _89>>, |
| | _at<list<_90, _91, _92, _93, _94, _95, _96, _97, _98, _99>>>; |
| | }; |
| | template <> |
| | struct grouper<10> { |
| | template < |
| | class _00, class _01, class _02, class _03, class _04, |
| | class _05, class _06, class _07, class _08, class _09, |
| | class... tail> |
| | using type = typename grouper<sizeof...(tail)>:: |
| | template type<tail...>:: |
| | template prepend<_at<list<_00, _01, _02, _03, _04, _05, _06, _07, _08, _09>>>; |
| | }; |
| | template <> |
| | struct grouper<1> { |
| | template <class... vals> |
| | using type = prepender<_at<list<vals...>>>; |
| | }; |
| | template <> |
| | struct grouper<0> { |
| | template <class...> |
| | using type = prepender<>; |
| | }; |
| | template <class... vals> |
| | using group = typename grouper<sizeof...(vals)>::template type<vals...>::type; |
| | template <class groups, class m, class n> |
| | using select = typename _at<groups>::template type<m>::template type<n>; |
| | template <class num, class = true_> |
| | struct _at_impl { |
| | }; |
| | template <int_ n> |
| | struct _at_impl<number<n>, number<(n > 9)>> { |
| | template <class... vals> |
| | using type = select<call<group, vals...>, number<n / 10>, number<n % 10>>; |
| | }; |
| | template <> |
| | struct _at_impl<number<9>> { |
| | template <class, class, class, class, class, class, class, class, class, class val, class...> |
| | using type = val; |
| | }; |
| | template <> |
| | struct _at_impl<number<8>> { |
| | template <class, class, class, class, class, class, class, class, class val, class...> |
| | using type = val; |
| | }; |
| | template <> |
| | struct _at_impl<number<7>> { |
| | template <class, class, class, class, class, class, class, class val, class...> |
| | using type = val; |
| | }; |
| | template <> |
| | struct _at_impl<number<6>> { |
| | template <class, class, class, class, class, class, class val, class...> |
| | using type = val; |
| | }; |
| | template <> |
| | struct _at_impl<number<5>> { |
| | template <class, class, class, class, class, class val, class...> |
| | using type = val; |
| | }; |
| | template <> |
| | struct _at_impl<number<4>> { |
| | template <class, class, class, class, class val, class...> |
| | using type = val; |
| | }; |
| | template <> |
| | struct _at_impl<number<3>> { |
| | template <class, class, class, class val, class...> |
| | using type = val; |
| | }; |
| | template <> |
| | struct _at_impl<number<2>> { |
| | template <class, class, class val, class...> |
| | using type = val; |
| | }; |
| | template <> |
| | struct _at_impl<number<1>> { |
| | template <class, class val, class...> |
| | using type = val; |
| | }; |
| | template <> |
| | struct _at_impl<number<0>> { |
| | template <class val, class...> |
| | using type = val; |
| | }; |
| | template <class seq> |
| | struct _at { |
| | }; |
| | template <class... vals> |
| | struct _at<list<vals...>> { |
| | #if defined(METAL_USE_BUILTIN_TYPE_PACK_ELEMENT) |
| | template <class, class = true_> |
| | struct impl { |
| | }; |
| | template <int_ n> |
| | struct impl<number<n>, number<(n >= 0 && n < sizeof...(vals))>> { |
| | using type = __type_pack_element<n, vals...>; |
| | }; |
| | template <class... num> |
| | using type = typename impl<num...>::type; |
| | #else |
| | template <class... num> |
| | using type = call<_at_impl<num...>::template type, vals...>; |
| | #endif |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <std::size_t n> |
| | struct _arg { |
| | template <class... vals> |
| | using impl = at<list<vals...>, number<n - 1>>; |
| | using type = lambda<impl>; |
| | }; |
| | template <> |
| | struct _arg<0U> { |
| | }; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | using _1 = metal::arg<1U>; |
| | using _2 = metal::arg<2U>; |
| | using _3 = metal::arg<3U>; |
| | using _4 = metal::arg<4U>; |
| | using _5 = metal::arg<5U>; |
| | using _6 = metal::arg<6U>; |
| | using _7 = metal::arg<7U>; |
| | using _8 = metal::arg<8U>; |
| | using _9 = metal::arg<9U>; |
| | |
| | } |
| | #endif |
| | #ifndef METAL_LAMBDA_BIND_HPP |
| | #define METAL_LAMBDA_BIND_HPP |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class lbd, class... vals> |
| | struct _bind; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class lbd, class... vals> |
| | using bind = typename detail::_bind<lbd, vals...>::type; |
| | } |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class... vals> |
| | struct _bind_impl { |
| | template <template <class...> class expr, template <class...> class... params> |
| | using type = |
| | #if defined(METAL_WORKAROUND) |
| | call<expr, call<params, vals...>...>; |
| | #else |
| | expr<params<vals...>...>; |
| | #endif |
| | }; |
| | template <class lbd, class... vals> |
| | struct _bind { |
| | }; |
| | template <template <class...> class expr, template <class...> class... params> |
| | struct _bind<lambda<expr>, lambda<params>...> { |
| | template <class... vals> |
| | using impl = forward<_bind_impl<vals...>::template type, expr, params...>; |
| | using type = lambda<impl>; |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | #ifndef METAL_LAMBDA_INVOKE_HPP |
| | #define METAL_LAMBDA_INVOKE_HPP |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class lbd, class... vals> |
| | using invoke = metal::apply<lbd, metal::list<vals...>>; |
| | } |
| | #endif |
| | #ifndef METAL_LAMBDA_IS_INVOCABLE_HPP |
| | #define METAL_LAMBDA_IS_INVOCABLE_HPP |
| | #ifndef METAL_VALUE_SAME_HPP |
| | #define METAL_VALUE_SAME_HPP |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class... vals> |
| | struct _same; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class... vals> |
| | using same = typename detail::_same<vals...>::type; |
| | } |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class...> |
| | struct _same_impl : false_ { |
| | }; |
| | template <template <class> class... _, class val> |
| | struct _same_impl<_<val>...> : true_ { |
| | }; |
| | template <class... vals> |
| | struct _same : _same_impl<maybe<vals>...> { |
| | }; |
| | template <class x, class y> |
| | struct _same<x, y> : false_ { |
| | }; |
| | template <class x> |
| | struct _same<x, x> : true_ { |
| | }; |
| | template <class x> |
| | struct _same<x> : true_ { |
| | }; |
| | template <> |
| | struct _same<> : true_ { |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | #include <type_traits> |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class lbd, class... vals> |
| | using is_invocable = same<std::false_type, typename std::is_base_of<value<>, detail::caller<invoke, lbd, vals...>>::type>; |
| | } |
| | #endif |
| | #ifndef METAL_LAMBDA_LAZY_HPP |
| | #define METAL_LAMBDA_LAZY_HPP |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <template <class...> class expr> |
| | using lazy = metal::bind<metal::lambda<metal::eval>, metal::lambda<expr>>; |
| | } |
| | #endif |
| | #ifndef METAL_LAMBDA_PARTIAL_HPP |
| | #define METAL_LAMBDA_PARTIAL_HPP |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class lbd, class... vals> |
| | struct _partial; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class lbd, class... vals> |
| | using partial = typename detail::_partial<lbd, vals...>::type; |
| | } |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class lbd, class... leading> |
| | struct _partial { |
| | }; |
| | template <template <class...> class expr, class... leading> |
| | struct _partial<lambda<expr>, leading...> { |
| | template <class... trailing> |
| | using impl = invoke<lambda<expr>, leading..., trailing...>; |
| | using type = lambda<impl>; |
| | }; |
| | template <class x> |
| | struct _partial<lambda<same>, x> { |
| | template <class y> |
| | using impl = same<x, y>; |
| | using type = lambda<impl>; |
| | }; |
| | template <template <class...> class expr> |
| | struct _partial<lambda<expr>> { |
| | using type = lambda<expr>; |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | #ifndef METAL_LAMBDA_TRAIT_HPP |
| | #define METAL_LAMBDA_TRAIT_HPP |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <template <class...> class expr> |
| | using trait = metal::bind<metal::lambda<metal::as_number>, metal::lambda<expr>>; |
| | } |
| | #endif |
| | |
| | |
| | #endif |
| | #ifndef METAL_LIST_HPP |
| | #define METAL_LIST_HPP |
| | #ifndef METAL_LIST_ACCUMULATE_HPP |
| | #define METAL_LIST_ACCUMULATE_HPP |
| | #ifndef METAL_LIST_SIZE_HPP |
| | #define METAL_LIST_SIZE_HPP |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class seq> |
| | struct _size; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq> |
| | using size = typename detail::_size<seq>::type; |
| | } |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class seq> |
| | struct _size { |
| | }; |
| | template <class... vals> |
| | struct _size<list<vals...>> : number<sizeof...(vals)> { |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | #ifndef METAL_NUMBER_IF_HPP |
| | #define METAL_NUMBER_IF_HPP |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class cond> |
| | struct _if_; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class cond, class... then> |
| | using if_ = detail::call<detail::_if_<cond>::template type, then...>; |
| | } |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class> |
| | struct _if_ { |
| | }; |
| | template <int_ v> |
| | struct _if_<number<v>> { |
| | template <class val, class = void> |
| | using type = val; |
| | }; |
| | template <> |
| | struct _if_<false_> { |
| | template <class, class val> |
| | using type = val; |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class lbd> |
| | struct _accumulate; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class lbd, class state, class... seqs> |
| | using accumulate = detail::call< |
| | if_<same<size<seqs>...>, detail::_accumulate<lbd>>::template type, |
| | state, seqs...>; |
| | } |
| | #ifndef METAL_LIST_TRANSPOSE_HPP |
| | #define METAL_LIST_TRANSPOSE_HPP |
| | #ifndef METAL_LIST_TRANSFORM_HPP |
| | #define METAL_LIST_TRANSFORM_HPP |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class lbd> |
| | struct _transform; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class lbd, class... seqs> |
| | using transform = detail::call<if_<same<size<seqs>...>, detail::_transform<lbd>>::template type, seqs...>; |
| | } |
| | #ifndef METAL_LIST_INDICES_HPP |
| | #define METAL_LIST_INDICES_HPP |
| | #ifndef METAL_NUMBER_IOTA_HPP |
| | #define METAL_NUMBER_IOTA_HPP |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class, class, class> |
| | struct _iota; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class start, class size, class stride = number<1>> |
| | using iota = typename detail::_iota<start, size, stride>::type; |
| | } |
| | #ifndef METAL_NUMBER_NUMBERS_HPP |
| | #define METAL_NUMBER_NUMBERS_HPP |
| | #include <type_traits> |
| | namespace metal { |
| | |
| | namespace detail { |
| | #if defined(METAL_WORKAROUND) |
| | template <int_... vs> |
| | struct _numbers; |
| | #endif |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <int_... vs> |
| | using numbers = |
| | #if defined(METAL_WORKAROUND) |
| | typename detail::_numbers<vs...>::type; |
| | #else |
| | metal::list<metal::number<vs>...>; |
| | #endif |
| | |
| | namespace detail { |
| | #if defined(METAL_WORKAROUND) |
| | template <int_... vs> |
| | struct _numbers { |
| | using type = list<std::integral_constant<int_, vs>...>; |
| | }; |
| | #endif |
| | } |
| | |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <int_... ns> |
| | struct enumeration { |
| | }; |
| | template <class ns> |
| | struct _even { |
| | }; |
| | template <int_... ns> |
| | struct _even<enumeration<ns...>> { |
| | using type = enumeration<ns..., (sizeof...(ns) + ns)...>; |
| | }; |
| | template <class ns> |
| | struct _odd { |
| | }; |
| | template <int_... ns> |
| | struct _odd<enumeration<ns...>> { |
| | using type = enumeration<ns..., (sizeof...(ns) + ns)..., 2 * sizeof...(ns)>; |
| | }; |
| | template <int_ n> |
| | struct _enumerate; |
| | template <int_ n> |
| | using enumerate = typename _enumerate<n>::type; |
| | template <int_ n> |
| | struct _enumerate |
| | : if_<number<n % 2>, _odd<enumerate<n / 2>>, _even<enumerate<n / 2>>> { |
| | }; |
| | template <> |
| | struct _enumerate<0> { |
| | using type = enumeration<>; |
| | }; |
| | template <class, int_ a, int_ b> |
| | struct _iota_impl { |
| | }; |
| | template <int_... vs, int_ a, int_ b> |
| | struct _iota_impl<enumeration<vs...>, a, b> { |
| | using type = numbers<(b + a * vs)...>; |
| | }; |
| | template <class, class, class> |
| | struct _iota { |
| | }; |
| | template <int_ st, int_ sz, int_ sd> |
| | struct _iota<number<st>, number<sz>, number<sd>> |
| | : _iota_impl<enumerate<(sz < 0) ? (0 - sz) : sz>, (sz < 0) ? (0 - sd) : sd, st> { |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq> |
| | using indices = metal::iota<metal::number<0>, metal::size<seq>>; |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class num, class... seqs> |
| | struct transformer_impl { |
| | template <template <class...> class expr> |
| | using type = expr<at<seqs, num>...>; |
| | }; |
| | template <template <class...> class expr, class... seqs> |
| | struct transformer { |
| | template <class num> |
| | using type = forward<transformer_impl<num, seqs...>::template type, expr>; |
| | }; |
| | template <class head, class... tail> |
| | struct _transform_impl { |
| | template <template <class...> class expr> |
| | using type = forward< |
| | _transform_impl<indices<head>>::template type, |
| | transformer<expr, head, tail...>::template type>; |
| | }; |
| | template <class... xs, class... ys, class... zs> |
| | struct _transform_impl<list<xs...>, list<ys...>, list<zs...>> { |
| | template <template <class...> class expr> |
| | using type = list<expr<xs, ys, zs>...>; |
| | }; |
| | template <class... xs, class... ys> |
| | struct _transform_impl<list<xs...>, list<ys...>> { |
| | template <template <class...> class expr> |
| | using type = list<expr<xs, ys>...>; |
| | }; |
| | template <class... xs> |
| | struct _transform_impl<list<xs...>> { |
| | template <template <class...> class expr> |
| | using type = list<expr<xs>...>; |
| | }; |
| | template <class lbd> |
| | struct _transform { |
| | }; |
| | template <template <class...> class expr> |
| | struct _transform<lambda<expr>> { |
| | template <class... seqs> |
| | using type = forward<_transform_impl<seqs...>::template type, expr>; |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq> |
| | using transpose = metal::apply< |
| | metal::partial<metal::lambda<metal::transform>, metal::lambda<metal::list>>, |
| | seq>; |
| | } |
| | #endif |
| | #ifndef METAL_VALUE_FOLD_LEFT_HPP |
| | #define METAL_VALUE_FOLD_LEFT_HPP |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class lbd> |
| | struct _fold_left; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class lbd, class... vals> |
| | using fold_left = detail::call<detail::_fold_left<lbd>::template type, vals...>; |
| | } |
| | #include <cstddef> |
| | namespace metal { |
| | |
| | namespace detail { |
| | template < |
| | class state, |
| | class _00, class _01, class _02, class _03, class _04, class _05, |
| | class _06, class _07, class _08, class _09, class _10, class _11, |
| | class _12, class _13, class _14, class _15, class _16, class _17, |
| | class _18, class _19, class _20, class _21, class _22, class _23, |
| | class _24, class _25, class _26, class _27, class _28, class _29, |
| | class _30, class _31, class _32, class _33, class _34, class _35, |
| | class _36, class _37, class _38, class _39, class _40, class _41, |
| | class _42, class _43, class _44, class _45, class _46, class _47, |
| | class _48, class _49, class _50, class _51, class _52, class _53, |
| | class _54, class _55, class _56, class _57, class _58, class _59, |
| | class _60, class _61, class _62, class _63, class _64, class _65, |
| | class _66, class _67, class _68, class _69, class _70, class _71, |
| | class _72, class _73, class _74, class _75, class _76, class _77, |
| | class _78, class _79, class _80, class _81, class _82, class _83, |
| | class _84, class _85, class _86, class _87, class _88, class _89, |
| | class _90, class _91, class _92, class _93, class _94, class _95, |
| | class _96, class _97, class _98, class _99> |
| | struct left_folder_100 { |
| | template<template<class...> class expr> |
| | using type = |
| | expr<expr<expr<expr<expr<expr<expr<expr<expr<expr< |
| | expr<expr<expr<expr<expr<expr<expr<expr<expr<expr< |
| | expr<expr<expr<expr<expr<expr<expr<expr<expr<expr< |
| | expr<expr<expr<expr<expr<expr<expr<expr<expr<expr< |
| | expr<expr<expr<expr<expr<expr<expr<expr<expr<expr< |
| | expr<expr<expr<expr<expr<expr<expr<expr<expr<expr< |
| | expr<expr<expr<expr<expr<expr<expr<expr<expr<expr< |
| | expr<expr<expr<expr<expr<expr<expr<expr<expr<expr< |
| | expr<expr<expr<expr<expr<expr<expr<expr<expr<expr< |
| | expr<expr<expr<expr<expr<expr<expr<expr<expr<expr< |
| | forward<state::template type, expr>, |
| | _00>, _01>, _02>, _03>, _04>, _05>, _06>, _07>, _08>, _09>, |
| | _10>, _11>, _12>, _13>, _14>, _15>, _16>, _17>, _18>, _19>, |
| | _20>, _21>, _22>, _23>, _24>, _25>, _26>, _27>, _28>, _29>, |
| | _30>, _31>, _32>, _33>, _34>, _35>, _36>, _37>, _38>, _39>, |
| | _40>, _41>, _42>, _43>, _44>, _45>, _46>, _47>, _48>, _49>, |
| | _50>, _51>, _52>, _53>, _54>, _55>, _56>, _57>, _58>, _59>, |
| | _60>, _61>, _62>, _63>, _64>, _65>, _66>, _67>, _68>, _69>, |
| | _70>, _71>, _72>, _73>, _74>, _75>, _76>, _77>, _78>, _79>, |
| | _80>, _81>, _82>, _83>, _84>, _85>, _86>, _87>, _88>, _89>, |
| | _90>, _91>, _92>, _93>, _94>, _95>, _96>, _97>, _98>, _99>; |
| | }; |
| | template < |
| | class state, |
| | class _00, class _01, class _02, class _03, class _04, |
| | class _05, class _06, class _07, class _08, class _09> |
| | struct left_folder_10 { |
| | template <template <class...> class expr> |
| | |
| | using type = |
| | expr<expr<expr<expr<expr<expr<expr<expr<expr<expr< |
| | forward<state::template type, expr>, |
| | _00>, _01>, _02>, _03>, _04>, _05>, _06>, _07>, _08>, _09>; |
| | |
| | }; |
| | template <class state, class _00> |
| | struct left_folder_1 { |
| | template <template <class...> class expr> |
| | using type = expr<forward<state::template type, expr>, _00>; |
| | }; |
| | template <class state> |
| | struct left_folder_0 { |
| | template <template <class...> class> |
| | using type = identity<state>; |
| | }; |
| | template <std::size_t n> |
| | struct _fold_left_impl |
| | |
| | : _fold_left_impl<(n > 100) ? 100 : (n > 10) ? 10 : (n > 1)> { |
| | |
| | }; |
| | template <> |
| | struct _fold_left_impl<100> { |
| | template < |
| | class state, |
| | class _00, class _01, class _02, class _03, class _04, |
| | class _05, class _06, class _07, class _08, class _09, |
| | class _10, class _11, class _12, class _13, class _14, |
| | class _15, class _16, class _17, class _18, class _19, |
| | class _20, class _21, class _22, class _23, class _24, |
| | class _25, class _26, class _27, class _28, class _29, |
| | class _30, class _31, class _32, class _33, class _34, |
| | class _35, class _36, class _37, class _38, class _39, |
| | class _40, class _41, class _42, class _43, class _44, |
| | class _45, class _46, class _47, class _48, class _49, |
| | class _50, class _51, class _52, class _53, class _54, |
| | class _55, class _56, class _57, class _58, class _59, |
| | class _60, class _61, class _62, class _63, class _64, |
| | class _65, class _66, class _67, class _68, class _69, |
| | class _70, class _71, class _72, class _73, class _74, |
| | class _75, class _76, class _77, class _78, class _79, |
| | class _80, class _81, class _82, class _83, class _84, |
| | class _85, class _86, class _87, class _88, class _89, |
| | class _90, class _91, class _92, class _93, class _94, |
| | class _95, class _96, class _97, class _98, class _99, |
| | class... tail> |
| | using type = typename _fold_left_impl<sizeof...(tail)>:: |
| | template type< |
| | left_folder_100< |
| | state, |
| | _00, _01, _02, _03, _04, _05, _06, _07, _08, _09, _10, |
| | _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, |
| | _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, |
| | _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, |
| | _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, |
| | _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, _65, |
| | _66, _67, _68, _69, _70, _71, _72, _73, _74, _75, _76, |
| | _77, _78, _79, _80, _81, _82, _83, _84, _85, _86, _87, |
| | _88, _89, _90, _91, _92, _93, _94, _95, _96, _97, _98, |
| | _99>, |
| | tail...>; |
| | }; |
| | template <> |
| | struct _fold_left_impl<10> { |
| | template < |
| | class state, |
| | class _00, class _01, class _02, class _03, class _04, |
| | class _05, class _06, class _07, class _08, class _09, |
| | class... tail> |
| | using type = typename _fold_left_impl<sizeof...(tail)>:: |
| | template type<left_folder_10<state, _00, _01, _02, _03, _04, _05, _06, _07, _08, _09>, tail...>; |
| | }; |
| | template <> |
| | struct _fold_left_impl<1> { |
| | template <class state, class _00, class... tail> |
| | using type = typename _fold_left_impl<sizeof...(tail)>:: |
| | template type<left_folder_1<state, _00>, tail...>; |
| | }; |
| | template <> |
| | struct _fold_left_impl<0> { |
| | template <class state, class...> |
| | using type = state; |
| | }; |
| | template <class state, class... vals> |
| | struct left_folder |
| | : _fold_left_impl<sizeof...(vals)>:: |
| | template type<left_folder_0<state>, vals...> { |
| | }; |
| | template <class lbd> |
| | struct _fold_left { |
| | }; |
| | template <template <class...> class expr> |
| | struct _fold_left<lambda<expr>> { |
| | template <class... vals> |
| | using type = forward<left_folder<vals...>::template type, expr>; |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class state, class vals> |
| | struct accumulator_impl { |
| | }; |
| | template <class state, class... vals> |
| | struct accumulator_impl<state, list<vals...>> { |
| | template <template <class...> class expr> |
| | using type = expr<state, vals...>; |
| | }; |
| | template <template <class...> class expr> |
| | struct accumulator { |
| | template <class state, class vals> |
| | using type = forward<accumulator_impl<state, vals>::template type, expr>; |
| | }; |
| | template <class state, class... seqs> |
| | struct _accumulate_impl { |
| | template <template <class...> class expr> |
| | using type = forward< |
| | _accumulate_impl<state, transpose<list<seqs...>>>::template type, |
| | accumulator<expr>::template type>; |
| | }; |
| | template <class state, class... vals> |
| | struct _accumulate_impl<state, list<vals...>> { |
| | template <template <class...> class expr> |
| | using type = fold_left<lambda<expr>, state, vals...>; |
| | }; |
| | template <class state> |
| | struct _accumulate_impl<state> { |
| | template <template <class...> class expr> |
| | using type = state; |
| | }; |
| | template <class lbd> |
| | struct _accumulate { |
| | }; |
| | template <template <class...> class expr> |
| | struct _accumulate<lambda<expr>> { |
| | template <class state, class... seqs> |
| | using type = forward<_accumulate_impl<state, seqs...>::template type, expr>; |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | #ifndef METAL_LIST_ALL_OF_HPP |
| | #define METAL_LIST_ALL_OF_HPP |
| | #ifndef METAL_NUMBER_AND_HPP |
| | #define METAL_NUMBER_AND_HPP |
| | #ifndef METAL_NUMBER_NOT_HPP |
| | #define METAL_NUMBER_NOT_HPP |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class num> |
| | using not_ = metal::if_<num, metal::false_, metal::true_>; |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class... nums> |
| | using and_ = metal::same<metal::false_, metal::not_<nums>...>; |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq, class lbd> |
| | using all_of = metal::apply<metal::lambda<metal::and_>, metal::transform<lbd, seq>>; |
| | } |
| | #endif |
| | #ifndef METAL_LIST_ANY_OF_HPP |
| | #define METAL_LIST_ANY_OF_HPP |
| | #ifndef METAL_NUMBER_OR_HPP |
| | #define METAL_NUMBER_OR_HPP |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class... nums> |
| | using or_ = metal::not_<metal::same<metal::true_, metal::not_<nums>...>>; |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq, class lbd> |
| | using any_of = metal::apply<metal::lambda<metal::or_>, metal::transform<lbd, seq>>; |
| | } |
| | #endif |
| | #ifndef METAL_LIST_APPEND_HPP |
| | #define METAL_LIST_APPEND_HPP |
| | #ifndef METAL_LIST_JOIN_HPP |
| | #define METAL_LIST_JOIN_HPP |
| | #include <cstddef> |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <std::size_t n> |
| | struct joiner; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class... seqs> |
| | using join = detail::call<detail::joiner<sizeof...(seqs)>::template type, seqs...>; |
| | } |
| | namespace metal { |
| | |
| | namespace detail { |
| | template < |
| | class = list<>, class = list<>, class = list<>, class = list<>, class = list<>, |
| | class = list<>, class = list<>, class = list<>, class = list<>, class = list<>, |
| | class = list<>, class = list<>, class = list<>, class = list<>, class = list<>, |
| | class = list<>, class = list<>, class = list<>, class = list<>, class = list<>, |
| | class = list<>, class = list<>, class = list<>, class = list<>, class = list<>, |
| | class = list<>, class = list<>, class = list<>, class = list<>, class = list<>, |
| | class = list<>, class = list<>, class = list<>, class = list<>, class = list<>, |
| | class = list<>, class = list<>, class = list<>, class = list<>, class = list<>, |
| | class = list<>, class = list<>, class = list<>, class = list<>, class = list<>, |
| | class = list<>, class = list<>, class = list<>, class = list<>, class = list<>, |
| | class = list<>, class = list<>, class = list<>, class = list<>, class = list<>, |
| | class = list<>, class = list<>, class = list<>, class = list<>, class = list<>, |
| | class = list<>, class = list<>, class = list<>, class = list<>, class = list<>, |
| | class = list<>, class = list<>, class = list<>, class = list<>, class = list<>, |
| | class = list<>, class = list<>, class = list<>, class = list<>, class = list<>, |
| | class = list<>, class = list<>, class = list<>, class = list<>, class = list<>, |
| | class = list<>, class = list<>, class = list<>, class = list<>, class = list<>, |
| | class = list<>, class = list<>, class = list<>, class = list<>, class = list<>, |
| | class = list<>, class = list<>, class = list<>, class = list<>, class = list<>, |
| | class = list<>, class = list<>, class = list<>, class = list<>, class = list<>, |
| | class = list<>> |
| | struct _join_impl { |
| | }; |
| | template < |
| | class... _00, class... _01, class... _02, class... _03, class... _04, |
| | class... _05, class... _06, class... _07, class... _08, class... _09, |
| | class... _10, class... _11, class... _12, class... _13, class... _14, |
| | class... _15, class... _16, class... _17, class... _18, class... _19, |
| | class... _20, class... _21, class... _22, class... _23, class... _24, |
| | class... _25, class... _26, class... _27, class... _28, class... _29, |
| | class... _30, class... _31, class... _32, class... _33, class... _34, |
| | class... _35, class... _36, class... _37, class... _38, class... _39, |
| | class... _40, class... _41, class... _42, class... _43, class... _44, |
| | class... _45, class... _46, class... _47, class... _48, class... _49, |
| | class... _50, class... _51, class... _52, class... _53, class... _54, |
| | class... _55, class... _56, class... _57, class... _58, class... _59, |
| | class... _60, class... _61, class... _62, class... _63, class... _64, |
| | class... _65, class... _66, class... _67, class... _68, class... _69, |
| | class... _70, class... _71, class... _72, class... _73, class... _74, |
| | class... _75, class... _76, class... _77, class... _78, class... _79, |
| | class... _80, class... _81, class... _82, class... _83, class... _84, |
| | class... _85, class... _86, class... _87, class... _88, class... _89, |
| | class... _90, class... _91, class... _92, class... _93, class... _94, |
| | class... _95, class... _96, class... _97, class... _98, class... _99, |
| | class... _> |
| | struct _join_impl< |
| | list<_00...>, list<_01...>, list<_02...>, list<_03...>, list<_04...>, |
| | list<_05...>, list<_06...>, list<_07...>, list<_08...>, list<_09...>, |
| | list<_10...>, list<_11...>, list<_12...>, list<_13...>, list<_14...>, |
| | list<_15...>, list<_16...>, list<_17...>, list<_18...>, list<_19...>, |
| | list<_20...>, list<_21...>, list<_22...>, list<_23...>, list<_24...>, |
| | list<_25...>, list<_26...>, list<_27...>, list<_28...>, list<_29...>, |
| | list<_30...>, list<_31...>, list<_32...>, list<_33...>, list<_34...>, |
| | list<_35...>, list<_36...>, list<_37...>, list<_38...>, list<_39...>, |
| | list<_40...>, list<_41...>, list<_42...>, list<_43...>, list<_44...>, |
| | list<_45...>, list<_46...>, list<_47...>, list<_48...>, list<_49...>, |
| | list<_50...>, list<_51...>, list<_52...>, list<_53...>, list<_54...>, |
| | list<_55...>, list<_56...>, list<_57...>, list<_58...>, list<_59...>, |
| | list<_60...>, list<_61...>, list<_62...>, list<_63...>, list<_64...>, |
| | list<_65...>, list<_66...>, list<_67...>, list<_68...>, list<_69...>, |
| | list<_70...>, list<_71...>, list<_72...>, list<_73...>, list<_74...>, |
| | list<_75...>, list<_76...>, list<_77...>, list<_78...>, list<_79...>, |
| | list<_80...>, list<_81...>, list<_82...>, list<_83...>, list<_84...>, |
| | list<_85...>, list<_86...>, list<_87...>, list<_88...>, list<_89...>, |
| | list<_90...>, list<_91...>, list<_92...>, list<_93...>, list<_94...>, |
| | list<_95...>, list<_96...>, list<_97...>, list<_98...>, list<_99...>, |
| | list<_...>> { |
| | using type = list< |
| | _00..., _01..., _02..., _03..., _04..., _05..., _06..., _07..., _08..., _09..., |
| | _10..., _11..., _12..., _13..., _14..., _15..., _16..., _17..., _18..., _19..., |
| | _20..., _21..., _22..., _23..., _24..., _25..., _26..., _27..., _28..., _29..., |
| | _30..., _31..., _32..., _33..., _34..., _35..., _36..., _37..., _38..., _39..., |
| | _40..., _41..., _42..., _43..., _44..., _45..., _46..., _47..., _48..., _49..., |
| | _50..., _51..., _52..., _53..., _54..., _55..., _56..., _57..., _58..., _59..., |
| | _60..., _61..., _62..., _63..., _64..., _65..., _66..., _67..., _68..., _69..., |
| | _70..., _71..., _72..., _73..., _74..., _75..., _76..., _77..., _78..., _79..., |
| | _80..., _81..., _82..., _83..., _84..., _85..., _86..., _87..., _88..., _89..., |
| | _90..., _91..., _92..., _93..., _94..., _95..., _96..., _97..., _98..., _99..., |
| | _...>; |
| | }; |
| | template <class... seqs> |
| | using join_impl = typename _join_impl<seqs...>::type; |
| | template <std::size_t n> |
| | struct joiner : joiner<(n > 100) ? 100 : 0> { |
| | }; |
| | template <> |
| | struct joiner<100> { |
| | template < |
| | class _00, class _01, class _02, class _03, class _04, |
| | class _05, class _06, class _07, class _08, class _09, |
| | class _10, class _11, class _12, class _13, class _14, |
| | class _15, class _16, class _17, class _18, class _19, |
| | class _20, class _21, class _22, class _23, class _24, |
| | class _25, class _26, class _27, class _28, class _29, |
| | class _30, class _31, class _32, class _33, class _34, |
| | class _35, class _36, class _37, class _38, class _39, |
| | class _40, class _41, class _42, class _43, class _44, |
| | class _45, class _46, class _47, class _48, class _49, |
| | class _50, class _51, class _52, class _53, class _54, |
| | class _55, class _56, class _57, class _58, class _59, |
| | class _60, class _61, class _62, class _63, class _64, |
| | class _65, class _66, class _67, class _68, class _69, |
| | class _70, class _71, class _72, class _73, class _74, |
| | class _75, class _76, class _77, class _78, class _79, |
| | class _80, class _81, class _82, class _83, class _84, |
| | class _85, class _86, class _87, class _88, class _89, |
| | class _90, class _91, class _92, class _93, class _94, |
| | class _95, class _96, class _97, class _98, class _99, |
| | class... tail> |
| | using type = join_impl< |
| | _00, _01, _02, _03, _04, _05, _06, _07, _08, _09, |
| | _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, |
| | _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, |
| | _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, |
| | _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, |
| | _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, |
| | _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, |
| | _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, |
| | _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, |
| | _90, _91, _92, _93, _94, _95, _96, _97, _98, _99, |
| | typename joiner<sizeof...(tail)>::template type<tail...>>; |
| | }; |
| | template <> |
| | struct joiner<0> { |
| | template <class... seqs> |
| | using type = join_impl<seqs...>; |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq, class... vals> |
| | using append = metal::join<seq, metal::list<vals...>>; |
| | } |
| | #endif |
| | #ifndef METAL_LIST_BACK_HPP |
| | #define METAL_LIST_BACK_HPP |
| | #ifndef METAL_NUMBER_DEC_HPP |
| | #define METAL_NUMBER_DEC_HPP |
| | #ifndef METAL_NUMBER_SUB_HPP |
| | #define METAL_NUMBER_SUB_HPP |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class x, class y> |
| | struct _sub; |
| | template <class x, class y> |
| | using sub = typename _sub<x, y>::type; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class... nums> |
| | using sub = fold_left<lambda<detail::sub>, nums..., number<0>>; |
| | |
| | namespace detail { |
| | template <class x, class y> |
| | struct _sub { |
| | }; |
| | template <int_ x, int_ y> |
| | struct _sub<number<x>, number<y>> { |
| | using type = number<x - y>; |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class num> |
| | using dec = metal::sub<num, metal::number<1>>; |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq> |
| | using back = metal::at<seq, metal::dec<metal::size<seq>>>; |
| | } |
| | #endif |
| | #ifndef METAL_LIST_CARTESIAN_HPP |
| | #define METAL_LIST_CARTESIAN_HPP |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class, class> |
| | struct _product; |
| | template <class seqs, class seq> |
| | using product = typename _product<seqs, seq>::type; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class... seqs> |
| | using cartesian = fold_left<lambda<detail::product>, list<list<>>, seqs...>; |
| | } |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class, class> |
| | struct _product_impl { |
| | }; |
| | template <class... xs, class... ys> |
| | struct _product_impl<list<xs...>, list<ys...>> { |
| | using type = list<list<xs..., ys>...>; |
| | }; |
| | template <class seqs, class seq> |
| | using product_impl = typename _product_impl<seqs, seq>::type; |
| | template <class, class> |
| | struct _product { |
| | }; |
| | template <class... seqs, class... vals> |
| | struct _product<list<seqs...>, list<vals...>> { |
| | using type = join<product_impl<seqs, list<vals...>>...>; |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | #ifndef METAL_LIST_CASCADE_HPP |
| | #define METAL_LIST_CASCADE_HPP |
| | #ifndef METAL_VALUE_FOLD_RIGHT_HPP |
| | #define METAL_VALUE_FOLD_RIGHT_HPP |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class lbd> |
| | struct _fold_right; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class lbd, class... vals> |
| | using fold_right = detail::call<detail::_fold_right<lbd>::template type, vals...>; |
| | } |
| | #include <cstddef> |
| | namespace metal { |
| | |
| | namespace detail { |
| | template < |
| | class state, |
| | class _00, class _01, class _02, class _03, class _04, class _05, |
| | class _06, class _07, class _08, class _09, class _10, class _11, |
| | class _12, class _13, class _14, class _15, class _16, class _17, |
| | class _18, class _19, class _20, class _21, class _22, class _23, |
| | class _24, class _25, class _26, class _27, class _28, class _29, |
| | class _30, class _31, class _32, class _33, class _34, class _35, |
| | class _36, class _37, class _38, class _39, class _40, class _41, |
| | class _42, class _43, class _44, class _45, class _46, class _47, |
| | class _48, class _49, class _50, class _51, class _52, class _53, |
| | class _54, class _55, class _56, class _57, class _58, class _59, |
| | class _60, class _61, class _62, class _63, class _64, class _65, |
| | class _66, class _67, class _68, class _69, class _70, class _71, |
| | class _72, class _73, class _74, class _75, class _76, class _77, |
| | class _78, class _79, class _80, class _81, class _82, class _83, |
| | class _84, class _85, class _86, class _87, class _88, class _89, |
| | class _90, class _91, class _92, class _93, class _94, class _95, |
| | class _96, class _97, class _98, class _99> |
| | struct right_folder_100 { |
| | template<template<class...> class expr> |
| | using type = |
| | expr<_00, expr<_01, expr<_02, expr<_03, expr<_04, |
| | expr<_05, expr<_06, expr<_07, expr<_08, expr<_09, |
| | expr<_10, expr<_11, expr<_12, expr<_13, expr<_14, |
| | expr<_15, expr<_16, expr<_17, expr<_18, expr<_19, |
| | expr<_20, expr<_21, expr<_22, expr<_23, expr<_24, |
| | expr<_25, expr<_26, expr<_27, expr<_28, expr<_29, |
| | expr<_30, expr<_31, expr<_32, expr<_33, expr<_34, |
| | expr<_35, expr<_36, expr<_37, expr<_38, expr<_39, |
| | expr<_40, expr<_41, expr<_42, expr<_43, expr<_44, |
| | expr<_45, expr<_46, expr<_47, expr<_48, expr<_49, |
| | expr<_50, expr<_51, expr<_52, expr<_53, expr<_54, |
| | expr<_55, expr<_56, expr<_57, expr<_58, expr<_59, |
| | expr<_60, expr<_61, expr<_62, expr<_63, expr<_64, |
| | expr<_65, expr<_66, expr<_67, expr<_68, expr<_69, |
| | expr<_70, expr<_71, expr<_72, expr<_73, expr<_74, |
| | expr<_75, expr<_76, expr<_77, expr<_78, expr<_79, |
| | expr<_80, expr<_81, expr<_82, expr<_83, expr<_84, |
| | expr<_85, expr<_86, expr<_87, expr<_88, expr<_89, |
| | expr<_90, expr<_91, expr<_92, expr<_93, expr<_94, |
| | expr<_95, expr<_96, expr<_97, expr<_98, expr<_99, |
| | forward<state::template type, expr> |
| | >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> |
| | >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>; |
| | }; |
| | template < |
| | class state, |
| | class _00, class _01, class _02, class _03, class _04, class _05, |
| | class _06, class _07, class _08, class _09> |
| | struct right_folder_10 { |
| | template <template <class...> class expr> |
| | |
| | using type = |
| | expr<_00, expr<_01, expr<_02, expr<_03, expr<_04, |
| | expr<_05, expr<_06, expr<_07, expr<_08, expr<_09, |
| | forward<state::template type, expr> |
| | >>>>>>>>>>; |
| | |
| | }; |
| | template <class state, class _00> |
| | struct right_folder_1 { |
| | template <template <class...> class expr> |
| | using type = expr<_00, forward<state::template type, expr>>; |
| | }; |
| | template <class state> |
| | struct right_folder_0 { |
| | template <template <class...> class> |
| | using type = identity<state>; |
| | }; |
| | template <std::size_t n> |
| | struct _fold_right_impl |
| | |
| | : _fold_right_impl<(n > 100) ? 100 : (n > 10) ? 10: (n > 1)> { |
| | |
| | }; |
| | template <> |
| | struct _fold_right_impl<100> { |
| | template < |
| | class _00, class _01, class _02, class _03, class _04, |
| | class _05, class _06, class _07, class _08, class _09, |
| | class _10, class _11, class _12, class _13, class _14, |
| | class _15, class _16, class _17, class _18, class _19, |
| | class _20, class _21, class _22, class _23, class _24, |
| | class _25, class _26, class _27, class _28, class _29, |
| | class _30, class _31, class _32, class _33, class _34, |
| | class _35, class _36, class _37, class _38, class _39, |
| | class _40, class _41, class _42, class _43, class _44, |
| | class _45, class _46, class _47, class _48, class _49, |
| | class _50, class _51, class _52, class _53, class _54, |
| | class _55, class _56, class _57, class _58, class _59, |
| | class _60, class _61, class _62, class _63, class _64, |
| | class _65, class _66, class _67, class _68, class _69, |
| | class _70, class _71, class _72, class _73, class _74, |
| | class _75, class _76, class _77, class _78, class _79, |
| | class _80, class _81, class _82, class _83, class _84, |
| | class _85, class _86, class _87, class _88, class _89, |
| | class _90, class _91, class _92, class _93, class _94, |
| | class _95, class _96, class _97, class _98, class _99, |
| | class... tail> |
| | using type = right_folder_100< |
| | typename _fold_right_impl<sizeof...(tail) - 1>::template type<tail...>, |
| | _00, _01, _02, _03, _04, _05, _06, _07, _08, _09, |
| | _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, |
| | _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, |
| | _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, |
| | _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, |
| | _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, |
| | _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, |
| | _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, |
| | _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, |
| | _90, _91, _92, _93, _94, _95, _96, _97, _98, _99>; |
| | }; |
| | template <> |
| | struct _fold_right_impl<10> { |
| | template < |
| | class _00, class _01, class _02, class _03, class _04, |
| | class _05, class _06, class _07, class _08, class _09, |
| | class... tail> |
| | using type = right_folder_10< |
| | typename _fold_right_impl<sizeof...(tail) - 1>::template type<tail...>, |
| | _00, _01, _02, _03, _04, _05, _06, _07, _08, _09>; |
| | }; |
| | template <> |
| | struct _fold_right_impl<1> { |
| | template <class _00, class... tail> |
| | using type = right_folder_1<typename _fold_right_impl<sizeof...(tail) - 1>::template type<tail...>, _00>; |
| | }; |
| | template <> |
| | struct _fold_right_impl<0> { |
| | template <class _00> |
| | using type = right_folder_0<_00>; |
| | }; |
| | template <class state, class... vals> |
| | struct right_folder |
| | : _fold_right_impl<sizeof...(vals)>::template type<state, vals...> { |
| | }; |
| | template <class lbd> |
| | struct _fold_right { |
| | }; |
| | template <template <class...> class expr> |
| | struct _fold_right<lambda<expr>> { |
| | template <class... vals> |
| | using type = forward<right_folder<vals...>::template type, expr>; |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class outer, class inner> |
| | struct _cascader; |
| | template <class outer, class inner> |
| | using cascader = typename _cascader<outer, inner>::type; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq, class... lbds> |
| | using cascade = apply<fold_right<lambda<detail::cascader>, lbds...>, seq>; |
| | } |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class outer, class inner> |
| | struct _cascader { |
| | }; |
| | template <template <class...> class outer, template <class...> class inner> |
| | struct _cascader<lambda<outer>, lambda<inner>> { |
| | template <class... seqs> |
| | using impl = invoke<lambda<outer>, apply<lambda<inner>, seqs>...>; |
| | using type = lambda<impl>; |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | #ifndef METAL_LIST_COMBINE_HPP |
| | #define METAL_LIST_COMBINE_HPP |
| | #ifndef METAL_LIST_REPEAT_HPP |
| | #define METAL_LIST_REPEAT_HPP |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class val, class num> |
| | using repeat = metal::transform< |
| | metal::always<val>, |
| | metal::iota<metal::number<0>, num, metal::number<0>>>; |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq, class num = metal::size<seq>> |
| | using combine = metal::apply< |
| | metal::lambda<metal::cartesian>, |
| | metal::repeat<metal::if_<metal::is_list<seq>, seq>, num>>; |
| | } |
| | #endif |
| | #ifndef METAL_LIST_CONTAINS_HPP |
| | #define METAL_LIST_CONTAINS_HPP |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq, class val> |
| | using contains = metal::any_of<seq, metal::partial<metal::lambda<metal::same>, val>>; |
| | } |
| | #endif |
| | #ifndef METAL_LIST_COPY_HPP |
| | #define METAL_LIST_COPY_HPP |
| | #ifndef METAL_LIST_COPY_IF_HPP |
| | #define METAL_LIST_COPY_IF_HPP |
| | #ifndef METAL_LIST_REMOVE_IF_HPP |
| | #define METAL_LIST_REMOVE_IF_HPP |
| | #ifndef METAL_LIST_REPLACE_IF_HPP |
| | #define METAL_LIST_REPLACE_IF_HPP |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class, class, class...> |
| | struct _replace_if; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq, class lbd, class... vals> |
| | using replace_if = typename detail::_replace_if<seq, transform<lbd, seq>, vals...>::type; |
| | } |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class vals, class vs, class...> |
| | struct _replace_if { |
| | }; |
| | template <class... vals, int_... vs, class x, class y, class... t> |
| | struct _replace_if<list<vals...>, list<number<vs>...>, x, y, t...> { |
| | using type = call<join, if_<number<vs>, list<x, y, t...>, list<vals>>...>; |
| | }; |
| | template <class... vals, int_... vs, class x> |
| | struct _replace_if<list<vals...>, list<number<vs>...>, x> { |
| | using type = list<if_<number<vs>, x, vals>...>; |
| | }; |
| | template <class... vals, int_... vs> |
| | struct _replace_if<list<vals...>, list<number<vs>...>> { |
| | using type = call<join, if_<number<vs>, list<>, list<vals>>...>; |
| | }; |
| | template <class x, class y, class... t> |
| | struct _replace_if<list<>, list<>, x, y, t...> { |
| | using type = list<>; |
| | }; |
| | template <class x> |
| | struct _replace_if<list<>, list<>, x> { |
| | using type = list<>; |
| | }; |
| | template <> |
| | struct _replace_if<list<>, list<>> { |
| | using type = list<>; |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq, class lbd> |
| | using remove_if = metal::replace_if<seq, lbd>; |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq, class lbd> |
| | using copy_if = metal::remove_if<seq, metal::bind<metal::lambda<metal::not_>, lbd>>; |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq, class val> |
| | using copy = metal::copy_if<seq, metal::partial<metal::lambda<metal::same>, val>>; |
| | } |
| | #endif |
| | #ifndef METAL_LIST_COUNT_HPP |
| | #define METAL_LIST_COUNT_HPP |
| | #ifndef METAL_LIST_COUNT_IF_HPP |
| | #define METAL_LIST_COUNT_IF_HPP |
| | #ifndef METAL_NUMBER_ADD_HPP |
| | #define METAL_NUMBER_ADD_HPP |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class x, class y> |
| | struct _add; |
| | template <class x, class y> |
| | using add = typename _add<x, y>::type; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class... nums> |
| | using add = fold_left<lambda<detail::add>, nums..., number<0>>; |
| | |
| | namespace detail { |
| | template <class x, class y> |
| | struct _add { |
| | }; |
| | template <int_ x, int_ y> |
| | struct _add<number<x>, number<y>> { |
| | using type = number<x + y>; |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq, class lbd> |
| | using count_if = metal::apply<metal::lambda<metal::add>, metal::transform<lbd, seq>>; |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq, class val> |
| | using count = metal::count_if<seq, metal::partial<metal::lambda<metal::same>, val>>; |
| | } |
| | #endif |
| | #ifndef METAL_LIST_DROP_HPP |
| | #define METAL_LIST_DROP_HPP |
| | #ifndef METAL_LIST_RANGE_HPP |
| | #define METAL_LIST_RANGE_HPP |
| | #ifndef METAL_NUMBER_GREATER_HPP |
| | #define METAL_NUMBER_GREATER_HPP |
| | #ifndef METAL_NUMBER_LESS_HPP |
| | #define METAL_NUMBER_LESS_HPP |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class x, class y> |
| | struct _less; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class x, class y> |
| | using less = typename detail::_less<x, y>::type; |
| | } |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class x, class y> |
| | struct _less { |
| | }; |
| | template <int_ x, int_ y> |
| | struct _less<number<x>, number<y>> : number<(x < y)> { |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class x, class y> |
| | using greater = metal::less<y, x>; |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class seq, class beg, class end> |
| | struct _range; |
| | template <class seq, class beg, class end> |
| | using range = typename detail::_range<seq, beg, end>::type; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq, class beg, class end> |
| | using range = detail::range< |
| | seq, |
| | if_<not_<or_<greater<number<0>, beg>, greater<beg, size<seq>>>>, beg>, |
| | if_<not_<or_<greater<number<0>, end>, greater<end, size<seq>>>>, end>>; |
| | } |
| | #ifndef METAL_LIST_REVERSE_HPP |
| | #define METAL_LIST_REVERSE_HPP |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq> |
| | using reverse = metal::range<seq, metal::size<seq>, metal::number<0>>; |
| | } |
| | #endif |
| | #ifndef METAL_LIST_ROTATE_HPP |
| | #define METAL_LIST_ROTATE_HPP |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class seq, class num> |
| | struct _rotate; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq, class num> |
| | using rotate = typename detail::_rotate<seq, num>::type; |
| | } |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <int_ n> |
| | struct rotator |
| | |
| | : rotator<(n > 100) ? 100 : (n > 10) ? 10 : (n > 1)> { |
| | |
| | }; |
| | template <> |
| | struct rotator<100> { |
| | template <int_ n, |
| | class _00, class _01, class _02, class _03, class _04, |
| | class _05, class _06, class _07, class _08, class _09, |
| | class _10, class _11, class _12, class _13, class _14, |
| | class _15, class _16, class _17, class _18, class _19, |
| | class _20, class _21, class _22, class _23, class _24, |
| | class _25, class _26, class _27, class _28, class _29, |
| | class _30, class _31, class _32, class _33, class _34, |
| | class _35, class _36, class _37, class _38, class _39, |
| | class _40, class _41, class _42, class _43, class _44, |
| | class _45, class _46, class _47, class _48, class _49, |
| | class _50, class _51, class _52, class _53, class _54, |
| | class _55, class _56, class _57, class _58, class _59, |
| | class _60, class _61, class _62, class _63, class _64, |
| | class _65, class _66, class _67, class _68, class _69, |
| | class _70, class _71, class _72, class _73, class _74, |
| | class _75, class _76, class _77, class _78, class _79, |
| | class _80, class _81, class _82, class _83, class _84, |
| | class _85, class _86, class _87, class _88, class _89, |
| | class _90, class _91, class _92, class _93, class _94, |
| | class _95, class _96, class _97, class _98, class _99, |
| | class... tail> |
| | using type = typename rotator<(n - 100)>::template type< |
| | (n - 100), tail..., |
| | _00, _01, _02, _03, _04, _05, _06, _07, _08, _09, |
| | _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, |
| | _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, |
| | _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, |
| | _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, |
| | _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, |
| | _60, _61, _62, _63, _64, _65, _66, _67, _68, _69, |
| | _70, _71, _72, _73, _74, _75, _76, _77, _78, _79, |
| | _80, _81, _82, _83, _84, _85, _86, _87, _88, _89, |
| | _90, _91, _92, _93, _94, _95, _96, _97, _98, _99>; |
| | }; |
| | template <> |
| | struct rotator<10> { |
| | template <int_ n, |
| | class _00, class _01, class _02, class _03, class _04, |
| | class _05, class _06, class _07, class _08, class _09, |
| | class... tail> |
| | using type = typename rotator<(n - 10)>:: |
| | template type<(n - 10), tail..., _00, _01, _02, _03, _04, _05, _06, _07, _08, _09>; |
| | }; |
| | template <> |
| | struct rotator<1> { |
| | template <int_ n, class head, class... tail> |
| | using type = typename rotator<(n - 1)>::template type<(n - 1), tail..., head>; |
| | }; |
| | template <> |
| | struct rotator<0> { |
| | template <int_, class... vals> |
| | using type = list<vals...>; |
| | }; |
| | template <class seq, class num> |
| | struct _rotate { |
| | }; |
| | template <class... vals, int_ n> |
| | struct _rotate<list<vals...>, number<n>> { |
| | enum : int_ { size = sizeof...(vals) }; |
| | enum : std::size_t { m = ((n % size) + size * (n < 0)) }; |
| | using type = typename rotator<m>::template type<m, vals...>; |
| | }; |
| | template <int_ n> |
| | struct _rotate<list<>, number<n>> { |
| | using type = list<>; |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | #ifndef METAL_NUMBER_MAX_HPP |
| | #define METAL_NUMBER_MAX_HPP |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class x, class y> |
| | using max = if_<greater<x, y>, x, y>; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class... nums> |
| | using max = fold_left<lambda<detail::max>, if_<is_number<nums>, nums>...>; |
| | } |
| | #endif |
| | #ifndef METAL_NUMBER_MIN_HPP |
| | #define METAL_NUMBER_MIN_HPP |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class x, class y> |
| | using min = if_<less<x, y>, x, y>; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class... nums> |
| | using min = fold_left<lambda<detail::min>, if_<is_number<nums>, nums>...>; |
| | } |
| | #endif |
| | #include <cstddef> |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class... vals> |
| | struct appender { |
| | template <class... _> |
| | using append = appender<vals..., _...>; |
| | using type = list<vals...>; |
| | }; |
| | template <std::size_t n> |
| | struct reverser |
| | |
| | : reverser<(n > 100) ? 100 : (n > 10) ? 10 : (n > 1)> { |
| | |
| | }; |
| | template <> |
| | struct reverser<100> { |
| | template < |
| | class _00, class _01, class _02, class _03, class _04, |
| | class _05, class _06, class _07, class _08, class _09, |
| | class _10, class _11, class _12, class _13, class _14, |
| | class _15, class _16, class _17, class _18, class _19, |
| | class _20, class _21, class _22, class _23, class _24, |
| | class _25, class _26, class _27, class _28, class _29, |
| | class _30, class _31, class _32, class _33, class _34, |
| | class _35, class _36, class _37, class _38, class _39, |
| | class _40, class _41, class _42, class _43, class _44, |
| | class _45, class _46, class _47, class _48, class _49, |
| | class _50, class _51, class _52, class _53, class _54, |
| | class _55, class _56, class _57, class _58, class _59, |
| | class _60, class _61, class _62, class _63, class _64, |
| | class _65, class _66, class _67, class _68, class _69, |
| | class _70, class _71, class _72, class _73, class _74, |
| | class _75, class _76, class _77, class _78, class _79, |
| | class _80, class _81, class _82, class _83, class _84, |
| | class _85, class _86, class _87, class _88, class _89, |
| | class _90, class _91, class _92, class _93, class _94, |
| | class _95, class _96, class _97, class _98, class _99, |
| | class... tail> |
| | using type = typename reverser<sizeof...(tail)>:: |
| | template type<tail...>::template append< |
| | _99, _98, _97, _96, _95, _94, _93, _92, _91, _90, |
| | _89, _88, _87, _86, _85, _84, _83, _82, _81, _80, |
| | _79, _78, _77, _76, _75, _74, _73, _72, _71, _70, |
| | _69, _68, _67, _66, _65, _64, _63, _62, _61, _60, |
| | _59, _58, _57, _56, _55, _54, _53, _52, _51, _50, |
| | _49, _48, _47, _46, _45, _44, _43, _42, _41, _40, |
| | _39, _38, _37, _36, _35, _34, _33, _32, _31, _30, |
| | _29, _28, _27, _26, _25, _24, _23, _22, _21, _20, |
| | _19, _18, _17, _16, _15, _14, _13, _12, _11, _10, |
| | _09, _08, _07, _06, _05, _04, _03, _02, _01, _00>; |
| | }; |
| | template <> |
| | struct reverser<10> { |
| | template < |
| | class _00, class _01, class _02, class _03, class _04, |
| | class _05, class _06, class _07, class _08, class _09, |
| | class... tail> |
| | using type = typename reverser<sizeof...(tail)>:: |
| | template type<tail...>:: |
| | template append<_09, _08, _07, _06, _05, _04, _03, _02, _01, _00>; |
| | }; |
| | template <> |
| | struct reverser<1> { |
| | template <class _00, class... tail> |
| | using type = typename reverser<sizeof...(tail)>:: |
| | template type<tail...>:: |
| | template append<_00>; |
| | }; |
| | template <> |
| | struct reverser<0> { |
| | template <class...> |
| | using type = appender<>; |
| | }; |
| | template <class seq> |
| | struct _reverse { |
| | }; |
| | template <class... vals> |
| | struct _reverse<list<vals...>> { |
| | using type = typename reverser<sizeof...(vals)>::template type<vals...>::type; |
| | }; |
| | template <class seq> |
| | using reverse = typename _reverse<seq>::type; |
| | template <int_ n> |
| | struct dropper |
| | |
| | : dropper<(n > 100) ? 100 : (n > 10) ? 10 : (n > 1)> { |
| | |
| | }; |
| | template <> |
| | struct dropper<100> { |
| | template < |
| | int_ n, |
| | class, class, class, class, class, class, class, class, class, class, |
| | class, class, class, class, class, class, class, class, class, class, |
| | class, class, class, class, class, class, class, class, class, class, |
| | class, class, class, class, class, class, class, class, class, class, |
| | class, class, class, class, class, class, class, class, class, class, |
| | class, class, class, class, class, class, class, class, class, class, |
| | class, class, class, class, class, class, class, class, class, class, |
| | class, class, class, class, class, class, class, class, class, class, |
| | class, class, class, class, class, class, class, class, class, class, |
| | class, class, class, class, class, class, class, class, class, class, |
| | class... tail> |
| | using type = typename dropper<(n - 100)>::template type<(n - 100), tail...>; |
| | }; |
| | template <> |
| | struct dropper<10> { |
| | template <int_ n, class, class, class, class, class, class, class, class, class, class, class... tail> |
| | using type = typename dropper<(n - 10)>::template type<(n - 10), tail...>; |
| | }; |
| | template <> |
| | struct dropper<1> { |
| | template <int_ n, class, class... tail> |
| | using type = typename dropper<(n - 1)>::template type<(n - 1), tail...>; |
| | }; |
| | template <> |
| | struct dropper<0> { |
| | template <int_, class... vals> |
| | using type = list<vals...>; |
| | }; |
| | template <class seq, class num> |
| | struct _drop { |
| | }; |
| | template <class... vals, int_ n> |
| | struct _drop<list<vals...>, number<n>> { |
| | using type = typename dropper<n>::template type<n, vals...>; |
| | }; |
| | template <class seq, class num> |
| | using drop = typename _drop<seq, num>::type; |
| | template <class seq, class num> |
| | using take = drop<rotate<seq, num>, sub<size<seq>, num>>; |
| | template <class seq, class beg, class end> |
| | struct _range { |
| | using b = min<beg, end>; |
| | using e = max<beg, end>; |
| | using type = range<range<range<seq, number<0>, e>, b, e>, sub<beg, b>, sub<end, b>>; |
| | }; |
| | template <class seq, class num> |
| | struct _range<seq, number<0>, num> { |
| | using type = take<seq, num>; |
| | }; |
| | template <class seq, class num> |
| | struct _range<seq, num, size<seq>> { |
| | using type = drop<seq, num>; |
| | }; |
| | template <class seq> |
| | struct _range<seq, number<0>, size<seq>> { |
| | using type = seq; |
| | }; |
| | template <class seq> |
| | struct _range<seq, size<seq>, number<0>> { |
| | using type = reverse<seq>; |
| | }; |
| | template <> |
| | struct _range<list<>, number<0>, number<0>> { |
| | using type = list<>; |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq, class n> |
| | using drop = metal::range<seq, n, metal::size<seq>>; |
| | } |
| | #endif |
| | #ifndef METAL_LIST_EMPTY_HPP |
| | #define METAL_LIST_EMPTY_HPP |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq> |
| | using empty = metal::not_<metal::size<seq>>; |
| | } |
| | #endif |
| | #ifndef METAL_LIST_ERASE_HPP |
| | #define METAL_LIST_ERASE_HPP |
| | #ifndef METAL_LIST_TAKE_HPP |
| | #define METAL_LIST_TAKE_HPP |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq, class n> |
| | using take = metal::range<seq, metal::number<0>, n>; |
| | } |
| | #endif |
| | #ifndef METAL_NUMBER_INC_HPP |
| | #define METAL_NUMBER_INC_HPP |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class num> |
| | using inc = metal::add<num, metal::number<1>>; |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq, class beg, class end = inc<beg>> |
| | using erase = metal::join< |
| | metal::take<seq, metal::min<beg, end>>, |
| | metal::drop<seq, metal::max<beg, end>>>; |
| | } |
| | #endif |
| | #ifndef METAL_LIST_FIND_HPP |
| | #define METAL_LIST_FIND_HPP |
| | #ifndef METAL_LIST_FIND_IF_HPP |
| | #define METAL_LIST_FIND_IF_HPP |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class seq> |
| | struct _find_if; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq, class lbd> |
| | using find_if = typename detail::_find_if<transform<lbd, seq>>::type; |
| | } |
| | #ifndef METAL_LIST_FRONT_HPP |
| | #define METAL_LIST_FRONT_HPP |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq> |
| | using front = metal::at<seq, metal::number<0>>; |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class seq, class = indices<seq>> |
| | struct _find_index { |
| | }; |
| | template <int_... vs, class... is> |
| | struct _find_index<list<number<vs>...>, list<is...>> { |
| | using type = front<call<join, if_<number<vs>, list<is>, list<>>...>>; |
| | }; |
| | template <class seq> |
| | struct _find_if { |
| | }; |
| | template <> |
| | struct _find_if<list<>> : number<0> { |
| | }; |
| | template <int_... vs> |
| | struct _find_if<list<number<vs>...>> |
| | : _find_index<list<number<vs>..., true_>> { |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq, class val> |
| | using find = metal::find_if<seq, metal::partial<metal::lambda<metal::same>, val>>; |
| | } |
| | #endif |
| | #ifndef METAL_LIST_FLATTEN_HPP |
| | #define METAL_LIST_FLATTEN_HPP |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq> |
| | using flatten = metal::apply<metal::lambda<metal::join>, seq>; |
| | } |
| | #endif |
| | #ifndef METAL_LIST_INSERT_HPP |
| | #define METAL_LIST_INSERT_HPP |
| | #ifndef METAL_LIST_SPLICE_HPP |
| | #define METAL_LIST_SPLICE_HPP |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq, class num, class other> |
| | using splice = metal::join<metal::take<seq, num>, other, metal::drop<seq, num>>; |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq, class num, class... vals> |
| | using insert = metal::splice<seq, num, metal::list<vals...>>; |
| | } |
| | #endif |
| | #ifndef METAL_LIST_NONE_OF_HPP |
| | #define METAL_LIST_NONE_OF_HPP |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq, class lbd> |
| | using none_of = metal::not_<metal::any_of<seq, lbd>>; |
| | } |
| | #endif |
| | #ifndef METAL_LIST_PARTITION_HPP |
| | #define METAL_LIST_PARTITION_HPP |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class lbd> |
| | struct _partition; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq, class lbd> |
| | using partition = detail::call<detail::_partition<lbd>::template type, seq>; |
| | } |
| | #ifndef METAL_PAIR_PAIR_HPP |
| | #define METAL_PAIR_PAIR_HPP |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class val> |
| | struct _is_pair; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class val> |
| | using is_pair = typename detail::_is_pair<val>::type; |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class x, class y> |
| | using pair = metal::list<x, y>; |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class val> |
| | using as_pair = metal::apply<metal::lambda<metal::pair>, metal::as_list<val>>; |
| | } |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class val> |
| | struct _is_pair : false_ { |
| | }; |
| | template <class x, class y> |
| | struct _is_pair<list<x, y>> : true_ { |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class...> |
| | struct _partition_joiner { |
| | }; |
| | template <class... left, class... right> |
| | struct _partition_joiner<list<left, right>...> { |
| | using type = pair<join<left...>, join<right...>>; |
| | }; |
| | template <bool cond> |
| | struct _partition_filter { |
| | template <class val> |
| | using type = list<list<val>, list<>>; |
| | }; |
| | template <> |
| | struct _partition_filter<false> { |
| | template <class val> |
| | using type = list<list<>, list<val>>; |
| | }; |
| | template <class conds, class seq> |
| | struct _partitioner { |
| | }; |
| | template <int_... ns, class... vals> |
| | struct _partitioner<list<number<ns>...>, list<vals...>> |
| | : _partition_joiner<typename _partition_filter<ns>::template type<vals>...> { |
| | }; |
| | template <class seq> |
| | struct _partition_impl { |
| | }; |
| | template <> |
| | struct _partition_impl<list<>> { |
| | template <template <class...> class> |
| | using type = pair<list<>, list<>>; |
| | }; |
| | template <class... vals> |
| | struct _partition_impl<list<vals...>> { |
| | template <template <class...> class expr> |
| | using type = typename _partitioner<list<expr<vals>...>, list<vals...>>::type; |
| | }; |
| | template <class lbd> |
| | struct _partition { |
| | }; |
| | template <template <class...> class expr> |
| | struct _partition<lambda<expr>> { |
| | template <class seq> |
| | using type = forward<_partition_impl<seq>::template type, expr>; |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | #ifndef METAL_LIST_POWERSET_HPP |
| | #define METAL_LIST_POWERSET_HPP |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class, class> |
| | struct _power; |
| | template <class seqs, class val> |
| | using power = typename _power<seqs, val>::type; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq> |
| | using powerset = accumulate<lambda<detail::power>, list<list<>>, metal::reverse<seq>>; |
| | } |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class, class> |
| | struct _power_impl { |
| | }; |
| | template <class... xs, class y> |
| | struct _power_impl<list<xs...>, y> { |
| | using type = list<list<xs...>, list<y, xs...>>; |
| | }; |
| | template <class xs, class y> |
| | using power_impl = typename _power_impl<xs, y>::type; |
| | template <class, class> |
| | struct _power { |
| | }; |
| | template <class... seqs, class val> |
| | struct _power<list<seqs...>, val> { |
| | using type = join<power_impl<seqs, val>...>; |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | #ifndef METAL_LIST_PREPEND_HPP |
| | #define METAL_LIST_PREPEND_HPP |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq, class... vals> |
| | using prepend = metal::join<metal::list<vals...>, seq>; |
| | } |
| | #endif |
| | #ifndef METAL_LIST_REMOVE_HPP |
| | #define METAL_LIST_REMOVE_HPP |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq, class val> |
| | using remove = metal::remove_if<seq, metal::partial<metal::lambda<metal::same>, val>>; |
| | } |
| | #endif |
| | #ifndef METAL_LIST_REPLACE_HPP |
| | #define METAL_LIST_REPLACE_HPP |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq, class val, class... vals> |
| | using replace = metal::replace_if<seq, metal::partial<metal::lambda<metal::same>, val>, vals...>; |
| | } |
| | #endif |
| | #ifndef METAL_LIST_SLICE_HPP |
| | #define METAL_LIST_SLICE_HPP |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq, class start, class size, class stride = number<1>> |
| | using slice = metal::transform< |
| | metal::partial<metal::lambda<metal::at>, metal::if_<metal::is_list<seq>, seq>>, |
| | metal::iota<start, size, stride>>; |
| | } |
| | #endif |
| | #ifndef METAL_LIST_SORT_HPP |
| | #define METAL_LIST_SORT_HPP |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class lbd = metal::lambda<metal::less>> |
| | struct _sort; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | #if !defined(METAL_WORKAROUND) |
| | template <class seq, class lbd = metal::lambda<metal::less>> |
| | using sort = detail::call< |
| | detail::_sort<lbd>::template type, |
| | metal::if_<metal::is_list<seq>, seq>>; |
| | #else |
| | |
| | template <class seq, class... lbd> |
| | using sort = detail::call< |
| | detail::_sort<lbd...>::template type, |
| | metal::if_<metal::is_list<seq>, seq>>; |
| | #endif |
| | } |
| | #ifndef METAL_NUMBER_DIV_HPP |
| | #define METAL_NUMBER_DIV_HPP |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class x, class y> |
| | struct _div; |
| | template <class x, class y> |
| | using div = typename _div<x, y>::type; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class... nums> |
| | using div = fold_left<lambda<detail::div>, nums..., number<1>>; |
| | |
| | namespace detail { |
| | template <class x, class y> |
| | struct _div { |
| | }; |
| | template <int_ x> |
| | struct _div<number<x>, number<0>> { |
| | }; |
| | template <int_ x, int_ y> |
| | struct _div<number<x>, number<y>> { |
| | using type = number<x / y>; |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class x, class y, class z = list<>, class = true_> |
| | struct _merge; |
| | template <class, class, class, template <class...> class, class = true_> |
| | struct _merge_impl { |
| | }; |
| | template < |
| | class xh, class... xt, class yh, class... yt, class... zs, |
| | template <class...> class e> |
| | struct _merge_impl<list<xh, xt...>, list<yh, yt...>, list<zs...>, e, if_<call<e, yh, xh>, true_, false_>> |
| | : _merge_impl<list<xh, xt...>, list<yt...>, list<zs..., yh>, e> { |
| | }; |
| | template < |
| | class xh, class... xt, class yh, class... yt, class... zs, |
| | template <class...> class e> |
| | struct _merge_impl<list<xh, xt...>, list<yh, yt...>, list<zs...>, e, if_<call<e, yh, xh>, false_, true_>> |
| | : _merge_impl<list<xt...>, list<yh, yt...>, list<zs..., xh>, e> { |
| | }; |
| | template <class... xs, class... zs, template <class...> class e> |
| | struct _merge_impl<list<xs...>, list<>, list<zs...>, e> { |
| | template <class x, class y> |
| | using part = typename _merge<prepend<x, xs...>, y, list<zs...>>::template type<e>; |
| | using type = list<zs..., xs...>; |
| | }; |
| | template <class... ys, class... zs, template <class...> class e> |
| | struct _merge_impl<list<>, list<ys...>, list<zs...>, e> { |
| | template <class x, class y> |
| | using part = typename _merge<x, prepend<y, ys...>, list<zs...>>::template type<e>; |
| | using type = list<zs..., ys...>; |
| | }; |
| | template <class x, class y, class z, class> |
| | struct _merge { |
| | using xe = size<x>; |
| | using ye = size<y>; |
| | using xm = div<inc<xe>, number<2>>; |
| | using ym = div<inc<ye>, number<2>>; |
| | using xl = range<x, number<0>, xm>; |
| | using yl = range<y, number<0>, ym>; |
| | using xr = range<x, xm, xe>; |
| | using yr = range<y, ym, ye>; |
| | using l = _merge<xl, yl, z>; |
| | template <template <class...> class expr> |
| | using type = typename l::template type<expr>::template part<xr, yr>; |
| | }; |
| | template <class x, class y, class z> |
| | struct _merge<x, y, z, less<add<size<x>, size<y>>, number<100>>> { |
| | template <template <class...> class expr> |
| | using type = _merge_impl<x, y, z, expr>; |
| | }; |
| | template <class seq> |
| | struct _sort_impl { |
| | using beg = number<0>; |
| | using end = size<seq>; |
| | using mid = div<end, number<2>>; |
| | using l = _sort_impl<range<seq, beg, mid>>; |
| | using r = _sort_impl<range<seq, mid, end>>; |
| | template <template <class...> class expr> |
| | using type = typename _merge< |
| | forward<l::template type, expr>, |
| | forward<r::template type, expr>>::template type<expr>::type; |
| | }; |
| | template <class x, class y> |
| | struct _sort_impl<list<x, y>> { |
| | template <template <class...> class expr> |
| | using type = if_<expr<y, x>, list<y, x>, list<x, y>>; |
| | }; |
| | template <class x> |
| | struct _sort_impl<list<x>> { |
| | template <template <class...> class> |
| | using type = list<x>; |
| | }; |
| | template <> |
| | struct _sort_impl<list<>> { |
| | template <template <class...> class> |
| | using type = list<>; |
| | }; |
| | template <class lbd> |
| | struct _sort { |
| | }; |
| | template <template <class...> class expr> |
| | struct _sort<lambda<expr>> { |
| | template <class... seq> |
| | using type = forward<_sort_impl<seq...>::template type, expr>; |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | |
| | |
| | #endif |
| | #ifndef METAL_MAP_HPP |
| | #define METAL_MAP_HPP |
| | #ifndef METAL_MAP_AT_KEY_HPP |
| | #define METAL_MAP_AT_KEY_HPP |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class seq, class key> |
| | struct _at_key; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq, class key> |
| | using at_key = typename detail::_at_key<seq, key>::type; |
| | } |
| | #ifndef METAL_VALUE_DISTINCT_HPP |
| | #define METAL_VALUE_DISTINCT_HPP |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class... vals> |
| | struct _distinct; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class... vals> |
| | using distinct = typename detail::_distinct<vals...>::type; |
| | } |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class, class base> |
| | struct inherit_second : base { |
| | }; |
| | template <class, class...> |
| | struct inherit_impl { |
| | }; |
| | template <class... _, class... bases> |
| | struct inherit_impl<list<_...>, bases...> |
| | : inherit_second<_, bases>... { |
| | }; |
| | template <class... bases> |
| | struct inherit : inherit_impl<indices<list<bases...>>, bases...> { |
| | }; |
| | template <class... bases> |
| | true_ disambiguate(bases*...); |
| | template <class derived, class... bases> |
| | auto _distinct_impl(derived* _) -> decltype( |
| | disambiguate<bases...>((declptr<bases>(), void(), _)...)); |
| | template <class...> |
| | false_ _distinct_impl(...); |
| | template <class... vals> |
| | struct _distinct |
| | : decltype( |
| | _distinct_impl<inherit<maybe<vals>...>, maybe<vals>...>(0)) { |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class, class = true_> |
| | struct table { |
| | }; |
| | template <class... keys, class... vals> |
| | struct table<list<list<keys, vals>...>, distinct<list<keys, vals>...>> |
| | : list<keys, vals>... { |
| | }; |
| | template <> |
| | struct table<list<>> { |
| | }; |
| | template <class key, class val> |
| | value<val> lookup(list<key, val>*); |
| | template <class> |
| | value<> lookup(...); |
| | template <class seq, class key> |
| | struct _at_key : decltype(lookup<key>(declptr<table<seq>>())) { |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | #ifndef METAL_MAP_ERASE_KEY_HPP |
| | #define METAL_MAP_ERASE_KEY_HPP |
| | #ifndef METAL_MAP_ORDER_HPP |
| | #define METAL_MAP_ORDER_HPP |
| | #ifndef METAL_MAP_KEYS_HPP |
| | #define METAL_MAP_KEYS_HPP |
| | #ifndef METAL_MAP_MAP_HPP |
| | #define METAL_MAP_MAP_HPP |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class val> |
| | struct _is_map; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class val> |
| | using is_map = typename detail::_is_map<val>::type; |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class... pairs> |
| | using map = metal::if_<metal::is_map<metal::list<pairs...>>, metal::list<pairs...>>; |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class val> |
| | using as_map = metal::apply< |
| | metal::lambda<metal::map>, |
| | metal::transform<metal::lambda<metal::as_pair>, metal::as_list<val>>>; |
| | } |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class val> |
| | struct _is_map : false_ { |
| | }; |
| | template <> |
| | struct _is_map<list<>> : true_ { |
| | }; |
| | template <class... keys, class... vals> |
| | struct _is_map<list<list<keys, vals>...>> : distinct<keys...> { |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | #ifndef METAL_PAIR_FIRST_HPP |
| | #define METAL_PAIR_FIRST_HPP |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq> |
| | using first = metal::if_<metal::is_pair<seq>, metal::front<seq>>; |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq> |
| | using keys = metal::if_<metal::is_map<seq>, metal::transform<metal::lambda<metal::first>, seq>>; |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq, class key> |
| | using order = metal::at_key<metal::transpose<metal::pair<metal::keys<seq>, metal::indices<seq>>>, key>; |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq, class key> |
| | using erase_key = metal::erase<seq, metal::order<seq, key>>; |
| | } |
| | #endif |
| | #ifndef METAL_MAP_HAS_KEY_HPP |
| | #define METAL_MAP_HAS_KEY_HPP |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq, class key> |
| | using has_key = metal::contains<metal::keys<seq>, key>; |
| | } |
| | #endif |
| | #ifndef METAL_MAP_INSERT_KEY_HPP |
| | #define METAL_MAP_INSERT_KEY_HPP |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq, class key, class val> |
| | using insert_key = metal::if_< |
| | metal::not_<metal::has_key<seq, key>>, |
| | metal::append<seq, metal::pair<key, val>>>; |
| | } |
| | #endif |
| | #ifndef METAL_MAP_VALUES_HPP |
| | #define METAL_MAP_VALUES_HPP |
| | #ifndef METAL_PAIR_SECOND_HPP |
| | #define METAL_PAIR_SECOND_HPP |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq> |
| | using second = metal::if_<metal::is_pair<seq>, metal::back<seq>>; |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class seq> |
| | using values = metal::if_<metal::is_map<seq>, metal::transform<metal::lambda<metal::second>, seq>>; |
| | } |
| | #endif |
| | |
| | |
| | #endif |
| | #ifndef METAL_NUMBER_HPP |
| | #define METAL_NUMBER_HPP |
| | #ifndef METAL_NUMBER_ABS_HPP |
| | #define METAL_NUMBER_ABS_HPP |
| | #ifndef METAL_NUMBER_NEG_HPP |
| | #define METAL_NUMBER_NEG_HPP |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class num> |
| | using neg = metal::sub<metal::number<0>, num>; |
| | } |
| | #endif |
| | namespace metal { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class num> |
| | using abs = metal::max<num, metal::neg<num>>; |
| | } |
| | #endif |
| | #ifndef METAL_NUMBER_MOD_HPP |
| | #define METAL_NUMBER_MOD_HPP |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class x, class y> |
| | struct _mod; |
| | template <class x, class y> |
| | using mod = typename _mod<x, y>::type; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class... nums> |
| | using mod = fold_left<lambda<detail::mod>, if_<is_number<nums>, nums>...>; |
| | |
| | namespace detail { |
| | template <class x, class y> |
| | struct _mod { |
| | }; |
| | template <int_ x> |
| | struct _mod<number<x>, number<0>> { |
| | }; |
| | template <int_ x, int_ y> |
| | struct _mod<number<x>, number<y>> { |
| | using type = number<x % y>; |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | #ifndef METAL_NUMBER_MUL_HPP |
| | #define METAL_NUMBER_MUL_HPP |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class x, class y> |
| | struct _mul; |
| | template <class x, class y> |
| | using mul = typename _mul<x, y>::type; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class... nums> |
| | using mul = fold_left<lambda<detail::mul>, nums..., number<1>>; |
| | |
| | namespace detail { |
| | template <class x, class y> |
| | struct _mul { |
| | }; |
| | template <int_ x, int_ y> |
| | struct _mul<number<x>, number<y>> { |
| | using type = number<x * y>; |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | #ifndef METAL_NUMBER_POW_HPP |
| | #define METAL_NUMBER_POW_HPP |
| | namespace metal { |
| | |
| | namespace detail { |
| | template <class base, class exp, class ret = number<1>> |
| | struct _pow; |
| | template <class base, class exp> |
| | using pow = typename _pow<base, exp>::type; |
| | } |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | template <class... nums> |
| | using pow = fold_left<lambda<detail::pow>, nums..., number<1>>; |
| | |
| | namespace detail { |
| | template <class base, class exp, class ret> |
| | struct _pow { |
| | }; |
| | template <int_ b, int_ e, int_ r> |
| | struct _pow<number<b>, number<e>, number<r>> |
| | : _pow<number<b * b>, number<e / 2>, number<(e % 2 ? b * r : r)>> { |
| | }; |
| | template <int_ b, int_ r> |
| | struct _pow<number<b>, number<0>, number<r>> : number<1> { |
| | }; |
| | template <int_ b, int_ r> |
| | struct _pow<number<b>, number<1>, number<r>> : number<b * r> { |
| | }; |
| | template <int_ b, int_ r> |
| | struct _pow<number<b>, number<-1>, number<r>> : number<1 / (b * r)> { |
| | }; |
| | template <int_ r> |
| | struct _pow<number<0>, number<-1>, number<r>> { |
| | }; |
| | } |
| | |
| | } |
| | #endif |
| | |
| | |
| | #endif |
| | #ifndef METAL_PAIR_HPP |
| | #define METAL_PAIR_HPP |
| | |
| | |
| | #endif |
| | #ifndef METAL_VALUE_HPP |
| | #define METAL_VALUE_HPP |
| | |
| | |
| | #endif |
| | |
| | |
| | |
| | #endif |
| |
|