Header file meta/meta.hpp

#include <meta/meta_fwd.hpp>

namespace meta
{
    inline namespace v1
    {
        namespace detail
        {
            template <typename T>
            constexpr T* _nullptr_v();
        }
        
        struct nil_;
        
        template <typename T>
        using _t = typename T::type;
        
        namespace lazy
        {
            template <typename T>
            using _t = defer<_t, T>;
        }
        
        template <std::size_t N>
        using size_t = std::integral_constant<std::size_t, N>;
        
        template <bool B>
        using bool_ = std::integral_constant<bool, B>;
        
        template <int I>
        using int_ = std::integral_constant<int, I>;
        
        template <char Ch>
        using char_ = std::integral_constant<char, Ch>;
        
        template <typename T>
        using inc = std::integral_constant<decltype(T::type::value+1), T::type::value+1>;
        
        template <typename T>
        using dec = std::integral_constant<decltype(T::type::value-1), T::type::value-1>;
        
        template <typename T, typename U>
        using plus = std::integral_constant<decltype(T::type::value+U::type::value), T::type::value+U::type::value>;
        
        template <typename T, typename U>
        using minus = std::integral_constant<decltype(T::type::value-U::type::value), T::type::value-U::type::value>;
        
        template <typename T, typename U>
        using multiplies = std::integral_constant<decltype(T::type::value*U::type::value), T::type::value*U::type::value>;
        
        template <typename T, typename U>
        using divides = std::integral_constant<decltype(T::type::value/U::type::value), T::type::value/U::type::value>;
        
        template <typename T>
        using negate = std::integral_constant<decltype(-T::type::value), -T::type::value>;
        
        template <typename T, typename U>
        using modulus = std::integral_constant<decltype(T::type::value%U::type::value), T::type::value%U::type::value>;
        
        template <typename T, typename U>
        using equal_to = bool_<T::type::value==U::type::value>;
        
        template <typename T, typename U>
        using not_equal_to = bool_<T::type::value!=U::type::value>;
        
        template <typename T, typename U>
        using greater = bool_<(T::type::value>U::type::value)>;
        
        template <typename T, typename U>
        using less = bool_<(T::type::value<U::type::value)>;
        
        template <typename T, typename U>
        using greater_equal = bool_<(T::type::value>=U::type::value)>;
        
        template <typename T, typename U>
        using less_equal = bool_<(T::type::value<=U::type::value)>;
        
        template <typename T, typename U>
        using bit_and = std::integral_constant<decltype(T::type::value&U::type::value), T::type::value&U::type::value>;
        
        template <typename T, typename U>
        using bit_or = std::integral_constant<decltype(T::type::value|U::type::value), T::type::value|U::type::value>;
        
        template <typename T, typename U>
        using bit_xor = std::integral_constant<decltype(T::type::value^U::type::value), T::type::value^U::type::value>;
        
        template <typename T>
        using bit_not = std::integral_constant<decltype(~T::type::value), ~T::type::value>;
        
        namespace lazy
        {
            template <typename T>
            using inc = defer<inc, T>;
            
            template <typename T>
            using dec = defer<dec, T>;
            
            template <typename T, typename U>
            using plus = defer<plus, T, U>;
            
            template <typename T, typename U>
            using minus = defer<minus, T, U>;
            
            template <typename T, typename U>
            using multiplies = defer<multiplies, T, U>;
            
            template <typename T, typename U>
            using divides = defer<divides, T, U>;
            
            template <typename T>
            using negate = defer<negate, T>;
            
            template <typename T, typename U>
            using modulus = defer<modulus, T, U>;
            
            template <typename T, typename U>
            using equal_to = defer<equal_to, T, U>;
            
            template <typename T, typename U>
            using not_equal_to = defer<not_equal_to, T, U>;
            
            template <typename T, typename U>
            using greater = defer<greater, T, U>;
            
            template <typename T, typename U>
            using less = defer<less, T, U>;
            
            template <typename T, typename U>
            using greater_equal = defer<greater_equal, T, U>;
            
            template <typename T, typename U>
            using less_equal = defer<less_equal, T, U>;
            
            template <typename T, typename U>
            using bit_and = defer<bit_and, T, U>;
            
            template <typename T, typename U>
            using bit_or = defer<bit_or, T, U>;
            
            template <typename T, typename U>
            using bit_xor = defer<bit_xor, T, U>;
            
            template <typename T>
            using bit_not = defer<bit_not, T>;
        }
        
        namespace detail
        {
            enum class indices_strategy_
            {
                done,
                repeat,
                recurse,
            };
            
            constexpr indices_strategy_ strategy_(std::size_t cur, std::size_t end);
            
            template <typename T>
            constexpr std::size_t range_distance_(T begin, T end);
            
            template <std::size_t End, typename State, indices_strategy_ Status>
            struct make_indices_
            {
                using type = State;
            };
            
            template <typename T, T, typename>
            struct coerce_indices_{};
        }
        
        template <std::size_t ... Is>
        using index_sequence = integer_sequence<std::size_t, Is...>;
        
        template <std::size_t N>
        using make_index_sequence = _t<detail::make_indices_<N, index_sequence<0>, detail::strategy_(1, N)>>;
        
        template <typename T, T N>
        using make_integer_sequence = _t<detail::coerce_indices_<T, 0, make_index_sequence<static_cast<std::size_t>(N)>>>;
        
        template <typename T, T From, T To>
        using integer_range = _t<detail::coerce_indices_<T, From, make_index_sequence<detail::range_distance_(From, To)>>>;
        
        namespace detail
        {
            template <typename, typename>
            struct concat_indices_{};
            
            template <std::size_t ... Is, std::size_t ... Js>
            struct concat_indices_<index_sequence<Is...>, index_sequence<Js...>>
            {
                using type = index_sequence<Is..., (Js+sizeof...(Is))...>;
            };
        }
        
        template <typename F, typename ... Args>
        using invoke = typename F::template invoke<Args...>;
        
        namespace lazy
        {
            template <typename F, typename ... Args>
            using invoke = defer<invoke, F, Args...>;
        }
        
        template <typename T>
        struct id;
        
        template <typename T>
        using id_t = _t<id<T>>;
        
        namespace lazy
        {
            template <typename T>
            using id = defer<id, T>;
        }
        
        template <typename ... Ts>
        using void_ = invoke<id<void>, Ts...>;
        
        namespace detail
        {
            template <typename, typename = void>
            struct is_trait_
            {
                using type = std::false_type;
            };
            
            template <typename T>
            struct is_trait_<T, void_<typename T::type>>
            {
                using type = std::true_type;
            };
            
            template <typename, typename = void>
            struct is_callable_
            {
                using type = std::false_type;
            };
            
            template <typename T>
            struct is_callable_<T, void_<quote<T::template invoke>>>
            {
                using type = std::true_type;
            };
            
            struct defer_if_
            {
                template <template <typename> typename C, typename ... Ts>
                struct result
                {
                    using type = C<Ts...>;
                };
                
                template <template <typename> typename C, typename ... Ts, typename = C<Ts...>>
                result<C, Ts...> try_();
                
                template <template <typename> typename C, typename ... Ts>
                nil_ try_() const;
            };
            
            struct defer_i_if_
            {
                template <typename T, template <T> typename C, T ... Is>
                struct result
                {
                    using type = C<Is...>;
                };
                
                template <typename T, template <T> typename C, T ... Is, typename = C<Is...>>
                result<T, C, Is...> try_();
                
                template <typename T, template <T> typename C, T ... Is>
                nil_ try_() const;
            };
            
            template <template <typename> typename C, typename ... Ts>
            using defer_ = decltype(defer_if_{}.try_<C, Ts...>());
            
            template <typename T, template <T> typename C, T ... Is>
            using defer_i_ = decltype(defer_i_if_{}.try_<T, C, Is...>());
            
            template <typename T>
            using _t_t = _t<_t<T>>;
        }
        
        template <typename T>
        using is_trait = _t<detail::is_trait_<T>>;
        
        template <typename T>
        using is_callable = _t<detail::is_callable_<T>>;
        
        template <template <typename> typename C, typename ... Ts>
        struct defer;
        
        template <typename T, template <T> typename C, T ... Is>
        struct defer_i;
        
        template <template <typename> typename C, typename ... Ts>
        using defer_trait = defer<detail::_t_t, detail::defer_<C, Ts...>>;
        
        template <typename T, template <T> typename C, T ... Is>
        using defer_trait_i = defer<detail::_t_t, detail::defer_i_<T, C, Is...>>;
        
        template <typename T>
        using sizeof_ = meta::size_t<sizeof(T)>;
        
        template <typename T>
        using alignof_ = meta::size_t<alignof(T)>;
        
        namespace lazy
        {
            template <typename T>
            using sizeof_ = defer<sizeof_, T>;
            
            template <typename T>
            using alignof_ = defer<alignof_, T>;
        }
        
        namespace detail
        {
            template <typename, template <typename> typename>
            struct is_
            : std::false_type
            {};
            
            template <typename ... Ts, template <typename> typename C>
            struct is_<C<Ts...>, C>
            : std::true_type
            {};
        }
        
        template <typename T, template <typename> typename C>
        using is = _t<detail::is_<T, C>>;
        
        template <typename ... Fs>
        struct compose;
        
        template <typename F0>
        struct compose<F0>
        {
            template <typename ... Ts>
            using invoke = invoke<F0, Ts...>;
        };
        
        template <typename F0, typename ... Fs>
        struct compose<F0, Fs...>
        {
            template <typename ... Ts>
            using invoke = invoke<F0, invoke<compose<Fs...>, Ts...>>;
        };
        
        namespace lazy
        {
            template <typename ... Fns>
            using compose = defer<compose, Fns...>;
        }
        
        template <template <typename> typename C>
        struct quote;
        
        template <typename T, template <T> typename C>
        struct quote_i;
        
        template <template <typename> typename C>
        using quote_trait = compose<quote<_t>, quote<C>>;
        
        template <typename T, template <T> typename C>
        using quote_trait_i = compose<quote<_t>, quote_i<T, C>>;
        
        template <typename F, typename ... Ts>
        struct bind_front;
        
        template <typename F, typename ... Us>
        struct bind_back;
        
        namespace lazy
        {
            template <typename Fn, typename ... Ts>
            using bind_front = defer<bind_front, Fn, Ts...>;
            
            template <typename Fn, typename ... Ts>
            using bind_back = defer<bind_back, Fn, Ts...>;
        }
        
        namespace extension
        {
            template <typename F, typename List>
            struct apply;
            
            template <typename F, typename Ret, typename ... Args>
            struct apply<F, Ret(Args...)>
            : lazy::invoke<F, Ret, Args...>
            {};
            
            template <typename F, template <typename> typename T, typename ... Ts>
            struct apply<F, T<Ts...>>
            : lazy::invoke<F, Ts...>
            {};
            
            template <typename F, typename T, T ... Is>
            struct apply<F, integer_sequence<T, Is...>>
            : lazy::invoke<F, std::integral_constant<T, Is>...>
            {};
        }
        
        template <typename C, typename List>
        using apply = _t<extension::apply<C, List>>;
        
        namespace lazy
        {
            template <typename F, typename List>
            using apply = defer<apply, F, List>;
        }
        
        template <typename F, typename Q = quote<list>>
        using curry = compose<F, Q>;
        
        template <typename F>
        using uncurry = bind_front<quote<apply>, F>;
        
        namespace lazy
        {
            template <typename F, typename Q = quote<list>>
            using curry = defer<curry, F, Q>;
            
            template <typename F>
            using uncurry = defer<uncurry, F>;
        }
        
        template <typename F>
        struct flip;
        
        namespace lazy
        {
            template <typename F>
            using flip = defer<flip, F>;
        }
        
        namespace detail
        {
            template <typename>
            struct on_{};
            
            template <typename F, typename ... Gs>
            struct on_<F, Gs...>
            {
                template <typename ... Ts>
                using invoke = invoke<F, invoke<compose<Gs...>, Ts>...>;
            };
        }
        
        template <typename ... Fs>
        using on = detail::on_<Fs...>;
        
        namespace lazy
        {
            template <typename F, typename G>
            using on = defer<on, F, G>;
        }
        
        namespace detail
        {
            template <typename, typename = std::true_type>
            struct _if_{};
            
            template <typename If>
            struct _if_<list<If>, bool_<If::type::value>>
            {
                using type = void;
            };
            
            template <typename If, typename Then>
            struct _if_<list<If, Then>, bool_<If::type::value>>
            {
                using type = Then;
            };
            
            template <typename If, typename Then, typename Else>
            struct _if_<list<If, Then, Else>, bool_<If::type::value>>
            {
                using type = Then;
            };
            
            template <typename If, typename Then, typename Else>
            struct _if_<list<If, Then, Else>, bool_<!If::type::value>>
            {
                using type = Else;
            };
        }
        
        template <typename ... Args>
        using if_ = _t<detail::_if_<list<Args...>>>;
        
        template <bool If, typename ... Args>
        using if_c = _t<detail::_if_<list<bool_<If>, Args...>>>;
        
        namespace lazy
        {
            template <typename ... Args>
            using if_ = defer<if_, Args...>;
            
            template <bool If, typename ... Args>
            using if_c = if_<bool_<If>, Args...>;
        }
        
        namespace detail
        {
            template <>
            struct _and_<>
            : std::true_type
            {};
            
            template <typename Bool, typename ... Bools>
            struct _and_<Bool, Bools...>
            : if_c<!Bool::type::value, std::false_type, _and_<Bools...> >
            {};
            
            template <>
            struct _or_<>
            : std::false_type
            {};
            
            template <typename Bool, typename ... Bools>
            struct _or_<Bool, Bools...>
            : if_c<Bool::type::value, std::true_type, _or_<Bools...> >
            {};
        }
        
        template <bool Bool>
        using not_c = bool_<!Bool>;
        
        template <typename Bool>
        using not_ = not_c<Bool::type::value>;
        
        template <bool ... Bools>
        using and_c = std::is_same<integer_sequence<bool, Bools...>, integer_sequence<bool, (Bools||true)...>>;
        
        template <typename ... Bools>
        using strict_and = and_c<Bools::type::value...>;
        
        template <typename ... Bools>
        using and_ = _t<detail::_and_<Bools...>>;
        
        template <bool ... Bools>
        using or_c = not_<std::is_same<integer_sequence<bool, Bools...>, integer_sequence<bool, (Bools&&false)...>>>;
        
        template <typename ... Bools>
        using strict_or = or_c<Bools::type::value...>;
        
        template <typename ... Bools>
        using or_ = _t<detail::_or_<Bools...>>;
        
        namespace lazy
        {
            template <typename ... Bools>
            using and_ = defer<and_, Bools...>;
            
            template <typename ... Bools>
            using or_ = defer<or_, Bools...>;
            
            template <typename Bool>
            using not_ = defer<not_, Bool>;
            
            template <typename ... Bools>
            using strict_and = defer<strict_and, Bools...>;
            
            template <typename ... Bools>
            using strict_or = defer<strict_or, Bools...>;
        }
        
        namespace detail
        {
            template <typename Fun, typename T0>
            struct compose1_
            {
                template <typename X>
                using invoke = invoke<Fun, _t<X>, T0>;
            };
            
            template <typename Fun, typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
            struct compose10_
            {
                template <typename X, typename Y>
                using F = invoke<Fun, X, Y>;
                
                template <typename S>
                using invoke = F<F<F<F<F<F<F<F<F<F<_t<S>, T0>, T1>, T2>, T3>, T4>, T5>, T6>, T7>, T8>, T9>;
            };
            
            template <typename, typename, typename>
            struct fold_{};
            
            template <typename State, typename Fun>
            struct fold_<list<>, State, Fun>
            : State
            {};
            
            template <typename Head, typename ... List, typename State, typename Fun>
            struct fold_<list<Head, List...>, State, Fun>
            : fold_<list<List...>, lazy::invoke<compose1_<Fun, Head>, State>, Fun>
            {};
            
            template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename ... List, typename State, typename Fun>
            struct fold_<list<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, List...>, State, Fun>
            : fold_<list<List...>, lazy::invoke<compose10_<Fun, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>, State>, Fun>
            {};
        }
        
        template <typename List, typename State, typename Fun>
        using fold = _t<detail::fold_<List, id<State>, Fun>>;
        
        template <typename List, typename State, typename Fun>
        using accumulate = fold<List, State, Fun>;
        
        namespace lazy
        {
            template <typename List, typename State, typename Fun>
            using fold = defer<fold, List, State, Fun>;
            
            template <typename List, typename State, typename Fun>
            using accumulate = defer<accumulate, List, State, Fun>;
        }
        
        namespace detail
        {
            template <typename List, typename State, typename Fun>
            struct reverse_fold_{};
            
            template <typename State, typename Fun>
            struct reverse_fold_<list<>, State, Fun>
            {
                using type = State;
            };
            
            template <typename Head, typename ... List, typename State, typename Fun>
            struct reverse_fold_<list<Head, List...>, State, Fun>
            : lazy::invoke<compose1_<Fun, Head>, reverse_fold_<list<List...>, State, Fun> >
            {};
            
            template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename ... List, typename State, typename Fun>
            struct reverse_fold_<list<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, List...>, State, Fun>
            : lazy::invoke<compose10_<Fun, T9, T8, T7, T6, T5, T4, T3, T2, T1, T0>, reverse_fold_<list<List...>, State, Fun> >
            {};
        }
        
        template <typename List, typename State, typename Fun>
        using reverse_fold = _t<detail::reverse_fold_<List, State, Fun>>;
        
        namespace lazy
        {
            template <typename List, typename State, typename Fun>
            using reverse_fold = defer<reverse_fold, List, State, Fun>;
        }
        
        using npos = meta::size_t<std::size_t(-1)>;
        
        template <typename ... Ts>
        struct list;
        
        template <typename List>
        using size = meta::size_t<List::size()>;
        
        namespace lazy
        {
            template <typename List>
            using size = defer<size, List>;
        }
        
        namespace detail
        {
            template <typename ... Lists>
            struct concat_{};
            
            template <>
            struct concat_<>
            {
                using type = list<>;
            };
            
            template <typename ... List1>
            struct concat_<list<List1...>>
            {
                using type = list<List1...>;
            };
            
            template <typename ... List1, typename ... List2, typename ... Rest>
            struct concat_<list<List1...>, list<List2...>, Rest...>
            : concat_<list<List1..., List2...>, Rest...>
            {};
            
            template <typename ... List1, typename ... List2, typename ... List3, typename ... List4, typename ... List5, typename ... List6, typename ... List7, typename ... List8, typename ... List9, typename ... List10, typename ... Rest>
            struct concat_<list<List1...>, list<List2...>, list<List3...>, list<List4...>, list<List5...>, list<List6...>, list<List7...>, list<List8...>, list<List9...>, list<List10...>, Rest...>
            : concat_<list<List1..., List2..., List3..., List4..., List5..., List6..., List7..., List8..., List9..., List10...>, Rest...>
            {};
        }
        
        template <typename ... Lists>
        using concat = _t<detail::concat_<Lists...>>;
        
        namespace lazy
        {
            template <typename ... Lists>
            using concat = defer<concat, Lists...>;
        }
        
        template <typename ListOfLists>
        using join = apply<quote<concat>, ListOfLists>;
        
        namespace lazy
        {
            template <typename ListOfLists>
            using join = defer<join, ListOfLists>;
        }
        
        namespace detail
        {
            template <typename, typename = void>
            struct transform_{};
            
            template <typename ... Ts, typename Fun>
            struct transform_<list<list<Ts...>, Fun>, void_<invoke<Fun, Ts>...>>
            {
                using type = list<invoke<Fun, Ts>...>;
            };
            
            template <typename ... Ts0, typename ... Ts1, typename Fun>
            struct transform_<list<list<Ts0...>, list<Ts1...>, Fun>, void_<invoke<Fun, Ts0, Ts1>...>>
            {
                using type = list<invoke<Fun, Ts0, Ts1>...>;
            };
        }
        
        template <typename ... Args>
        using transform = _t<detail::transform_<list<Args...>>>;
        
        namespace lazy
        {
            template <typename ... Args>
            using transform = defer<transform, Args...>;
        }
        
        namespace detail
        {
            template <typename T, std::size_t>
            using first_ = T;
            
            template <typename T, typename Ints>
            struct repeat_n_c_{};
            
            template <typename T, std::size_t ... Is>
            struct repeat_n_c_<T, index_sequence<Is...>>
            {
                using type = list<first_<T, Is>...>;
            };
        }
        
        template <std::size_t N, typename T = void>
        using repeat_n_c = _t<detail::repeat_n_c_<T, make_index_sequence<N>>>;
        
        template <typename N, typename T = void>
        using repeat_n = repeat_n_c<N::type::value, T>;
        
        namespace lazy
        {
            template <typename N, typename T = void>
            using repeat_n = defer<repeat_n, N, T>;
            
            template <std::size_t N, typename T = void>
            using repeat_n_c = defer<repeat_n, meta::size_t<N>, T>;
        }
        
        namespace detail
        {
            template <typename ... VoidPtrs>
            struct at_impl_<list<VoidPtrs...>>
            {
                static nil_ eval(...);
                
                template <typename T, typename ... Us>
                static T eval(VoidPtrs..., T*, Us*...);
            };
            
            template <typename List, typename N>
            struct at_{};
            
            template <typename ... Ts, typename N>
            struct at_<list<Ts...>, N>
            : decltype(at_impl_<repeat_n<N, void *> >::eval(static_cast<id<Ts> *>(nullptr)...))
            {};
        }
        
        template <typename List, typename N>
        using at = _t<detail::at_<List, N>>;
        
        template <typename List, std::size_t N>
        using at_c = at<List, meta::size_t<N>>;
        
        namespace lazy
        {
            template <typename List, typename N>
            using at = defer<at, List, N>;
        }
        
        namespace detail
        {
            template <typename VoidPtrs>
            struct drop_impl_;
            
            template <typename ... VoidPtrs>
            struct drop_impl_<list<VoidPtrs...>>
            {
                static nil_ eval(...);
                
                template <typename ... Ts>
                static id<list<Ts...>> eval(VoidPtrs..., id<Ts>*...);
            };
            
            template <>
            struct drop_impl_<list<>>
            {
                template <typename ... Ts>
                static id<list<Ts...>> eval(id<Ts>*...);
            };
            
            template <typename List, typename N>
            struct drop_{};
            
            template <typename ... Ts, typename N>
            struct drop_<list<Ts...>, N>
            : decltype(drop_impl_<repeat_n<N, void *> >::eval(detail::_nullptr_v<id<Ts> >()...))
            {};
        }
        
        template <typename List, typename N>
        using drop = _t<detail::drop_<List, N>>;
        
        template <typename List, std::size_t N>
        using drop_c = _t<detail::drop_<List, meta::size_t<N>>>;
        
        namespace lazy
        {
            template <typename List, typename N>
            using drop = defer<drop, List, N>;
        }
        
        namespace detail
        {
            template <typename List>
            struct front_{};
            
            template <typename Head, typename ... List>
            struct front_<list<Head, List...>>
            {
                using type = Head;
            };
        }
        
        template <typename List>
        using front = _t<detail::front_<List>>;
        
        namespace lazy
        {
            template <typename List>
            using front = defer<front, List>;
        }
        
        namespace detail
        {
            template <typename List>
            struct back_{};
            
            template <typename Head, typename ... List>
            struct back_<list<Head, List...>>
            {
                using type = at_c<list<Head, List...>, sizeof...(List)>;
            };
        }
        
        template <typename List>
        using back = _t<detail::back_<List>>;
        
        namespace lazy
        {
            template <typename List>
            using back = defer<back, List>;
        }
        
        namespace detail
        {
            template <typename List, typename T>
            struct push_front_{};
            
            template <typename ... List, typename T>
            struct push_front_<list<List...>, T>
            {
                using type = list<T, List...>;
            };
        }
        
        template <typename List, typename T>
        using push_front = _t<detail::push_front_<List, T>>;
        
        namespace lazy
        {
            template <typename List, typename T>
            using push_front = defer<push_front, List, T>;
        }
        
        namespace detail
        {
            template <typename List>
            struct pop_front_{};
            
            template <typename Head, typename ... List>
            struct pop_front_<list<Head, List...>>
            {
                using type = list<List...>;
            };
        }
        
        template <typename List>
        using pop_front = _t<detail::pop_front_<List>>;
        
        namespace lazy
        {
            template <typename List>
            using pop_front = defer<pop_front, List>;
        }
        
        namespace detail
        {
            template <typename List, typename T>
            struct push_back_{};
            
            template <typename ... List, typename T>
            struct push_back_<list<List...>, T>
            {
                using type = list<List..., T>;
            };
        }
        
        template <typename List, typename T>
        using push_back = _t<detail::push_back_<List, T>>;
        
        namespace lazy
        {
            template <typename List, typename T>
            using push_back = defer<push_back, List, T>;
        }
        
        namespace detail
        {
            template <typename T, typename U>
            using min_ = if_<less<U, T>, U, T>;
            
            template <typename T, typename U>
            using max_ = if_<less<U, T>, T, U>;
        }
        
        template <typename ... Ts>
        using min = fold<pop_front<list<Ts...>>, front<list<Ts...>>, quote<detail::min_>>;
        
        template <typename ... Ts>
        using max = fold<pop_front<list<Ts...>>, front<list<Ts...>>, quote<detail::max_>>;
        
        namespace lazy
        {
            template <typename ... Ts>
            using min = defer<min, Ts...>;
            
            template <typename ... Ts>
            using max = defer<max, Ts...>;
        }
        
        template <typename List>
        using empty = bool_<0==size<List>::type::value>;
        
        namespace lazy
        {
            template <typename List>
            using empty = defer<empty, List>;
        }
        
        template <typename F, typename S>
        using pair = list<F, S>;
        
        template <typename Pair>
        using first = front<Pair>;
        
        template <typename Pair>
        using second = front<pop_front<Pair>>;
        
        namespace lazy
        {
            template <typename Pair>
            using first = defer<first, Pair>;
            
            template <typename Pair>
            using second = defer<second, Pair>;
        }
        
        namespace detail
        {
            constexpr std::size_t find_index_i_(bool const*const first, bool const*const last, std::size_t N = 0);
            
            template <typename List, typename T>
            struct find_index_{};
            
            template <typename V>
            struct find_index_<list<>, V>
            {
                using type = npos;
            };
            
            template <typename ... T, typename V>
            struct find_index_<list<T...>, V>
            {
                static constexpr bool s_v[] = {std::is_same<T, V>::value...};
                
                using type = size_t<find_index_i_(s_v, s_v+sizeof...(T))>;
            };
        }
        
        template <typename List, typename T>
        using find_index = _t<detail::find_index_<List, T>>;
        
        namespace lazy
        {
            template <typename List, typename T>
            using find_index = defer<find_index, List, T>;
        }
        
        namespace detail
        {
            constexpr std::size_t reverse_find_index_i_(bool const*const first, bool const*const last, std::size_t N);
            
            template <typename List, typename T>
            struct reverse_find_index_{};
            
            template <typename V>
            struct reverse_find_index_<list<>, V>
            {
                using type = npos;
            };
            
            template <typename ... T, typename V>
            struct reverse_find_index_<list<T...>, V>
            {
                static constexpr bool s_v[] = {std::is_same<T, V>::value...};
                
                using type = size_t<reverse_find_index_i_(s_v, s_v+sizeof...(T), sizeof...(T))>;
            };
        }
        
        template <typename List, typename T>
        using reverse_find_index = _t<detail::reverse_find_index_<List, T>>;
        
        namespace lazy
        {
            template <typename List, typename T>
            using reverse_find_index = defer<reverse_find_index, List, T>;
        }
        
        template <typename List, typename T>
        using find = drop<List, min<find_index<List, T>, size<List>>>;
        
        namespace lazy
        {
            template <typename List, typename T>
            using find = defer<find, List, T>;
        }
        
        template <typename List, typename T>
        using reverse_find = drop<List, min<reverse_find_index<List, T>, size<List>>>;
        
        namespace lazy
        {
            template <typename List, typename T>
            using reverse_find = defer<reverse_find, List, T>;
        }
        
        namespace detail
        {
            constexpr bool const* find_if_i_(bool const*const begin, bool const*const end);
            
            template <typename List, typename Fun, typename = void>
            struct find_if_{};
            
            template <typename Fun>
            struct find_if_<list<>, Fun>
            {
                using type = list<>;
            };
            
            template <typename ... List, typename Fun>
            struct find_if_<list<List...>, Fun, void_<integer_sequence<bool, bool(invoke<Fun, List>::type::value)...>>>
            {
                static constexpr bool s_v[] = {invoke<Fun, List>::type::value...};
                
                using type = drop_c<list<List...>, detail::find_if_i_(s_v, s_v+sizeof...(List))-s_v>;
            };
        }
        
        template <typename List, typename Fun>
        using find_if = _t<detail::find_if_<List, Fun>>;
        
        namespace lazy
        {
            template <typename List, typename Fun>
            using find_if = defer<find_if, List, Fun>;
        }
        
        namespace detail
        {
            constexpr bool const* reverse_find_if_i_(bool const*const begin, bool const*const pos, bool const*const end);
            
            template <typename List, typename Fun, typename = void>
            struct reverse_find_if_{};
            
            template <typename Fun>
            struct reverse_find_if_<list<>, Fun>
            {
                using type = list<>;
            };
            
            template <typename ... List, typename Fun>
            struct reverse_find_if_<list<List...>, Fun, void_<integer_sequence<bool, bool(invoke<Fun, List>::type::value)...>>>
            {
                static constexpr bool s_v[] = {invoke<Fun, List>::type::value...};
                
                using type = drop_c<list<List...>, detail::reverse_find_if_i_(s_v, s_v+sizeof...(List), s_v+sizeof...(List))-s_v>;
            };
        }
        
        template <typename List, typename Fun>
        using reverse_find_if = _t<detail::reverse_find_if_<List, Fun>>;
        
        namespace lazy
        {
            template <typename List, typename Fun>
            using reverse_find_if = defer<reverse_find_if, List, Fun>;
        }
        
        namespace detail
        {
            template <typename List, typename T, typename U>
            struct replace_{};
            
            template <typename ... List, typename T, typename U>
            struct replace_<list<List...>, T, U>
            {
                using type = list<if_<std::is_same<T, List>, U, List>...>;
            };
        }
        
        template <typename List, typename T, typename U>
        using replace = _t<detail::replace_<List, T, U>>;
        
        namespace lazy
        {
            template <typename List, typename T, typename U>
            using replace = defer<replace, T, U>;
        }
        
        namespace detail
        {
            template <typename List, typename C, typename U, typename = void>
            struct replace_if_{};
            
            template <typename ... List, typename C, typename U>
            struct replace_if_<list<List...>, C, U, void_<integer_sequence<bool, bool(invoke<C, List>::type::value)...>>>
            {
                using type = list<if_<invoke<C, List>, U, List>...>;
            };
        }
        
        template <typename List, typename C, typename U>
        using replace_if = _t<detail::replace_if_<List, C, U>>;
        
        namespace lazy
        {
            template <typename List, typename C, typename U>
            using replace_if = defer<replace_if, C, U>;
        }
        
        namespace detail
        {
            constexpr std::size_t count_i_(bool const*const begin, bool const*const end, std::size_t n);
            
            template <typename List, typename T, typename = void>
            struct count_{};
            
            template <typename T>
            struct count_<list<>, T>
            {
                using type = meta::size_t<0>;
            };
            
            template <typename ... List, typename T>
            struct count_<list<List...>, T>
            {
                static constexpr bool s_v[] = {std::is_same<T, List>::value...};
                
                using type = meta::size_t<detail::count_i_(s_v, s_v+sizeof...(List), 0u)>;
            };
        }
        
        template <typename List, typename T>
        using count = _t<detail::count_<List, T>>;
        
        namespace lazy
        {
            template <typename List, typename T>
            using count = defer<count, List, T>;
        }
        
        namespace detail
        {
            template <typename List, typename Fn, typename = void>
            struct count_if_{};
            
            template <typename Fn>
            struct count_if_<list<>, Fn>
            {
                using type = meta::size_t<0>;
            };
            
            template <typename ... List, typename Fn>
            struct count_if_<list<List...>, Fn, void_<integer_sequence<bool, bool(invoke<Fn, List>::type::value)...>>>
            {
                static constexpr bool s_v[] = {invoke<Fn, List>::type::value...};
                
                using type = meta::size_t<detail::count_i_(s_v, s_v+sizeof...(List), 0u)>;
            };
        }
        
        template <typename List, typename Fn>
        using count_if = _t<detail::count_if_<List, Fn>>;
        
        namespace lazy
        {
            template <typename List, typename Fn>
            using count_if = defer<count_if, List, Fn>;
        }
        
        namespace detail
        {
            template <typename Pred>
            struct filter_
            {
                template <typename A>
                using invoke = if_c<invoke<Pred, A>::type::value, list<A>, list<>>;
            };
        }
        
        template <typename List, typename Pred>
        using filter = join<transform<List, detail::filter_<Pred>>>;
        
        namespace lazy
        {
            template <typename List, typename Pred>
            using filter = defer<filter, List, Pred>;
        }
        
        namespace detail
        {
            template <typename T>
            struct static_const
            {
                static constexpr T{} value;
            };
        }
        
        namespace detail
        {
            struct for_each_fn
            {
                template <typename UnaryFunction, typename ... Args>
                constexpr UnaryFunction operator()(list<Args...>, UnaryFunction f) const;
            };
        }
        
        namespace 
        {
            constexpr auto&& for_each = detail::static_const<detail::for_each_fn>::value;
        }
        
        template <typename ListOfLists>
        using transpose = fold<ListOfLists, repeat_n<size<front<ListOfLists>>, list<>>, bind_back<quote<transform>, quote<push_back>>>;
        
        namespace lazy
        {
            template <typename ListOfLists>
            using transpose = defer<transpose, ListOfLists>;
        }
        
        template <typename Fun, typename ListOfLists>
        using zip_with = transform<transpose<ListOfLists>, uncurry<Fun>>;
        
        namespace lazy
        {
            template <typename Fun, typename ListOfLists>
            using zip_with = defer<zip_with, Fun, ListOfLists>;
        }
        
        template <typename ListOfLists>
        using zip = transpose<ListOfLists>;
        
        namespace lazy
        {
            template <typename ListOfLists>
            using zip = defer<zip, ListOfLists>;
        }
        
        namespace detail
        {
            template <typename T>
            using uncvref_t = _t<std::remove_cv<_t<std::remove_reference<T>>>>;
            
            template <typename Sequence>
            struct as_list_
            : lazy::invoke<uncurry<curry<quote_trait<id> > >, uncvref_t<Sequence> >
            {};
        }
        
        template <typename Sequence>
        using as_list = _t<detail::as_list_<Sequence>>;
        
        namespace lazy
        {
            template <typename Sequence>
            using as_list = defer<as_list, Sequence>;
        }
        
        namespace detail
        {
            template <typename List, typename State = list<>>
            struct reverse_
            : lazy::fold<List, State, quote<push_front> >
            {};
            
            template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename ... Ts, typename ... Us>
            struct reverse_<list<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, Ts...>, list<Us...>>
            : reverse_<list<Ts...>, list<T9, T8, T7, T6, T5, T4, T3, T2, T1, T0, Us...> >
            {};
        }
        
        template <typename List>
        using reverse = _t<detail::reverse_<List>>;
        
        namespace lazy
        {
            template <typename List>
            using reverse = defer<reverse, List>;
        }
        
        template <typename F>
        using not_fn = compose<quote<not_>, F>;
        
        namespace lazy
        {
            template <typename F>
            using not_fn = defer<not_fn, F>;
        }
        
        template <typename List, typename F>
        using all_of = empty<find_if<List, not_fn<F>>>;
        
        namespace lazy
        {
            template <typename List, typename Fn>
            using all_of = defer<all_of, List, Fn>;
        }
        
        template <typename List, typename F>
        using any_of = not_<empty<find_if<List, F>>>;
        
        namespace lazy
        {
            template <typename List, typename Fn>
            using any_of = defer<any_of, List, Fn>;
        }
        
        template <typename List, typename F>
        using none_of = empty<find_if<List, F>>;
        
        namespace lazy
        {
            template <typename List, typename Fn>
            using none_of = defer<none_of, List, Fn>;
        }
        
        template <typename List, typename T>
        using in = not_<empty<find<List, T>>>;
        
        namespace lazy
        {
            template <typename List, typename T>
            using in = defer<in, List, T>;
        }
        
        namespace detail
        {
            template <typename List>
            struct inherit_{};
            
            template <typename ... List>
            struct inherit_<list<List...>>
            : List
            {
                using type = inherit_;
            };
        }
        
        template <typename List>
        using inherit = meta::_t<detail::inherit_<List>>;
        
        namespace lazy
        {
            template <typename List>
            using inherit = defer<inherit, List>;
        }
        
        namespace detail
        {
            template <typename Set, typename T>
            struct in_{};
            
            template <typename ... Set, typename T>
            struct in_<list<Set...>, T>
            : std::is_base_of<id<T>, inherit<list<id<Set>...> > >
            {};
            
            template <typename Set, typename T>
            struct insert_back_{};
            
            template <typename ... Set, typename T>
            struct insert_back_<list<Set...>, T>
            {
                using type = if_<in_<list<Set...>, T>, list<Set...>, list<Set..., T>>;
            };
        }
        
        template <typename List>
        using unique = fold<List, list<>, quote_trait<detail::insert_back_>>;
        
        namespace lazy
        {
            template <typename List>
            using unique = defer<unique, List>;
        }
        
        namespace detail
        {
            template <typename Pred>
            struct partition_
            {
                template <typename, typename, typename = void>
                struct impl{};
                
                template <typename ... Yes, typename ... No, typename A>
                struct impl<pair<list<Yes...>, list<No...>>, A, void_<bool_<invoke<Pred, A>::type::value>>>
                {
                    using type = if_<invoke<Pred, A>, pair<list<Yes..., A>, list<No...>>, pair<list<Yes...>, list<No..., A>>>;
                };
                
                template <typename State, typename A>
                using invoke = _t<impl<State, A>>;
            };
        }
        
        template <typename List, typename Pred>
        using partition = fold<List, pair<list<>, list<>>, detail::partition_<Pred>>;
        
        namespace lazy
        {
            template <typename List, typename Pred>
            using partition = defer<partition, List, Pred>;
        }
        
        namespace detail
        {
            template <typename, typename, typename = void>
            struct sort_{};
            
            template <typename Pred>
            struct sort_<list<>, Pred>
            {
                using type = list<>;
            };
            
            template <typename A, typename Pred>
            struct sort_<list<A>, Pred>
            {
                using type = list<A>;
            };
            
            template <typename A, typename B, typename ... List, typename Pred>
            struct sort_<list<A, B, List...>, Pred, void_<_t<sort_<first<partition<list<B, List...>, bind_back<Pred, A>>>, Pred>>>>
            {
                using P = partition<list<B, List...>, bind_back<Pred, A>>;
                
                using type = concat<_t<sort_<first<P>, Pred>>, list<A>, _t<sort_<second<P>, Pred>>>;
            };
        }
        
        template <typename List, typename Pred>
        using sort = _t<detail::sort_<List, Pred>>;
        
        namespace lazy
        {
            template <typename List, typename Pred>
            using sort = defer<sort, List, Pred>;
        }
        
        namespace detail
        {
            template <typename If, typename ... Ts>
            using lazy_if_ = lazy::_t<defer<_if_, list<If, protect_<Ts>...>>>;
            
            template <typename A, typename T, typename F, typename Ts>
            struct subst1_
            {
                using type = list<list<T>>;
            };
            
            template <typename T, typename F, typename Ts>
            struct subst1_<F, T, F, Ts>
            {
                using type = list<>;
            };
            
            template <typename A, typename T, typename F, typename Ts>
            struct subst1_<vararg_<A>, T, F, Ts>
            {
                using type = list<Ts>;
            };
            
            template <typename As, typename Ts>
            using substitutions_ = push_back<join<transform<concat<As, repeat_n_c<size<Ts>{}+2-size<As>{}, back<As>>>, concat<Ts, repeat_n_c<2, back<As>>>, bind_back<quote_trait<subst1_>, back<As>, drop_c<Ts, size<As>{}-2>>>>, list<back<As>>>;
            
            template <typename As, typename Ts>
            using substitutions = invoke<if_c<(size<Ts>{}+2>=size<As>{}), quote<substitutions_>>, As, Ts>;
            
            template <typename T>
            struct is_vararg_
            : std::false_type
            {};
            
            template <typename T>
            struct is_vararg_<vararg_<T>>
            : std::true_type
            {};
            
            template <typename Tags>
            using is_variadic_ = is_vararg_<at<push_front<Tags, void>, dec<size<Tags>>>>;
            
            template <typename ... As>
            struct lambda_<list<As...>, false>
            {
                template <typename ... Ts>
                using invoke = _t<if_c<sizeof...(Ts)==arity, impl<F, list<Ts..., F>>>>;
            };
            
            template <typename ... As>
            struct lambda_<list<As...>, true>
            {
                template <typename ... Ts>
                using invoke = invoke<thunk, substitutions<Tags, list<Ts...>>>;
            };
        }
        
        template <typename ... Ts>
        using lambda = if_c<(sizeof...(Ts)>0), detail::lambda_<list<Ts...>>>;
        
        template <typename T>
        using is_valid = detail::is_valid_<T>;
        
        template <typename T>
        using vararg = detail::vararg_<T>;
        
        template <typename T>
        using protect = detail::protect_<T>;
        
        namespace detail
        {
            template <typename ... As>
            struct let_{};
            
            template <typename Fn>
            struct let_<Fn>
            {
                using type = lazy::invoke<lambda<Fn>>;
            };
            
            template <typename Tag, typename Value, typename ... Rest>
            struct let_<var<Tag, Value>, Rest...>
            {
                using type = lazy::invoke<lambda<Tag, _t<let_<Rest...>>>, Value>;
            };
        }
        
        template <typename ... As>
        using let = _t<_t<detail::let_<As...>>>;
        
        namespace lazy
        {
            template <typename ... As>
            using let = defer<let, As...>;
        }
        
        inline namespace placeholders
        {
            using _args = vararg<void>;
            
            using _args_a = vararg<_a>;
            
            using _args_b = vararg<_b>;
            
            using _args_c = vararg<_c>;
        }
        
        namespace detail
        {
            template <typename M2, typename M>
            struct cartesian_product_fn
            {
                template <typename X>
                struct lambda0
                {
                    template <typename Xs>
                    using lambda1 = list<push_front<Xs, X>>;
                    
                    using type = join<transform<M2, quote<lambda1>>>;
                };
                
                using type = join<transform<M, quote_trait<lambda0>>>;
            };
        }
        
        template <typename ListOfLists>
        using cartesian_product = reverse_fold<ListOfLists, list<list<>>, quote_trait<detail::cartesian_product_fn>>;
        
        namespace lazy
        {
            template <typename ListOfLists>
            using cartesian_product = defer<cartesian_product, ListOfLists>;
        }
        
        template <typename If>
        using add_const_if = if_<If, quote_trait<std::add_const>, quote_trait<id>>;
        
        template <bool If>
        using add_const_if_c = if_c<If, quote_trait<std::add_const>, quote_trait<id>>;
        
        namespace detail
        {
            template <typename State, typename Ch>
            using atoi_ = if_c<(Ch::value>='0'&&Ch::value<='9'), std::integral_constant<typename State::value_type, State::value*10+(Ch::value-'0')>>;
        }
        
        inline namespace literals
        {
            template <char ... Chs>
            constexpr fold<list<char_<Chs>...>, meta::size_t<0>, quote<detail::atoi_>> operator""_z();
        }
    }
}

