From 8e053269a8db29398c27aacacd3daf3e46e6c54d Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 18 Mar 2017 19:48:07 +0200 Subject: [PATCH] Make mp_transform_if variadic. --- include/boost/mp11/algorithm.hpp | 49 ++++++++++++++++++++++++++++++-- test/mp_transform_if.cpp | 18 +++++++++++- 2 files changed, 63 insertions(+), 4 deletions(-) diff --git a/include/boost/mp11/algorithm.hpp b/include/boost/mp11/algorithm.hpp index 8930660..144f1f9 100644 --- a/include/boost/mp11/algorithm.hpp +++ b/include/boost/mp11/algorithm.hpp @@ -71,11 +71,20 @@ template class F, template class L1, class... T1, t template class F, class... L> using mp_transform = typename detail::mp_transform_impl::type; -// mp_transform_if +// mp_transform_if namespace detail { -template class P, template class F, class L> struct mp_transform_if_impl; +/* +template class P, template class F, class... L> struct mp_transform_if_impl +{ + // error: pack expansion used as argument for non-pack parameter of alias template + template using _f = mp_eval_if>, mp_first>, F, U...>; + using type = mp_transform<_f, L...>; +}; +*/ + +template class P, template class F, class... L> struct mp_transform_if_impl; template class P, template class F, template class L, class... T> struct mp_transform_if_impl> { @@ -92,9 +101,43 @@ template class P, template class F, template class P, template class F, template class L1, class... T1, template class L2, class... T2> struct mp_transform_if_impl, L2> +{ + static_assert( sizeof...(T1) == sizeof...(T2), "The arguments of mp_transform_if should be of the same size" ); + +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1910 ) + + template struct _f { using type = mp_eval_if>, U1, F, U1, U2>; }; + using type = L1::type...>; + +#else + + template using _f = mp_eval_if>, U1, F, U1, U2>; + using type = L1<_f...>; + +#endif +}; + +template class P, template class F, template class L1, class... T1, template class L2, class... T2, template class L3, class... T3> struct mp_transform_if_impl, L2, L3> +{ + static_assert( sizeof...(T1) == sizeof...(T2) && sizeof...(T1) == sizeof...(T3), "The arguments of mp_transform_if should be of the same size" ); + +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1910 ) + + template struct _f { using type = mp_eval_if>, U1, F, U1, U2, U3>; }; + using type = L1::type...>; + +#else + + template using _f = mp_eval_if>, U1, F, U1, U2, U3>; + using type = L1<_f...>; + +#endif +}; + } // namespace detail -template class P, template class F, class L> using mp_transform_if = typename detail::mp_transform_if_impl::type; +template class P, template class F, class... L> using mp_transform_if = typename detail::mp_transform_if_impl::type; // mp_fill namespace detail diff --git a/test/mp_transform_if.cpp b/test/mp_transform_if.cpp index 0151ac5..89292dd 100644 --- a/test/mp_transform_if.cpp +++ b/test/mp_transform_if.cpp @@ -23,12 +23,18 @@ struct X4 {}; using boost::mp11::mp_not; template using add_pointer = T*; -template using is_not_ref = mp_not>; +template using is_not_ref = mp_not>; +template using second = T2; +template using third = T3; int main() { using boost::mp11::mp_list; using boost::mp11::mp_transform_if; + using boost::mp11::mp_size_t; + using boost::mp11::mp_size; + using boost::mp11::mp_fill; + using boost::mp11::mp_iota; using L1 = mp_list; @@ -44,5 +50,15 @@ int main() // + BOOST_TEST_TRAIT_TRUE((std::is_same>, mp_list>)); + BOOST_TEST_TRAIT_TRUE((std::is_same>, std::tuple>)); + BOOST_TEST_TRAIT_TRUE((std::is_same>, std::pair>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same>>, mp_list, X2&, mp_size_t<2>, X4 const&>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same>>, std::tuple, X2&, mp_size_t<2>, X4 const&>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same>>, std::pair, X2&>>)); + + // + return boost::report_errors(); }