`, 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();
+}