Function template meta::v1::detail::_nullptr_v<T>

template <typename T>
constexpr T* _nullptr_v();

Returns a \p T nullptr


Class meta::v1::nil_

struct nil_{};

An empty type.


Alias template meta::v1::_t<T>

template <typename T>
using _t = typename T::type;

Type alias for \p T::type.


Alias template meta::v1::lazy::_t<T>

template <typename T>
using _t = defer<_t, T>;

meta::_t


Alias template meta::v1::size_t<N>

template <std::size_t N>
using size_t = std::integral_constant<std::size_t, N>;

An integral constant wrapper for \c std::size_t.


Alias template meta::v1::bool_<B>

template <bool B>
using bool_ = std::integral_constant<bool, B>;

An integral constant wrapper for \c bool.


Alias template meta::v1::int_<I>

template <int I>
using int_ = std::integral_constant<int, I>;

An integral constant wrapper for \c int.


Alias template meta::v1::char_<Ch>

template <char Ch>
using char_ = std::integral_constant<char, Ch>;

An integral constant wrapper for \c char.


Alias template meta::v1::inc<T>

template <typename T>
using inc = std::integral_constant<decltype(T::type::value+1), T::type::value+1>;

//////////////////////////////////////////////////////////////////////////////////////// An integral constant wrapper around the result of incrementing the wrapped integer \c T::type::value.


