diff --git a/doc/html/mp11.html b/doc/html/mp11.html index f35da32..06276b0 100644 --- a/doc/html/mp11.html +++ b/doc/html/mp11.html @@ -107,6 +107,7 @@
mp_transform<F, L...>
mp_transform_q<Q, L...>
mp_transform_if<P, F, L...>
+
mp_transform_if_q<Qp, Qf, L...>
mp_fill<L, V>
mp_count<L, V>
mp_count_if<L, P>
@@ -861,7 +862,7 @@ template<class F, class... V> auto rvisit( F&& f, V&&... v ) { - using R = mp_unique<mp_product<Qret<F>::template fn, std::remove_reference_t<V>...>>; + using R = mp_unique<mp_product_q<Qret<F>, std::remove_reference_t<V>...>>; return std::visit( [&]( auto&&... x ){ return R( std::forward<F>(f)( std::forward<decltype(x)>(x)... ) ); }, std::forward<V>( v )... ); } @@ -1526,6 +1527,17 @@

+mp_transform_if_q<Qp, Qf, L...> +

+
template<class Qp, class Qf, class... L> using mp_transform_if_q = mp_transform_if<Qp::template fn, Qf::template fn, L...>;
+
+

+ As mp_transform_if, but + takes a quoted metafunction. +

+
+
+

mp_fill<L, V>

template<class L, class V> using mp_fill = /*...*/;
@@ -1555,7 +1567,7 @@
 
template<class L, template<class...> class P> using mp_count_if = /*...*/;
 

- mp_count_f<L, P> returns mp_size_t<N>, where N + mp_count_if<L, P> returns mp_size_t<N>, where N is the number of elements T of L for which mp_to_bool<P<T>> is mp_true. @@ -2482,7 +2494,7 @@ each element of tp by evaluating the expression f(std::get<J>(std::forward<Tp>(tp))) for J in 0..N-1, - where N is std::tuple_size<std::remove_reference_t<Tp>>::value. + where N is std::tuple_size<typename std::remove_reference<Tp>::type>::value.

Returns std::forward<F>(f). @@ -2492,7 +2504,7 @@

- +

Last revised: May 24, 2017 at 02:43:53 GMT

Last revised: May 25, 2017 at 18:31:25 GMT


diff --git a/doc/mp11/algorithm.qbk b/doc/mp11/algorithm.qbk index 8a555db..9f603f9 100644 --- a/doc/mp11/algorithm.qbk +++ b/doc/mp11/algorithm.qbk @@ -39,6 +39,12 @@ As `mp_transform`, but takes a quoted metafunction. `F`, and returns the result, where `Ti` are the corresponding elements of `Li`. [endsect] +[section `mp_transform_if_q`] + template using mp_transform_if_q = mp_transform_if; + +As `mp_transform_if`, but takes a quoted metafunction. +[endsect] + [section `mp_fill`] template using mp_fill = /*...*/; @@ -54,7 +60,7 @@ As `mp_transform`, but takes a quoted metafunction. [section `mp_count_if`] template class P> using mp_count_if = /*...*/; -`mp_count_f` returns `mp_size_t`, where `N` is the number of elements `T` of `L` for which `mp_to_bool>` is `mp_true`. +`mp_count_if` returns `mp_size_t`, where `N` is the number of elements `T` of `L` for which `mp_to_bool>` is `mp_true`. [endsect] [section `mp_contains`] diff --git a/doc/mp11/examples.qbk b/doc/mp11/examples.qbk index fe315a1..a75b9f1 100644 --- a/doc/mp11/examples.qbk +++ b/doc/mp11/examples.qbk @@ -403,7 +403,7 @@ and we're done: template auto rvisit( F&& f, V&&... v ) { - using R = mp_unique::template fn, std::remove_reference_t...>>; + using R = mp_unique, std::remove_reference_t...>>; return std::visit( [&]( auto&&... x ){ return R( std::forward(f)( std::forward(x)... ) ); }, std::forward( v )... ); } diff --git a/doc/mp11/tuple_for_each.qbk b/doc/mp11/tuple_for_each.qbk index 4eb6b9e..7b1f53e 100644 --- a/doc/mp11/tuple_for_each.qbk +++ b/doc/mp11/tuple_for_each.qbk @@ -12,7 +12,7 @@ template constexpr F tuple_for_each(Tp&& tp, F&& f); `tuple_for_each(tp, f)` applies the function object `f` to each element of `tp` by evaluating the -expression `f(std::get(std::forward(tp)))` for `J` in 0..`N-1`, where `N` is `std::tuple_size>::value`. +expression `f(std::get(std::forward(tp)))` for `J` in 0..`N-1`, where `N` is `std::tuple_size::type>::value`. Returns `std::forward(f)`. [endsect] diff --git a/include/boost/mp11/algorithm.hpp b/include/boost/mp11/algorithm.hpp index e31e3b7..0f68974 100644 --- a/include/boost/mp11/algorithm.hpp +++ b/include/boost/mp11/algorithm.hpp @@ -66,17 +66,47 @@ template class F, class... L> struct mp_transform_impl template class F, template class L, class... T> struct mp_transform_impl> { +#if BOOST_WORKAROUND( BOOST_MSVC, <= 1910 ) + + template struct f { using type = F; }; + + using type = L::type...>; + +#else + using type = L...>; + +#endif }; template class F, template class L1, class... T1, template class L2, class... T2> struct mp_transform_impl, L2> { +#if BOOST_WORKAROUND( BOOST_MSVC, <= 1910 ) + + template struct f { using type = F; }; + + using type = L1::type...>; + +#else + using type = L1...>; + +#endif }; template class F, template class L1, class... T1, template class L2, class... T2, template class L3, class... T3> struct mp_transform_impl, L2, L3> { +#if BOOST_WORKAROUND( BOOST_MSVC, <= 1910 ) + + template struct f { using type = F; }; + + using type = L1::type...>; + +#else + using type = L1...>; + +#endif }; #if BOOST_WORKAROUND( BOOST_MSVC, == 1900 ) || BOOST_WORKAROUND( BOOST_GCC, < 40800 ) @@ -125,14 +155,18 @@ namespace detail template class P, template class F, class... L> struct mp_transform_if_impl { // the stupid quote-unquote dance avoids "pack expansion used as argument for non-pack parameter of alias template" -#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1910 ) - template struct _f_ { using type = mp_eval_if, U...>>, mp_first>, mp_quote::template fn, U...>; }; + using Qp = mp_quote

