#ifndef BOOST_MP11_ALGORITHM_HPP_INCLUDED #define BOOST_MP11_ALGORITHM_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 #include #include namespace boost { // 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; #if !defined( BOOST_NO_CXX11_CONSTEXPR ) constexpr std::size_t cx_plus() { return 0; } template constexpr std::size_t cx_plus(T1 t1, T... t) { return t1 + cx_plus(t...); } template class L, class... T, class V> struct mp_count_impl, V> { using type = mp_size_t::value...)>; }; #else template class L, class... T, class V> struct mp_count_impl, V> { using type = mp_size_t...>::value>; }; #endif } // 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; #if !defined( BOOST_NO_CXX11_CONSTEXPR ) template class L, class... T, template class P> struct mp_count_if_impl, P> { using type = mp_size_t>::value...)>; }; #else 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_size_t::type...>::value>; #else using type = mp_size_t>...>::value>; #endif }; #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_product namespace detail { template class F, class P, class... L> struct mp_product_impl_2; template class F, class P> struct mp_product_impl_2 { using type = mp_list>; }; template class F, class P, template class L1, class... T1, class... L> struct mp_product_impl_2, L...> { using type = mp_append, L...>::type...>; }; template class F, class... L> struct mp_product_impl; template class F, class L1, class... L> struct mp_product_impl { using type = mp_assign, L1, L...>::type>; }; } // namespace detail template class F, class... L> using mp_product = typename detail::mp_product_impl::type; // mp_drop(_c) namespace detail { template struct mp_drop_impl; template class L, class... T, template class L2, class... U> struct mp_drop_impl, L2> { template static mp_identity> f( U*..., mp_identity*... ); using R = decltype( f( (mp_identity*)0 ... ) ); using type = typename R::type; }; } // namespace detail template using mp_drop_c = typename detail::mp_drop_impl, N>>::type; template using mp_drop = typename detail::mp_drop_impl, N>>::type; // mp_take(_c) // mp_at(_c) // mp_find // mp_find_if // mp_find_index // mp_find_index_if // mp_reverse // mp_copy_if // mp_remove_if // mp_fold // mp_reverse_fold // mp_replace? // mp_replace_if? // mp_partition // mp_sort } // namespace boost #endif // #ifndef BOOST_MP11_ALGORITHM_HPP_INCLUDED