Alias template meta::v1::dec<T>

template <typename T>
using dec = std::integral_constant<decltype(T::type::value-1), T::type::value-1>;

An integral constant wrapper around the result of decrementing the wrapped integer \c T::type::value.


Alias template meta::v1::plus<T, U>

template <typename T, typename U>
using plus = std::integral_constant<decltype(T::type::value+U::type::value), T::type::value+U::type::value>;

An integral constant wrapper around the result of adding the two wrapped integers


Alias template meta::v1::minus<T, U>

template <typename T, typename U>
using minus = std::integral_constant<decltype(T::type::value-U::type::value), T::type::value-U::type::value>;

An integral constant wrapper around the result of subtracting the two wrapped integers


Alias template meta::v1::multiplies<T, U>

template <typename T, typename U>
using multiplies = std::integral_constant<decltype(T::type::value*U::type::value), T::type::value*U::type::value>;

An integral constant wrapper around the result of multiplying the two wrapped integers


Alias template meta::v1::divides<T, U>

template <typename T, typename U>
using divides = std::integral_constant<decltype(T::type::value/U::type::value), T::type::value/U::type::value>;

An integral constant wrapper around the result of dividing the two wrapped integers \c T::type::value and \c U::type::value.


Alias template meta::v1::negate<T>

template <typename T>
using negate = std::integral_constant<decltype(-T::type::value), -T::type::value>;

