diff --git a/include/boost/mp11/algorithm.hpp b/include/boost/mp11/algorithm.hpp index 07a8ffd..a1264f3 100644 --- a/include/boost/mp11/algorithm.hpp +++ b/include/boost/mp11/algorithm.hpp @@ -153,13 +153,13 @@ template using mp_transform_q = mp_transform using mp_transform_push_back = mp_transform; + template class F, template class L1, class... T1, template class L2, class... T2, template class L3, class... T3, template class L4, class... T4, class... L> struct mp_transform_impl, L2, L3, L4, L...> { using A1 = L1...>; - template using _f = mp_transform; - - using A2 = mp_fold, A1, _f>; + using A2 = mp_fold, A1, mp_transform_push_back>; template using _g = mp_apply; @@ -172,7 +172,7 @@ template class F, template class L1, class... T1, t namespace detail { -template class P, template class F, class... L> struct mp_transform_if_impl +template class P, template class F> struct mp_transform_if_impl { // the stupid quote-unquote dance avoids "pack expansion used as argument for non-pack parameter of alias template" @@ -181,34 +181,35 @@ template class P, template class F, class... L> str #if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) - template struct _f_ { using type = mp_eval_if_q>, mp_first>, Qf, U...>; }; - template using _f = typename _f_::type; + template struct _f { using type = mp_eval_if_q>, mp_first>, Qf, U...>; }; + template using fn = typename _f::type; #else - template using _f = mp_eval_if_q>, mp_first>, Qf, U...>; + template using fn = mp_eval_if_q>, mp_first>, Qf, U...>; #endif - - using type = mp_transform<_f, L...>; }; } // namespace detail -template class P, template class F, class... L> using mp_transform_if = typename detail::mp_transform_if_impl::type; -template using mp_transform_if_q = typename detail::mp_transform_if_impl::type; +template class P, template class F, class... L> using mp_transform_if = mp_transform_q, L...>; +template using mp_transform_if_q = mp_transform_q, L...>; // mp_filter namespace detail { -template class P, class L1, class... L> struct mp_filter_impl +template class P> struct mp_filter_impl_f { using Qp = mp_quote

; - template using _f = mp_if< mp_invoke_q, mp_list, mp_list<> >; + template using fn = mp_if, mp_list, mp_list<> >; +}; - using _t1 = mp_transform<_f, L1, L...>; +template class P, class L1, class... L> struct mp_filter_impl +{ + using _t1 = mp_transform_q, L1, L...>; using _t2 = mp_apply; using type = mp_assign; @@ -228,6 +229,8 @@ template struct mp_fill_impl // An error "no type named 'type'" here means that the L argument of mp_fill is not a list }; +template using mp_fill_first_item = T; + template class L, class... T, class V> struct mp_fill_impl, V> { #if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, <= 1900 ) @@ -237,8 +240,7 @@ template class L, class... T, class V> struct mp_fill_impl using _f = V; - using type = L<_f...>; + using type = L...>; #endif }; @@ -329,11 +331,14 @@ namespace detail template struct mp_drop_impl; -template class L, class... T, template class L2, class... U> struct mp_drop_impl, L2, mp_true> +template class L, class... U> struct mp_drop_impl_f { template static mp_identity> f( U*..., mp_identity*... ); +}; - using R = decltype( f( static_cast*>(0) ... ) ); +template class L, class... T, template class L2, class... U> struct mp_drop_impl, L2, mp_true> +{ + using R = decltype( mp_drop_impl_f::f( static_cast*>(0) ... ) ); using type = typename R::type; }; @@ -524,8 +529,7 @@ template class L, class... T, class V, class W> struct mp_rep template struct _f { using type = mp_if, W, A>; }; using type = L::type...>; #else - template using _f = mp_if, W, A>; - using type = L<_f...>; + using type = L, W, T>...>; #endif }; @@ -545,8 +549,7 @@ template class L, class... T, template class P, cla template struct _f { using type = mp_if, W, U>; }; using type = L::type...>; #else - template using _f = mp_if, W, U>; - using type = L<_f...>; + using type = L, W, T>...>; #endif }; @@ -570,8 +573,7 @@ template class L, class... T, class V> struct mp_remove_impl< template struct _f { using type = mp_if, mp_list<>, mp_list>; }; using type = mp_append, typename _f::type...>; #else - template using _f = mp_if, mp_list<>, mp_list>; - using type = mp_append, _f...>; + using type = mp_append, mp_if, mp_list<>, mp_list>...>; #endif }; @@ -639,11 +641,14 @@ template class L, class T1, template class P> struc using type = L; }; -template class L, class T1, class... T, template class P> struct mp_sort_impl, P> +template class P> struct mp_sort_impl_f { - template using F = P; + template using fn = P; +}; - using part = mp_partition, F>; +template class L, class T1, class... T, template class P> struct mp_sort_impl, P> +{ + using part = mp_partition_q, mp_sort_impl_f>; using S1 = typename mp_sort_impl, P>::type; using S2 = typename mp_sort_impl, P>::type; @@ -672,9 +677,7 @@ template class L, class T1, class... T, std::size_t I, templa { static_assert( I < 1 + sizeof...(T), "mp_nth_element index out of range" ); - template using F = P; - - using part = mp_partition, F>; + using part = mp_partition_q, mp_sort_impl_f>; using L1 = mp_first; static std::size_t const N1 = mp_size::value; @@ -1030,14 +1033,36 @@ template using mp_any_of_q = mp_any_of; namespace detail { +#if ! BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 ) + +template struct mp_replace_at_impl_p +{ + template using fn = std::is_same; +}; + +template struct mp_replace_at_impl_f +{ + template using fn = W; +}; + +#endif + template struct mp_replace_at_impl { static_assert( I::value >= 0, "mp_replace_at: I must not be negative" ); +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 ) + template using _p = std::is_same>; template using _f = W; using type = mp_transform_if<_p, _f, L, mp_iota > >; + +#else + + using type = mp_transform_if_q>, mp_replace_at_impl_f, L, mp_iota > >; + +#endif }; } // namespace detail @@ -1182,13 +1207,16 @@ template class L> struct mp_power_set_impl< L<> > #endif +template struct mp_power_set_impl_f +{ + template using fn = mp_push_front; +}; + template class L, class T1, class... T> struct mp_power_set_impl< L > { using S1 = mp_power_set< L >; - template using _f = mp_push_front; - - using S2 = mp_transform<_f, S1>; + using S2 = mp_transform_q, S1>; using type = mp_append< S1, S2 >; }; @@ -1260,15 +1288,18 @@ template class F> using mp_pairwise_fold = mp_pairwi namespace detail { +template struct mp_sliding_fold_impl_f +{ + template using fn = mp_slice_c; +}; + template struct mp_sliding_fold_impl; template struct mp_sliding_fold_impl { static const std::size_t M = mp_size::value - N::value + 1; - template using F = mp_slice_c; - - using J = mp_transform>; + using J = mp_transform_q, mp_iota>; using type = mp_apply>; }; diff --git a/include/boost/mp11/detail/mp_copy_if.hpp b/include/boost/mp11/detail/mp_copy_if.hpp index 4edcde0..99a6ab5 100644 --- a/include/boost/mp11/detail/mp_copy_if.hpp +++ b/include/boost/mp11/detail/mp_copy_if.hpp @@ -32,8 +32,7 @@ template class L, class... T, template class P> str template struct _f { using type = mp_if, mp_list, mp_list<>>; }; using type = mp_append, typename _f::type...>; #else - template using _f = mp_if, mp_list, mp_list<>>; - using type = mp_append, _f...>; + using type = mp_append, mp_if, mp_list, mp_list<>>...>; #endif }; diff --git a/include/boost/mp11/detail/mp_map_find.hpp b/include/boost/mp11/detail/mp_map_find.hpp index 035538a..f10157c 100644 --- a/include/boost/mp11/detail/mp_map_find.hpp +++ b/include/boost/mp11/detail/mp_map_find.hpp @@ -11,7 +11,8 @@ #include #include -#if BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, >= 140000 ) +#if (BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, >= 140000 ) && BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 140400 )) \ + || (BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, >= 150000 ) && BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 150200 )) #include #include @@ -34,20 +35,24 @@ namespace boost namespace mp11 { -#if BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, >= 140000 ) +#if (BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, >= 140000 ) && BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 140400 )) \ + || (BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, >= 150000 ) && BOOST_MP11_WORKAROUND( BOOST_MP11_GCC, < 150200 )) // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120161 namespace detail { +template struct mp_map_find_impl_k +{ + using type = mp_if, K>, mp_list, mp_list<>>; +}; + template struct mp_map_find_impl; template class M, class... T, class K> struct mp_map_find_impl, K> { - template using _f = mp_if, K>, mp_list, mp_list<>>; - - using _l = mp_append<_f..., mp_list>; + using _l = mp_append::type..., mp_list>; using type = mp_front<_l>; }; @@ -99,14 +104,17 @@ template using mpmf_unwrap = typename mpmf_unwrap_impl::type; template struct mp_map_find_impl; -template class M, class... T, class K> struct mp_map_find_impl, K> +template struct mp_map_find_impl_f { - using U = mp_inherit...>; - template class L, class... U> static mp_identity> f( mp_identity>* ); static mp_identity f( ... ); +}; + +template class M, class... T, class K> struct mp_map_find_impl, K> +{ + using U = mp_inherit...>; - using type = mpmf_unwrap< decltype( f( static_cast(0) ) ) >; + using type = mpmf_unwrap< decltype( mp_map_find_impl_f::f( static_cast(0) ) ) >; }; } // namespace detail diff --git a/include/boost/mp11/detail/mp_remove_if.hpp b/include/boost/mp11/detail/mp_remove_if.hpp index 9687b4a..cafbf34 100644 --- a/include/boost/mp11/detail/mp_remove_if.hpp +++ b/include/boost/mp11/detail/mp_remove_if.hpp @@ -32,8 +32,7 @@ template class L, class... T, template class P> str template struct _f { using type = mp_if, mp_list<>, mp_list>; }; using type = mp_append, typename _f::type...>; #else - template using _f = mp_if, mp_list<>, mp_list>; - using type = mp_append, _f...>; + using type = mp_append, mp_if, mp_list<>, mp_list>...>; #endif }; diff --git a/include/boost/mp11/integer_sequence.hpp b/include/boost/mp11/integer_sequence.hpp index 013991f..279550b 100644 --- a/include/boost/mp11/integer_sequence.hpp +++ b/include/boost/mp11/integer_sequence.hpp @@ -19,6 +19,8 @@ #if defined(__has_builtin) # if __has_builtin(__make_integer_seq) # define BOOST_MP11_HAS_MAKE_INTEGER_SEQ +# elif __has_builtin(__integer_pack) +# define BOOST_MP11_HAS_INTEGER_PACK # endif #endif @@ -36,69 +38,51 @@ template struct integer_sequence template using make_integer_sequence = __make_integer_seq; +#elif defined(BOOST_MP11_HAS_INTEGER_PACK) + +template using make_integer_sequence = integer_sequence; + #else // detail::make_integer_sequence_impl namespace detail { +template +struct iseq_expand; -// iseq_if_c -template struct iseq_if_c_impl; - -template struct iseq_if_c_impl +template +struct iseq_expand> { - using type = T; + using type = integer_sequence; }; -template struct iseq_if_c_impl +template +struct iseq_expand> { - using type = E; + using type = integer_sequence; }; -template using iseq_if_c = typename iseq_if_c_impl::type; - -// iseq_identity -template struct iseq_identity +template struct make_integer_sequence_impl { - using type = T; -}; - -template struct append_integer_sequence; + static_assert( N >= 0, "make_integer_sequence: N must not be negative" ); -template struct append_integer_sequence, integer_sequence> -{ - using type = integer_sequence< T, I..., ( J + sizeof...(I) )... >; + using type = typename iseq_expand::type>::type; }; -template struct make_integer_sequence_impl; - -template struct make_integer_sequence_impl_ +template struct make_integer_sequence_impl { -private: - - static_assert( N >= 0, "make_integer_sequence: N must not be negative" ); - - static T const M = N / 2; - static T const R = N % 2; - - using S1 = typename make_integer_sequence_impl::type; - using S2 = typename append_integer_sequence::type; - using S3 = typename make_integer_sequence_impl::type; - using S4 = typename append_integer_sequence::type; - -public: - - using type = S4; + using type = integer_sequence; }; -template struct make_integer_sequence_impl: iseq_if_c>, iseq_if_c>, make_integer_sequence_impl_ > > +template struct make_integer_sequence_impl { + using type = integer_sequence; }; } // namespace detail // make_integer_sequence -template using make_integer_sequence = typename detail::make_integer_sequence_impl::type; +template using make_integer_sequence = typename detail::make_integer_sequence_impl::type; #endif // defined(BOOST_MP11_HAS_MAKE_INTEGER_SEQ) diff --git a/include/boost/mp11/map.hpp b/include/boost/mp11/map.hpp index b9581ac..0836507 100644 --- a/include/boost/mp11/map.hpp +++ b/include/boost/mp11/map.hpp @@ -38,11 +38,17 @@ template class M, class... U, class T> struct mp_map_replace_ { using K = mp_first; - // mp_replace_if is inlined here using a struct _f because of msvc-14.0 +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1920 ) template struct _f { using type = mp_if< std::is_same, K>, T, V >; }; using type = mp_if< mp_map_contains, K>, M::type...>, M >; + +#else + + using type = mp_if< mp_map_contains, K>, M, K>, T, U >...>, M >; + +#endif }; } // namespace detail @@ -53,14 +59,37 @@ template using mp_map_replace = typename detail::mp_map_replac namespace detail { +#if ! BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 ) + +template struct mp_map_update_impl_f +{ + template using fn = std::is_same, mp_first>; +}; + +template class F> struct mp_map_update_impl_f3 +{ + // fn> -> L> + template using fn = mp_assign, mp_rename > >; +}; + +#endif + template class F> struct mp_map_update_impl { +#if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, < 1900 ) + template using _f = std::is_same, mp_first>; // _f3> -> L> template using _f3 = mp_assign, mp_rename > >; using type = mp_if< mp_map_contains>, mp_transform_if<_f, _f3, M>, mp_push_back >; + +#else + + using type = mp_if< mp_map_contains>, mp_transform_if_q, mp_map_update_impl_f3, M>, mp_push_back >; + +#endif }; } // namespace detail @@ -72,15 +101,14 @@ template using mp_map_update_q = mp_map_update struct mp_map_erase_impl +template struct mp_map_erase_impl { - template using _f = std::is_same, K>; - using type = mp_remove_if; + template using fn = std::is_same, K>; }; } // namespace detail -template using mp_map_erase = typename detail::mp_map_erase_impl::type; +template using mp_map_erase = mp_remove_if_q>; // mp_map_keys template using mp_map_keys = mp_transform;