1
0
forked from boostorg/mp11

Add a variadic mp_transform implementation

This commit is contained in:
Peter Dimov
2017-04-01 17:39:02 +03:00
parent e871f0c30c
commit fcbe835f4b
2 changed files with 50 additions and 2 deletions

View File

@@ -44,6 +44,16 @@ template<class L1, class L2> using mp_assign = typename detail::mp_assign_impl<L
// mp_clear<L> // mp_clear<L>
template<class L> using mp_clear = mp_assign<L, mp_list<>>; template<class L> using mp_clear = mp_assign<L, mp_list<>>;
// mp_fold<L, V, F> forward declaration
namespace detail
{
template<class L, class V, template<class...> class F> struct mp_fold_impl;
} // namespace detail
template<class L, class V, template<class...> class F> using mp_fold = typename detail::mp_fold_impl<L, V, F>::type;
// mp_transform<F, L...> // mp_transform<F, L...>
namespace detail namespace detail
{ {
@@ -71,6 +81,26 @@ template<template<class...> class F, template<class...> class L1, class... T1, t
template<template<class...> class F, class... L> using mp_transform = typename detail::mp_transform_impl<F, L...>::type; template<template<class...> class F, class... L> using mp_transform = typename detail::mp_transform_impl<F, L...>::type;
namespace detail
{
template<template<class...> class F, template<class...> class L1, class... T1, template<class...> class L2, class... T2, template<class...> class L3, class... T3, template<class...> class L4, class... T4, class... L> struct mp_transform_impl<F, L1<T1...>, L2<T2...>, L3<T3...>, L4<T4...>, L...>
{
static_assert( sizeof...(T1) == sizeof...(T2) && sizeof...(T1) == sizeof...(T3) && sizeof...(T1) == sizeof...(T4), "The arguments of mp_transform should be of the same size" );
using A1 = L1<mp_list<T1, T2, T3, T4>...>;
template<class V, class T> using _f = mp_transform<mp_push_back, V, T>;
using A2 = mp_fold<mp_list<L...>, A1, _f>;
template<class T> using _g = mp_apply<F, T>;
using type = mp_transform<_g, A2>;
};
} // namespace detail
// mp_transform_if<P, F, L...> // mp_transform_if<P, F, L...>
namespace detail namespace detail
{ {
@@ -753,8 +783,6 @@ template<template<class...> class L, class T1, class T2, class T3, class T4, cla
} // namespace detail } // namespace detail
template<class L, class V, template<class...> class F> using mp_fold = typename detail::mp_fold_impl<L, V, F>::type;
// mp_reverse_fold<L, V, F> // mp_reverse_fold<L, V, F>
namespace detail namespace detail
{ {

View File

@@ -29,6 +29,15 @@ struct Z2 {};
struct Z3 {}; struct Z3 {};
struct Z4 {}; struct Z4 {};
struct U1 {};
struct U2 {};
struct V1 {};
struct V2 {};
struct W1 {};
struct W2 {};
template<class T> using add_pointer = typename std::add_pointer<T>::type; template<class T> using add_pointer = typename std::add_pointer<T>::type;
template<class T, class U> using is_same = typename std::is_same<T, U>::type; template<class T, class U> using is_same = typename std::is_same<T, U>::type;
@@ -81,5 +90,16 @@ int main()
// //
using L8 = std::pair<Z1, Z2>;
using L9 = std::pair<U1, U2>;
using L10 = std::pair<V1, V2>;
using L11 = std::pair<W1, W2>;
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform<std::tuple, L5, L6, L8, L9>, std::pair<std::tuple<X1, Y1, Z1, U1>, std::tuple<X2, Y2, Z2, U2>>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform<std::tuple, L5, L6, L8, L9, L10>, std::pair<std::tuple<X1, Y1, Z1, U1, V1>, std::tuple<X2, Y2, Z2, U2, V2>>>));
BOOST_TEST_TRAIT_TRUE((std::is_same<mp_transform<std::tuple, L5, L6, L8, L9, L10, L11>, std::pair<std::tuple<X1, Y1, Z1, U1, V1, W1>, std::tuple<X2, Y2, Z2, U2, V2, W2>>>));
//
return boost::report_errors(); return boost::report_errors();
} }