An integral constant wrapper around the result of negating the wrapped integer


Alias template meta::v1::modulus<T, U>

template <typename T, typename U>
using modulus = std::integral_constant<decltype(T::type::value%U::type::value), T::type::value%U::type::value>;

An integral constant wrapper around the remainder of dividing the two wrapped integers


Alias template meta::v1::equal_to<T, U>

template <typename T, typename U>
using equal_to = bool_<T::type::value==U::type::value>;

A Boolean integral constant wrapper around the result of comparing \c T::type::value and


Alias template meta::v1::not_equal_to<T, U>

template <typename T, typename U>
using not_equal_to = bool_<T::type::value!=U::type::value>;

A Boolean integral constant wrapper around the result of comparing \c T::type::value and


Alias template meta::v1::greater<T, U>

template <typename T, typename U>
using greater = bool_<(T::type::value>U::type::value)>;

A Boolean integral constant wrapper around \c true if \c T::type::value is greater than


Alias template meta::v1::less<T, U>

template <typename T, typename U>
using less = bool_<(T::type::value<U::type::value)>;

A Boolean integral constant wrapper around \c true if \c T::type::value is less than \c U::type::value; \c false, otherwise.


Alias template meta::v1::greater_equal<T, U>

template <typename T, typename U>
using greater_equal = bool_<(T::type::value>=U::type::value)>;