; + using Qf = mp_quote; + +#if BOOST_WORKAROUND( BOOST_MSVC, <= 1910 ) + + template struct _f_ { using type = mp_eval_if_q>, mp_first>, Qf, U...>; }; template using _f = typename _f_::type; #else - template using _f = mp_eval_if, U...>>, mp_first>, mp_quote::template fn, U...>; + template using _f = mp_eval_if_q>, mp_first>, Qf, U...>; #endif @@ -142,6 +176,7 @@ template class P, template class F, class... L> str } // 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; // mp_fill namespace detail diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 277bc4f..2d6df0a 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -35,8 +35,10 @@ run mp_apply_q.cpp : : : $(REQ) ; run mp_assign.cpp : : : $(REQ) ; run mp_clear.cpp : : : $(REQ) ; run mp_transform.cpp : : : $(REQ) ; +run mp_transform_q.cpp : : : $(REQ) ; run mp_transform_sf.cpp : : : $(REQ) ; run mp_transform_if.cpp : : : $(REQ) ; +run mp_transform_if_q.cpp : : : $(REQ) ; run mp_fill.cpp : : : $(REQ) ; run mp_count.cpp : : : $(REQ) ; run mp_count_if.cpp : : : $(REQ) ; diff --git a/test/mp_transform_if_q.cpp b/test/mp_transform_if_q.cpp new file mode 100644 index 0000000..b2087be --- /dev/null +++ b/test/mp_transform_if_q.cpp @@ -0,0 +1,87 @@ + +// Copyright 2015, 2017 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 +#include + +struct X1 {}; +struct X2 {}; +struct X3 {}; +struct X4 {}; + +using boost::mp11::mp_not; +using boost::mp11::mp_quote; + +template using add_pointer = T*; +using Q_add_pointer = mp_quote; + +template using is_not_ref = mp_not>; +using Q_is_not_ref = mp_quote; + +template using second = T2; +using Q_second = mp_quote; + +template using third = T3; +using Q_third = mp_quote; + +template using fourth = T4; +using Q_fourth = mp_quote; + +template using fifth = T5; +using Q_fifth = mp_quote; + +int main() +{ + using boost::mp11::mp_list; + using boost::mp11::mp_transform_if_q; + 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; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list>)); + + using L2 = std::tuple; + + BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple>)); + + using L3 = std::pair; + + BOOST_TEST_TRAIT_TRUE((std::is_same, std::pair>)); + + // + + 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&>>)); + + 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&>>)); + + 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(); +} diff --git a/test/mp_transform_q.cpp b/test/mp_transform_q.cpp new file mode 100644 index 0000000..6c73cb1 --- /dev/null +++ b/test/mp_transform_q.cpp @@ -0,0 +1,114 @@ + +// 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 + +struct X1 {}; +struct X2 {}; +struct X3 {}; +struct X4 {}; + +struct Y1 {}; +struct Y2 {}; +struct Y3 {}; +struct Y4 {}; + +struct Z1 {}; +struct Z2 {}; +struct Z3 {}; +struct Z4 {}; + +struct U1 {}; +struct U2 {}; + +struct V1 {}; +struct V2 {}; + +struct W1 {}; +struct W2 {}; + +using boost::mp11::mp_quote; +using boost::mp11::mp_list; + +template using add_pointer = typename std::add_pointer::type; +using Q_add_pointer = mp_quote; + +template using is_same = typename std::is_same::type; +using Q_is_same = mp_quote; + +using Q_mp_list = mp_quote; +using Q_std_tuple = mp_quote; +using Q_std_pair = mp_quote; + +int main() +{ + using boost::mp11::mp_transform_q; + + using L1 = mp_list; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list, mp_list, mp_list, mp_list>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list, std::tuple, std::tuple, std::tuple>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list>)); + + using L2 = std::tuple; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list, mp_list, mp_list, mp_list>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list, std::tuple, std::tuple, std::tuple>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list, std::pair, std::pair, std::pair>>)); + + using L3 = mp_list; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list, mp_list, mp_list, mp_list>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list, std::tuple, std::tuple, std::tuple>>)); + + // + + using L4 = std::tuple; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list>)); + + // + + using L5 = std::pair; + using L6 = std::pair; + using L7 = std::pair; + + BOOST_TEST_TRAIT_TRUE((std::is_same, std::pair, mp_list>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, std::pair, mp_list>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, std::pair, mp_list>>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same, std::pair>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same, std::pair>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, std::pair>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, std::pair>)); + + // + + using L8 = std::pair; + using L9 = std::pair; + using L10 = std::pair; + using L11 = std::pair; + + BOOST_TEST_TRAIT_TRUE((std::is_same, std::pair, std::tuple>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, std::pair, std::tuple>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, std::pair, std::tuple>>)); + + // + + return boost::report_errors(); +}