#ifndef BOOST_MP11_LIST_HPP_INCLUDED #define BOOST_MP11_LIST_HPP_INCLUDED // Copyright 2015 Peter Dimov. // // Distributed under the Boost Software License, Version 1.0. // // See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt #include #include #include #include #include namespace boost { // mp_list template struct mp_list { }; // mp_size namespace detail { template struct mp_size_impl; template class L, class... T> struct mp_size_impl> { using type = mp_size_t; }; } // namespace detail template using mp_size = typename detail::mp_size_impl::type; // mp_empty template using mp_empty = mp_bool< mp_size::value == 0 >; // mp_front namespace detail { template struct mp_front_impl; template class L, class T1, class... T> struct mp_front_impl> { using type = T1; }; } // namespace detail template using mp_front = typename detail::mp_front_impl::type; // mp_pop_front namespace detail { template struct mp_pop_front_impl; template class L, class T1, class... T> struct mp_pop_front_impl> { using type = L; }; } // namespace detail template using mp_pop_front = typename detail::mp_pop_front_impl::type; // mp_first template using mp_first = mp_front; // mp_rest template using mp_rest = mp_pop_front; // mp_second namespace detail { template struct mp_second_impl; template class L, class T1, class T2, class... T> struct mp_second_impl> { using type = T2; }; } // namespace detail template using mp_second = typename detail::mp_second_impl::type; // mp_third namespace detail { template struct mp_third_impl; template class L, class T1, class T2, class T3, class... T> struct mp_third_impl> { using type = T3; }; } // namespace detail template using mp_third = typename detail::mp_third_impl::type; // mp_push_front namespace detail { template struct mp_push_front_impl; template class L, class... U, class... T> struct mp_push_front_impl, T...> { using type = L; }; } // namespace detail template using mp_push_front = typename detail::mp_push_front_impl::type; // mp_push_back namespace detail { template struct mp_push_back_impl; template class L, class... U, class... T> struct mp_push_back_impl, T...> { using type = L; }; } // namespace detail template using mp_push_back = typename detail::mp_push_back_impl::type; // mp_rename namespace detail { template class B> struct mp_rename_impl; template class A, class... T, template class B> struct mp_rename_impl, B> { using type = B; }; } // namespace detail template class B> using mp_rename = typename detail::mp_rename_impl::type; // mp_append namespace detail { template struct mp_append_impl; template<> struct mp_append_impl<> { using type = mp_list<>; }; template class L, class... T> struct mp_append_impl> { using type = L; }; template class L1, class... T1, template class L2, class... T2, class... Lr> struct mp_append_impl, L2, Lr...> { using type = typename mp_append_impl, Lr...>::type; }; } // namespace detail template using mp_append = typename detail::mp_append_impl::type; // mp_assign namespace detail { template struct mp_assign_impl; template class L1, class... T, template class L2, class... U> struct mp_assign_impl, L2> { using type = L1; }; } // namespace detail template using mp_assign = typename detail::mp_assign_impl::type; // mp_clear template using mp_clear = mp_assign>; // mp_transform namespace detail { template class F, class... L> struct mp_transform_impl; template class F, class... L> using mp_transform = typename mp_transform_impl::type; template class F, template class L, class... T> struct mp_transform_impl> { using type = L...>; }; template class F, template class L1, class... T1, template class L2, class... T2> struct mp_transform_impl, L2> { static_assert( sizeof...(T1) == sizeof...(T2), "The arguments of mp_transform should be of the same size" ); using type = L1...>; }; template class F, template class L1, class... T1, template class L2, class... T2, template class L3, class... T3> struct mp_transform_impl, L2, L3> { static_assert( sizeof...(T1) == sizeof...(T2) && sizeof...(T1) == sizeof...(T3), "The arguments of mp_transform should be of the same size" ); using type = L1...>; }; } // namespace detail template class F, class... L> using mp_transform = typename detail::mp_transform_impl::type; // mp_fill namespace detail { template struct mp_fill_impl; template class L, class... T, class V> struct mp_fill_impl, V> { #if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1800 ) template struct _f { using type = V; }; using type = L::type...>; #else template using _f = V; using type = L<_f...>; #endif }; } // namespace detail template using mp_fill = typename detail::mp_fill_impl::type; // mp_count namespace detail { template struct mp_count_impl; template class L, class... T, class V> struct mp_count_impl, V> { using type = mp_plus...>; }; } // namespace detail template using mp_count = typename detail::mp_count_impl::type; // mp_count_if namespace detail { template class P> struct mp_count_if_impl; template class L, class... T, template class P> struct mp_count_if_impl, P> { #if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1800 ) template struct _f { using type = mp_to_bool>; }; using type = mp_plus::type...>; #else using type = mp_plus>...>; #endif }; } // namespace detail template class P> using mp_count_if = typename detail::mp_count_if_impl::type; // mp_contains template using mp_contains = mp_to_bool>; // mp_repeat(_c) namespace detail { template struct mp_repeat_c_impl { using _l1 = typename mp_repeat_c_impl::type; using _l2 = typename mp_repeat_c_impl::type; using type = mp_append<_l1, _l1, _l2>; }; template struct mp_repeat_c_impl { using type = mp_clear; }; template struct mp_repeat_c_impl { using type = L; }; template struct mp_repeat_impl { static_assert( N::value >= 0, "mp_repeat: N must not be negative" ); using type = typename mp_repeat_c_impl::type; }; } // namespace detail template using mp_repeat_c = typename detail::mp_repeat_c_impl::type; template using mp_repeat = typename detail::mp_repeat_impl::type; // mp_drop // mp_take // mp_find // mp_find_if // mp_find_index // mp_find_index_if // mp_reverse // mp_copy_if // mp_remove_if // mp_product? // mp_fold // mp_reverse_fold // mp_replace? // mp_replace_if? // mp_partition // mp_sort } // namespace boost #endif // #ifndef BOOST_MP11_LIST_HPP_INCLUDED