A Boolean integral constant wrapper around \c true if \c T::type::value is greater than or equal to \c U::type::value; \c false, otherwise.


Alias template meta::v1::less_equal<T, U>

template <typename T, typename U>
using less_equal = bool_<(T::type::value<=U::type::value)>;

A Boolean integral constant wrapper around \c true if \c T::type::value is less than or equal to \c U::type::value; \c false, otherwise.


Alias template meta::v1::bit_and<T, U>

template <typename T, typename U>
using bit_and = std::integral_constant<decltype(T::type::value&U::type::value), T::type::value&U::type::value>;

An integral constant wrapper around the result of bitwise-and'ing the two wrapped integers \c T::type::value and \c U::type::value.


Alias template meta::v1::bit_or<T, U>

template <typename T, typename U>
using bit_or = std::integral_constant<decltype(T::type::value|U::type::value), T::type::value|U::type::value>;

An integral constant wrapper around the result of bitwise-or'ing the two wrapped integers \c T::type::value and \c U::type::value.


Alias template meta::v1::bit_xor<T, U>

template <typename T, typename U>
using bit_xor = std::integral_constant<decltype(T::type::value^U::type::value), T::type::value^U::type::value>;

An integral constant wrapper around the result of bitwise-exclusive-or'ing the two wrapped integers \c T::type::value and \c U::type::value.


