namespace std { // integral constants template<bool B> using mp_bool = integral_constant<bool, B>; template<int I> using mp_int = integral_constant<int, I>; template<size_t N> using mp_size_t = integral_constant<size_t, N>; using mp_true = mp_bool<true>; using mp_false = mp_bool<false>; template<class T> using mp_to_bool = mp_bool<static_cast<bool>(T::value)>; template<class T> using mp_not = mp_bool< !T::value >; // utility components template<class T> struct mp_identity; template<class T> using mp_identity_t = typename mp_identity<T>::type; template<class... T> struct mp_inherit; template<bool C, class T, class E> using mp_if_c = /*see below*/; template<class C, class T, class E> using mp_if = mp_if_c<static_cast<bool>(C::value), T, E>; template<bool C, class T, template<class...> class F, class... U> using mp_eval_if_c = /*see below*/; template<class C, class T, template<class...> class F, class... U> using mp_eval_if = mp_eval_if_c<static_cast<bool>(C::value), T, F, U...>; template<class C, class T, class Q, class... U> using mp_eval_if_q = mp_eval_if<C, T, Q::template fn, U...>; template<class C, class T, class... R> using mp_cond = /*see below*/; template<template<class...> class F, class... T> using mp_valid = /*see below*/; template<template<class...> class F, class... T> using mp_defer = /*see below*/; template<template<class...> class F> struct mp_quote; template<template<class...> class F> struct mp_quote_trait; template<class Q, class... T> using mp_invoke = typename Q::template fn<T...>; // list operations template<class... T> struct mp_list {}; template<class T, T... I> using mp_list_c = mp_list<integral_constant<T, I>...>; template<class L> using mp_is_list = /*see below*/; template<class L> using mp_size = /*see below*/; template<class L> using mp_empty = mp_bool<mp_size<L>::value == 0>; template<class L1, class L2> using mp_assign = /*see below*/; template<class L> using mp_clear = mp_assign<L, mp_list<>>; template<class L> using mp_front = /*see below*/; template<class L> using mp_pop_front = /*see below*/; template<class L> using mp_first = mp_front<L>; template<class L> using mp_rest = mp_pop_front<L>; template<class L> using mp_second = /*see below*/; template<class L> using mp_third = /*see below*/; template<class L, class... T> using mp_push_front = /*see below*/; template<class L, class... T> using mp_push_back = /*see below*/; template<class L, template<class...> class Y> using mp_rename = /*see below*/; template<template<class...> class F, class L> using mp_apply = mp_rename<L, F>; template<class Q, class L> using mp_apply_q = mp_apply<Q::template fn, L>; template<class... L> using mp_append = /*see below*/; template<class L, class T> using mp_replace_front = /*see below*/; template<class L, class T> using mp_replace_first = mp_replace_front<L, T>; template<class L, class T> using mp_replace_second = /*see below*/; template<class L, class T> using mp_replace_third = /*see below*/; // algorithms template<template<class...> class F, class... L> using mp_transform = /*see below*/; template<class Q, class... L> using mp_transform_q = mp_transform<Q::template fn, L...>; template<template<class...> class P, template<class...> class F, class... L> using mp_transform_if = /*see below*/; template<class Qp, class Qf, class... L> using mp_transform_if_q = mp_transform_if<Qp::template fn, Qf::template fn, L...>; template<class L, class V> using mp_fill = /*see below*/; template<class L, class V> using mp_count = /*see below*/; template<class L, template<class...> class P> using mp_count_if = /*see below*/; template<class L, class Q> using mp_count_if_q = mp_count_if<L, Q::template fn>; template<class L, class V> using mp_contains = mp_to_bool<mp_count<L, V>>; template<class L, size_t N> using mp_repeat_c = /*see below*/; template<class L, class N> using mp_repeat = mp_repeat_c<L, size_t{N::value}>; template<template<class...> class F, class... L> using mp_product = /*see below*/; template<class Q, class... L> using mp_product_q = mp_product<Q::template fn, L...>; template<class L, size_t N> using mp_drop_c = /*see below*/; template<class L, class N> using mp_drop = mp_drop_c<L, size_t{N::value}>; template<class S> using mp_from_sequence = /*see below*/ template<size_t N> using mp_iota_c = mp_from_sequence<make_index_sequence<N>>; template<class N> using mp_iota = mp_from_sequence<make_integer_sequence<remove_const_t<decltype(N::value)>, N::value>>; template<class L, size_t I> using mp_at_c = /*see below*/; template<class L, class I> using mp_at = mp_at_c<L, size_t{I::value}>; template<class L, size_t N> using mp_take_c = /*see below*/; template<class L, class N> using mp_take = mp_take_c<L, size_t{N::value}>; template<class L, size_t I, class... T> using mp_insert_c = mp_append<mp_take_c<L, I>, mp_push_front<mp_drop_c<L, I>, T...>>; template<class L, class I, class... T> using mp_insert = mp_append<mp_take<L, I>, mp_push_front<mp_drop<L, I>, T...>>; template<class L, size_t I, size_t J> using mp_erase_c = mp_append<mp_take_c<L, I>, mp_drop_c<L, J>>; template<class L, class I, class J> using mp_erase = mp_append<mp_take<L, I>, mp_drop<L, J>>; template<class L, class V, class W> using mp_replace = /*see below*/; template<class L, template<class...> class P, class W> using mp_replace_if = /*see below*/; template<class L, class Q, class W> using mp_replace_if_q = mp_replace_if<L, Q::template fn, W>; template<class L, size_t I, class W> using mp_replace_at_c = /*see below*/; template<class L, class I, class W> using mp_replace_at = mp_replace_at_c<L, size_t{I::value}, W>; template<class L, template<class...> class P> using mp_copy_if = /*see below*/; template<class L, class Q> using mp_copy_if_q = mp_copy_if<L, Q::template fn>; template<class L, class V> using mp_remove = /*see below*/; template<class L, template<class...> class P> using mp_remove_if = /*see below*/; template<class L, class Q> using mp_remove_if_q = mp_remove_if<L, Q::template fn>; template<class L, template<class...> class P> using mp_partition = /*see below*/; template<class L, class Q> using mp_partition_q = mp_partition<L, Q::template fn>; template<class L, template<class...> class P> using mp_sort = /*see below*/; template<class L, class Q> using mp_sort_q = mp_sort<L, Q::template fn>; template<class L, size_t I, template<class...> class P> using mp_nth_element_c = /*see below*/; template<class L, class I, template<class...> class P> using mp_nth_element = mp_nth_element_c<L, size_t{I::value}, P>; template<class L, class I, class Q> using mp_nth_element_q = mp_nth_element<L, I, Q::template fn>; template<class L, template<class...> class P> using mp_min_element = /*see below*/; template<class L, class Q> using mp_min_element_q = mp_min_element<L, Q::template fn>; template<class L, template<class...> class P> using mp_max_element = /*see below*/; template<class L, class Q> using mp_max_element_q = mp_max_element<L, Q::template fn>; template<class L, class V> using mp_find = /*see below*/; template<class L, template<class...> class P> using mp_find_if = /*see below*/; template<class L, class Q> using mp_find_if_q = mp_find_if<L, Q::template fn>; template<class L> using mp_reverse = /*see below*/; template<class L, class V, template<class...> class F> using mp_fold = /*see below*/; template<class L, class V, class Q> using mp_fold_q = mp_fold<L, V, Q::template fn>; template<class L, class V, template<class...> class F> using mp_reverse_fold = /*see below*/; template<class L, class V, class Q> using mp_reverse_fold_q = mp_reverse_fold<L, V, Q::template fn>; template<class L> using mp_unique = /*see below*/; template<class L, template<class...> class P> using mp_all_of = mp_bool<mp_count_if<L, P>::value == mp_size<L>::value>; template<class L, class Q> using mp_all_of_q = mp_all_of<L, Q::template fn>; template<class L, template<class...> class P> using mp_none_of = mp_bool<mp_count_if<L, P>::value == 0>; template<class L, class Q> using mp_none_of_q = mp_none_of<L, Q::template fn>; template<class L, template<class...> class P> using mp_any_of = mp_bool<mp_count_if<L, P>::value != 0>; template<class L, class Q> using mp_any_of_q = mp_any_of<L, Q::template fn>; template<class L, class F> constexpr F mp_for_each(F&& f); template<size_t N, class F> constexpr auto mp_with_index(size_t i, F&& f) -> decltype(declval<F>()(declval<mp_size_t<0>>())); template<class N, class F> constexpr auto mp_with_index(size_t i, F&& f) -> decltype(declval<F>()(declval<mp_size_t<0>>())); // set operations template<class S> using mp_is_set = /*see below*/; template<class S, class V> using mp_set_contains = /*see below*/; template<class S, class... T> using mp_set_push_back = /*see below*/; template<class S, class... T> using mp_set_push_front = /*see below*/; // map operations template<class M> using mp_is_map = /*see below*/; template<class M, class K> using mp_map_find = /*see below*/; template<class M, class K> using mp_map_contains = mp_not<is_same<mp_map_find<M, K>, void>>; template<class M, class T> using mp_map_insert = mp_if<mp_map_contains<M, mp_first<T>>, M, mp_push_back<M, T>>; template<class M, class T> using mp_map_replace = /*see below*/; template<class M, class T, template<class...> class F> using mp_map_update = /*see below*/; template<class M, class T, class Q> using mp_map_update_q = mp_map_update<M, T, Q::template fn>; template<class M, class K> using mp_map_erase = /*see below*/; template<class M> using mp_map_keys = mp_transform<mp_first, M>; // helper metafunctions template<class... T> using mp_and = /*see below*/; template<class... T> using mp_all = /*see below*/; template<class... T> using mp_or = /*see below*/; template<class... T> using mp_any = /*see below*/; template<class... T> using mp_same = /*see below*/; template<class... T> using mp_plus = /*see below*/; template<class T1, class T2> using mp_less = /*see below*/; template<class T1, class... T> using mp_min = mp_min_element<mp_list<T1, T...>, mp_less>; template<class T1, class... T> using mp_max = mp_max_element<mp_list<T1, T...>, mp_less>; // bind template<size_t I> struct mp_arg; using _1 = mp_arg<0>; using _2 = mp_arg<1>; using _3 = mp_arg<2>; using _4 = mp_arg<3>; using _5 = mp_arg<4>; using _6 = mp_arg<5>; using _7 = mp_arg<6>; using _8 = mp_arg<7>; using _9 = mp_arg<8>; template<template<class...> class F, class... T> struct mp_bind; template<class Q, class... T> using mp_bind_q = mp_bind<Q::template fn, T...>; template<template<class...> class F, class... T> struct mp_bind_front; template<class Q, class... T> using mp_bind_front_q = mp_bind_front<Q::template fn, T...>; template<template<class...> class F, class... T> struct mp_bind_back; template<class Q, class... T> using mp_bind_back_q = mp_bind_back<Q::template fn, T...>; } // namespace std