Alias template meta::v1::bit_not<T>

template <typename T>
using bit_not = std::integral_constant<decltype(~T::type::value), ~T::type::value>;

An integral constant wrapper around the result of bitwise-complementing the wrapped integer \c T::type::value.


Alias template meta::v1::index_sequence<Is...>

template <std::size_t ... Is>
using index_sequence = integer_sequence<std::size_t, Is...>;

//////////////////////////////////////////////////////////////////////////////////////////// A container for a sequence of compile-time integer constants of type


Alias template meta::v1::make_index_sequence<N>

template <std::size_t N>
using make_index_sequence = _t<detail::make_indices_<N, index_sequence<0>, detail::strategy_(1, N)>>;

Generate \c index_sequence containing integer constants [0,1,2,...,N-1].


Alias template meta::v1::make_integer_sequence<T, N>

template <typename T, T N>
using make_integer_sequence = _t<detail::coerce_indices_<T, 0, make_index_sequence<static_cast<std::size_t>(N)>>>;

Generate \c integer_sequence containing integer constants [0,1,2,...,N-1].


Alias template meta::v1::integer_range<T, From, To>

template <typename T, T From, T To>
using integer_range = _t<detail::coerce_indices_<T, From, make_index_sequence<detail::range_distance_(From, To)>>>;

//////////////////////////////////////////////////////////////////////////////////////////// Makes the integer sequence <tt>[From, To)</tt>.


Alias template meta::v1::invoke<F, Args...>

template <typename F, typename ... Args>
using invoke = typename F::template invoke<Args...>;

Evaluate the Callable \p F with the arguments \p Args.


Alias template meta::v1::lazy::invoke<F, Args...>

template <typename F, typename ... Args>
using invoke = defer<invoke, F, Args...>;

meta::invoke


Class template meta::v1::id<T>

template <typename T>
struct id
{
    static id impl(void*);
    
    using type = T;
    
    template <typename ... Ts>
    using invoke = _t<decltype(id::impl(static_cast<list<Ts...>*>(nullptr)))>;
};

A trait that always returns its argument \p T. Also, a Callable that always returns


Alias template meta::v1::id_t<T>

template <typename T>
using id_t = _t<id<T>>;

An alias for type \p T. Useful in non-deduced contexts.


Alias template meta::v1::lazy::id<T>

template <typename T>
using id = defer<id, T>;

meta::id


Alias template meta::v1::void_<Ts...>

template <typename ... Ts>
using void_ = invoke<id<void>, Ts...>;

An alias for void.


Alias template meta::v1::is_trait<T>

template <typename T>
using is_trait = _t<detail::is_trait_<T>>;

An alias for std::true_type if T::type exists and names a type; otherwise, it's an alias for std::false_type.


Alias template meta::v1::is_callable<T>

template <typename T>
using is_callable = _t<detail::is_callable_<T>>;

An alias for std::true_type if T::invoke exists and names a class template or alias template; otherwise, it's an alias for std::false_type.


Class template meta::v1::defer<C, Ts...>

template <template <typename> typename C, typename ... Ts>
struct defer
: detail::defer_<C, Ts...>
{};

//////////////////////////////////////////////////////////////////////////////////////// A wrapper that defers the instantiation of a template \p C with type parameters \p Ts in a \c lambda or \c let expression.

In the code below, the lambda would ideally be written as lambda<_a,_b,push_back<_a,_b>>, however this fails since push_back expects its first argument to be a list, not a placeholder. Instead, we express it using \c defer as follows:

template<typename List> using reverse = reverse_fold<List, list<>, lambda<_a, _b, defer<push_back, _a, _b>>>;


Class template meta::v1::defer_i<T, C, Is...>

template <typename T, template <T> typename C, T ... Is>
struct defer_i
: detail::defer_i_<T, C, Is...>
{};

//////////////////////////////////////////////////////////////////////////////////////// A wrapper that defers the instantiation of a template \p C with integral constant parameters \p Is in a \c lambda or \c let expression. defer


Alias template meta::v1::defer_trait<C, Ts...>

template <template <typename> typename C, typename ... Ts>
using defer_trait = defer<detail::_t_t, detail::defer_<C, Ts...>>;

//////////////////////////////////////////////////////////////////////////////////////// A wrapper that defers the instantiation of a trait \p C with type parameters defer


Alias template meta::v1::defer_trait_i<T, C, Is...>

template <typename T, template <T> typename C, T ... Is>
using defer_trait_i = defer<detail::_t_t, detail::defer_i_<T, C, Is...>>;

//////////////////////////////////////////////////////////////////////////////////////// A wrapper that defers the instantiation of a trait \p C with integral constant parameters \p Is in a \c lambda or \c let expression. defer_i


Alias template meta::v1::sizeof_<T>

template <typename T>
using sizeof_ = meta::size_t<sizeof(T)>;

An alias that computes the size of the type \p T.


Alias template meta::v1::alignof_<T>

template <typename T>
using alignof_ = meta::size_t<alignof(T)>;

An alias that computes the alignment required for any instance of the type


Alias template meta::v1::lazy::sizeof_<T>

template <typename T>
using sizeof_ = defer<sizeof_, T>;

meta::sizeof_


Alias template meta::v1::lazy::alignof_<T>

template <typename T>
using alignof_ = defer<alignof_, T>;

meta::alignof_


Alias template meta::v1::is<T, C>

template <typename T, template <typename> typename C>
using is = _t<detail::is_<T, C>>;

Test whether a type \c T is an instantiation of class template \c C.


Class template meta::v1::compose<Fs...>

template <typename ... Fs>
struct compose{};

Compose the Callables \p Fs in the parameter pack \p Ts.


Class template meta::v1::quote<C>

template <template <typename> typename C>
struct quote
{
    template <typename ... Ts>
    using invoke = _t<detail::defer_<C, Ts...>>;
};

Turn a class template or alias template \p C into a Callable.


Class template meta::v1::quote_i<T, C>

template <typename T, template <T> typename C>
struct quote_i
{
    template <typename ... Ts>
    using invoke = _t<detail::defer_i_<T, C, Ts::type::value...>>;
};

Turn a class template or alias template \p C taking literals of type \p T into a Callable.


Alias template meta::v1::quote_trait<C>

template <template <typename> typename C>
using quote_trait = compose<quote<_t>, quote<C>>;

Turn a trait template \p C into a Callable. static_assert(std::is_same<invoke<quote_traitstd::add_const, int>, int const>::value, "");


Alias template meta::v1::quote_trait_i<T, C>

template <typename T, template <T> typename C>
using quote_trait_i = compose<quote<_t>, quote_i<T, C>>;

Turn a trait \p C taking literals of type \p T into a Callable.


Class template meta::v1::bind_front<F, Ts...>

template <typename F, typename ... Ts>
struct bind_front
{
    template <typename ... Us>
    using invoke = invoke<F, Ts..., Us...>;
};

A Callable that partially applies the Callable


Class template meta::v1::bind_back<F, Us...>

template <typename F, typename ... Us>
struct bind_back
{
    template <typename ... Ts>
    using invoke = invoke<F, Ts..., Us...>;
};

A Callable that partially applies the Callable \p F by binding the arguments \p Us to the \e back of \p F.


Class template meta::v1::extension::apply<F, List>

template <typename F, typename List>
struct apply{};

A trait that unpacks the types in the type list \p List into the Callable


Alias template meta::v1::apply<C, List>

template <typename C, typename List>
using apply = _t<extension::apply<C, List>>;

Applies the Callable \p C using the types in the type list \p List as arguments.


Alias template meta::v1::curry<F, Q>

template <typename F, typename Q = quote<list>>
using curry = compose<F, Q>;

A Callable that takes a bunch of arguments, bundles them into a type list, and then calls the Callable \p F with the type list \p Q.


Alias template meta::v1::uncurry<F>

template <typename F>
using uncurry = bind_front<quote<apply>, F>;

A Callable that takes a type list, unpacks the types, and then calls the Callable \p F with the types.


Class template meta::v1::flip<F>

template <typename F>
struct flip
{
    template <typename ... Ts>
    using invoke = _t<impl<Ts...>>;
};

A Callable that reverses the order of the first two arguments.


Alias template meta::v1::on<Fs...>

template <typename ... Fs>
using on = detail::on_<Fs...>;

Use as on<F, Gs...>. Creates an Callable that applies Callable \c F to the result of applying Callable compose<Gs...> to all the arguments.


Alias template meta::v1::if_<Args...>

template <typename ... Args>
using if_ = _t<detail::_if_<list<Args...>>>;

Select one type or another depending on a compile-time Boolean.


Alias template meta::v1::if_c<If, Args...>

template <bool If, typename ... Args>
using if_c = _t<detail::_if_<list<bool_<If>, Args...>>>;

Select one type or another depending on a compile-time Boolean.


Alias template meta::v1::not_c<Bool>

template <bool Bool>
using not_c = bool_<!Bool>;

Logically negate the Boolean parameter


Alias template meta::v1::not_<Bool>

template <typename Bool>
using not_ = not_c<Bool::type::value>;

Logically negate the integral constant-wrapped Boolean parameter.


Alias template meta::v1::and_c<Bools...>

template <bool ... Bools>
using and_c = std::is_same<integer_sequence<bool, Bools...>, integer_sequence<bool, (Bools||true)...>>;

Logically and together all the Boolean parameters


Alias template meta::v1::strict_and<Bools...>

template <typename ... Bools>
using strict_and = and_c<Bools::type::value...>;

Logically and together all the integral constant-wrapped Boolean parameters, doing short-circuiting.


Alias template meta::v1::and_<Bools...>

template <typename ... Bools>
using and_ = _t<detail::_and_<Bools...>>;

Logically and together all the integral constant-wrapped Boolean parameters, short-circuiting.


Alias template meta::v1::or_c<Bools...>

template <bool ... Bools>
using or_c = not_<std::is_same<integer_sequence<bool, Bools...>, integer_sequence<bool, (Bools&&false)...>>>;

Logically or together all the Boolean parameters


Alias template meta::v1::strict_or<Bools...>

template <typename ... Bools>
using strict_or = or_c<Bools::type::value...>;

Logically or together all the integral constant-wrapped Boolean parameters, doing short-circuiting.


Alias template meta::v1::or_<Bools...>

template <typename ... Bools>
using or_ = _t<detail::_or_<Bools...>>;

Logically or together all the integral constant-wrapped Boolean parameters, short-circuiting.


Alias template meta::v1::fold<List, State, Fun>

template <typename List, typename State, typename Fun>
using fold = _t<detail::fold_<List, id<State>, Fun>>;

Return a new \c meta::list constructed by doing a left fold of the list \p List using binary Callable \p Fun and initial state \p State. That is, the \c State_N for the list element \c A_N is computed by Fun(State_N-1, A_N) -> State_N.


Alias template meta::v1::accumulate<List, State, Fun>

template <typename List, typename State, typename Fun>
using accumulate = fold<List, State, Fun>;

An alias for meta::fold.


Alias template meta::v1::reverse_fold<List, State, Fun>

template <typename List, typename State, typename Fun>
using reverse_fold = _t<detail::reverse_fold_<List, State, Fun>>;

Return a new \c meta::list constructed by doing a right fold of the list \p List using binary Callable \p Fun and initial state \p State. That is, the \c State_N for the list element \c A_N is computed by Fun(A_N, State_N+1) -> State_N.


Type alias meta::v1::npos

using npos = meta::size_t<std::size_t(-1)>;

//////////////////////////////////////////////////////////////////////////////////////////// A special value used to indicate no matches. It equals the maximum value representable by std::size_t.


Class template meta::v1::list<Ts...>

template <typename ... Ts>
struct list
{
    using type = list;
    
    static constexpr std::size_t size() noexcept;
};

//////////////////////////////////////////////////////////////////////////////////////// A list of types.

Function meta::v1::list<Ts...>::size

static constexpr std::size_t size() noexcept;

sizeof...(Ts)



Alias template meta::v1::size<List>

template <typename List>
using size = meta::size_t<List::size()>;

//////////////////////////////////////////////////////////////////////////////////////// An integral constant wrapper that is the size of the \c meta::list


Alias template meta::v1::concat<Lists...>

template <typename ... Lists>
using concat = _t<detail::concat_<Lists...>>;

Concatenates several lists into a single list.


Alias template meta::v1::join<ListOfLists>

template <typename ListOfLists>
using join = apply<quote<concat>, ListOfLists>;

Joins a list of lists into a single list. where each \c T is itself an instantiation of \c meta::list. lists.


Alias template meta::v1::transform<Args...>

template <typename ... Args>
using transform = _t<detail::transform_<list<Args...>>>;

Return a new \c meta::list constructed by transforming all the elements in the unary Callable \p Fun. \c transform can also be called with two lists of the same length and a binary Callable, in which case it returns a new list constructed with the results of calling \c Fun with each element in the lists, pairwise.


Alias template meta::v1::repeat_n_c<N, T>

template <std::size_t N, typename T = void>
using repeat_n_c = _t<detail::repeat_n_c_<T, make_index_sequence<N>>>;

Generate list<T,T,T...T> of size \p N arguments.


Alias template meta::v1::repeat_n<N, T>

template <typename N, typename T = void>
using repeat_n = repeat_n_c<N::type::value, T>;

Generate list<T,T,T...T> of size \p N arguments.


Alias template meta::v1::at<List, N>

template <typename List, typename N>
using at = _t<detail::at_<List, N>>;

//////////////////////////////////////////////////////////////////////////////////////// Return the \p N th element in the \c meta::list \p List. Amortized \f$ O(1) \f$.


Alias template meta::v1::at_c<List, N>

template <typename List, std::size_t N>
using at_c = at<List, meta::size_t<N>>;

Return the \p N th element in the \c meta::list \p List. Amortized \f$ O(1) \f$.


Class template meta::v1::detail::drop_impl_<VoidPtrs>

template <typename VoidPtrs>
struct drop_impl_
{
    static nil_ eval(...);
};

//////////////////////////////////////////////////////////////////////////////////// drop_impl_


Alias template meta::v1::drop<List, N>

template <typename List, typename N>
using drop = _t<detail::drop_<List, N>>;

Return a new \c meta::list by removing the first \p N elements from \p List.


Alias template meta::v1::drop_c<List, N>

template <typename List, std::size_t N>
using drop_c = _t<detail::drop_<List, meta::size_t<N>>>;

Return a new \c meta::list by removing the first \p N elements from \p List.


Alias template meta::v1::front<List>

template <typename List>
using front = _t<detail::front_<List>>;

Return the first element in \c meta::list \p List.


Alias template meta::v1::back<List>

template <typename List>
using back = _t<detail::back_<List>>;

Return the last element in \c meta::list \p List. Amortized \f$ O(1) \f$.


Alias template meta::v1::push_front<List, T>

template <typename List, typename T>
using push_front = _t<detail::push_front_<List, T>>;

Return a new \c meta::list by adding the element \c T to the front of \p List.


Alias template meta::v1::pop_front<List>

template <typename List>
using pop_front = _t<detail::pop_front_<List>>;

Return a new \c meta::list by removing the first element from the front of


Alias template meta::v1::push_back<List, T>

template <typename List, typename T>
using push_back = _t<detail::push_back_<List, T>>;

Return a new \c meta::list by adding the element \c T to the back of \p List. complexity guarantees one would expect.


Alias template meta::v1::min<Ts...>

template <typename ... Ts>
using min = fold<pop_front<list<Ts...>>, front<list<Ts...>>, quote<detail::min_>>;

An integral constant wrapper around the minimum of Ts::type::value...


Alias template meta::v1::max<Ts...>

template <typename ... Ts>
using max = fold<pop_front<list<Ts...>>, front<list<Ts...>>, quote<detail::max_>>;

An integral constant wrapper around the maximum of Ts::type::value...


Alias template meta::v1::empty<List>

template <typename List>
using empty = bool_<0==size<List>::type::value>;

//////////////////////////////////////////////////////////////////////////////////////// An Boolean integral constant wrapper around \c true if \p List is an empty type list; \c false, otherwise.


Alias template meta::v1::pair<F, S>

template <typename F, typename S>
using pair = list<F, S>;

//////////////////////////////////////////////////////////////////////////////////////// A list with exactly two elements


Alias template meta::v1::first<Pair>

template <typename Pair>
using first = front<Pair>;

Retrieve the first element of the \c pair \p Pair


Alias template meta::v1::second<Pair>

template <typename Pair>
using second = front<pop_front<Pair>>;

Retrieve the first element of the \c pair \p Pair


Alias template meta::v1::find_index<List, T>

template <typename List, typename T>
using find_index = _t<detail::find_index_<List, T>>;

Finds the index of the first occurrence of the type \p T within the list \p List. Returns #meta::npos if the type \p T was not found. meta::npos


Alias template meta::v1::reverse_find_index<List, T>

template <typename List, typename T>
using reverse_find_index = _t<detail::reverse_find_index_<List, T>>;

Finds the index of the last occurrence of the type \p T within the list \p List. Returns #meta::npos if the type \p T was not found. #meta::npos


Alias template meta::v1::find<List, T>

template <typename List, typename T>
using find = drop<List, min<find_index<List, T>, size<List>>>;

///////////////////////////////////////////////////////////////////////////////// Return the tail of the list \p List starting at the first occurrence of \p T, if any such element exists; the empty list, otherwise.


Alias template meta::v1::reverse_find<List, T>

template <typename List, typename T>
using reverse_find = drop<List, min<reverse_find_index<List, T>, size<List>>>;

///////////////////////////////////////////////////////////////////////////////// Return the tail of the list \p List starting at the last occurrence of \p T, if any such element exists; the empty list, otherwise.


Alias template meta::v1::find_if<List, Fun>

template <typename List, typename Fun>
using find_if = _t<detail::find_if_<List, Fun>>;

Return the tail of the list \p List starting at the first element A such that invoke<Fun, A>::%value is \c true, if any such element exists; the empty list, otherwise.


Alias template meta::v1::reverse_find_if<List, Fun>

template <typename List, typename Fun>
using reverse_find_if = _t<detail::reverse_find_if_<List, Fun>>;

Return the tail of the list \p List starting at the last element A such that invoke<Fun, A>::%value is \c true, if any such element exists; the empty list, otherwise.


Alias template meta::v1::replace<List, T, U>

template <typename List, typename T, typename U>
using replace = _t<detail::replace_<List, T, U>>;

Return a new \c meta::list where all instances of type \p T have been replaced with


Alias template meta::v1::replace_if<List, C, U>

template <typename List, typename C, typename U>
using replace_if = _t<detail::replace_if_<List, C, U>>;

Return a new \c meta::list where all elements \c A of the list \p List for which invoke<C,A>::%value is \c true have been replaced with \p U.


Alias template meta::v1::count<List, T>

template <typename List, typename T>
using count = _t<detail::count_<List, T>>;

Count the number of times a type \p T appears in the list \p List.


Alias template meta::v1::lazy::count<List, T>

template <typename List, typename T>
using count = defer<count, List, T>;

meta::count


Alias template meta::v1::count_if<List, Fn>

template <typename List, typename Fn>
using count_if = _t<detail::count_if_<List, Fn>>;

Count the number of times the predicate \p Fn evaluates to true for all the elements in the list \p List.


Alias template meta::v1::lazy::count_if<List, Fn>

template <typename List, typename Fn>
using count_if = defer<count_if, List, Fn>;

meta::count_if


Alias template meta::v1::filter<List, Pred>

template <typename List, typename Pred>
using filter = join<transform<List, detail::filter_<Pred>>>;

Returns a new meta::list where only those elements of \p List that satisfy the Callable \p Pred such that invoke<Pred,A>::%value is \c true are present. That is, those elements that don't satisfy the \p Pred are "removed".


Variable meta::v1::for_each

constexpr auto&& for_each = detail::static_const<detail::for_each_fn>::value;

for_each(List, UnaryFunction) calls the \p UnaryFunction for each argument in the \p List.


Alias template meta::v1::transpose<ListOfLists>

template <typename ListOfLists>
using transpose = fold<ListOfLists, repeat_n<size<front<ListOfLists>>, list<>>, bind_back<quote<transform>, quote<push_back>>>;

//////////////////////////////////////////////////////////////////////////////////////// Given a list of lists of types \p ListOfLists, transpose the elements from the lists.


Alias template meta::v1::zip_with<Fun, ListOfLists>

template <typename Fun, typename ListOfLists>
using zip_with = transform<transpose<ListOfLists>, uncurry<Fun>>;

//////////////////////////////////////////////////////////////////////////////////////// Given a list of lists of types \p ListOfLists and a Callable \p Fun, construct a new list by calling \p Fun with the elements from the lists pairwise.


Alias template meta::v1::zip<ListOfLists>

template <typename ListOfLists>
using zip = transpose<ListOfLists>;

//////////////////////////////////////////////////////////////////////////////////////// Given a list of lists of types \p ListOfLists, construct a new list by grouping the elements from the lists pairwise into meta::lists. is the size of the inner lists.


Alias template meta::v1::as_list<Sequence>

template <typename Sequence>
using as_list = _t<detail::as_list_<Sequence>>;

Turn a type into an instance of \c meta::list in a way determined by


Alias template meta::v1::reverse<List>

template <typename List>
using reverse = _t<detail::reverse_<List>>;

Return a new \c meta::list by reversing the elements in the list \p List.


Alias template meta::v1::not_fn<F>

template <typename F>
using not_fn = compose<quote<not_>, F>;

Logically negate the result of Callable \p F.


Alias template meta::v1::all_of<List, F>

template <typename List, typename F>
using all_of = empty<find_if<List, not_fn<F>>>;

//////////////////////////////////////////////////////////////////////////////////////// A Boolean integral constant wrapper around \c true if invoke<F, A>::%value is \c true for all elements \c A in \c meta::list \p List; \c false, otherwise.


Alias template meta::v1::any_of<List, F>

template <typename List, typename F>
using any_of = not_<empty<find_if<List, F>>>;

//////////////////////////////////////////////////////////////////////////////////////// A Boolean integral constant wrapper around \c true if invoke<F, A>::%value is


Alias template meta::v1::none_of<List, F>

template <typename List, typename F>
using none_of = empty<find_if<List, F>>;

//////////////////////////////////////////////////////////////////////////////////////// A Boolean integral constant wrapper around \c true if invoke<F, A>::%value is otherwise.


Alias template meta::v1::in<List, T>

template <typename List, typename T>
using in = not_<empty<find<List, T>>>;

//////////////////////////////////////////////////////////////////////////////////////// A Boolean integral constant wrapper around \c true if there is at least one occurrence of \p T in \p List.


Alias template meta::v1::inherit<List>

template <typename List>
using inherit = meta::_t<detail::inherit_<List>>;

A type that inherits from all the types in the list


Alias template meta::v1::unique<List>

template <typename List>
using unique = fold<List, list<>, quote_trait<detail::insert_back_>>;

//////////////////////////////////////////////////////////////////////////////////////// Return a new \c meta::list where all duplicate elements have been removed.


Alias template meta::v1::partition<List, Pred>

template <typename List, typename Pred>
using partition = fold<List, pair<list<>, list<>>, detail::partition_<Pred>>;

Returns a pair of lists, where the elements of \p List that satisfy the Callable \p Pred such that invoke<Pred,A>::%value is \c true are present in the first list and the rest are in the second.


Alias template meta::v1::sort<List, Pred>

template <typename List, typename Pred>
using sort = _t<detail::sort_<List, Pred>>;

Return a new \c meta::list that is sorted according to Callable predicate \p Pred. Expected: \f$ O(N log N) \f$ Worst case: \f$ O(N^2) \f$. using L0 = list<char[5], char[3], char[2], char[6], char[1], char[5], char[10]>; using L1 = meta::sort<L0, lambda<_a, b, lazy::less<lazy::sizeof<a>, lazy::sizeof<_b>>>>; static_assert(std::is_same<L1, list<char[1], char[2], char[3], char[5], char[5], char[6], char[10]>>::value, "");


Alias template meta::v1::lambda<Ts...>

template <typename ... Ts>
using lambda = if_c<(sizeof...(Ts)>0), detail::lambda_<list<Ts...>>>;

//////////////////////////////////////////////////////////////////////////////////////// For creating anonymous Callables. using L = lambda<_a, _b, std::pair<_b, std::pair<_a, _a>>>; using P = invoke<L, int, short>; static_assert(std::is_same<P, std::pair<short, std::pair<int, int>>>::value, "");


Alias template meta::v1::is_valid<T>

template <typename T>
using is_valid = detail::is_valid_<T>;

//////////////////////////////////////////////////////////////////////////////////////// For testing whether a deferred computation will succeed in a \c let or a \c lambda.


Alias template meta::v1::vararg<T>

template <typename T>
using vararg = detail::vararg_<T>;

//////////////////////////////////////////////////////////////////////////////////////// For defining variadic placeholders.


Alias template meta::v1::protect<T>

template <typename T>
using protect = detail::protect_<T>;

//////////////////////////////////////////////////////////////////////////////////////// For preventing the evaluation of a nested defered computation in a \c let or


Alias template meta::v1::let<As...>

template <typename ... As>
using let = _t<_t<detail::let_<As...>>>;

A lexically scoped expression with local variables.

template<typename T, typename List> using find_index_ = let< var<_a, List>, var<_b, lazy::find<a, T>>, lazy::if< std::is_same<_b, list<>>, meta::npos, lazy::minus<lazy::size<a>, lazy::size<b>>>>; static_assert(find_index<int, list<short, int, float>>{} == 1, ""); static_assert(find_index<double, list<short, int, float>>{} == meta::npos{}, "");


Alias template meta::v1::lazy::let<As...>

template <typename ... As>
using let = defer<let, As...>;

meta::let


Alias template meta::v1::cartesian_product<ListOfLists>

template <typename ListOfLists>
using cartesian_product = reverse_fold<ListOfLists, list<list<>>, quote_trait<detail::cartesian_product_fn>>;

Given a list of lists \p ListOfLists, return a new list of lists that is the Cartesian Product. Like the sequence function from the Haskell Prelude.


Alias template meta::v1::add_const_if<If>

template <typename If>
using add_const_if = if_<If, quote_trait<std::add_const>, quote_trait<id>>;

////////////////////////////////////////////////////////////////////////////////////////


Function template meta::v1::literals::operator""_z<Chs...>

template <char ... Chs>
constexpr fold<list<char_<Chs>...>, meta::size_t<0>, quote<detail::atoi_>> operator""_z();

A user-defined literal that generates objects of type \c meta::size_t.