...>`.
[endsect]
-[section `mp_transform_if`]
- template class P, template class F, class L> using mp_transform_if = /*...*/;
+[section `mp_transform_if`]
+ template class P, template class F, class L...> using mp_transform_if = /*...*/;
-`mp_transform_if` replaces the elements `T` of `L` for which `mp_to_bool>` is `mp_true` with `F`, and returns the result.
+`mp_transform_if` replaces the elements `T` of the list `L1` for which `mp_to_bool
>` is `mp_true` with
+`F`, and returns the result, where `Ti` are the corresponding elements of `Li`.
[endsect]
[section `mp_fill`]
@@ -138,6 +139,18 @@ Replaces all `V` elements of `L` with `W` and returns the result.
Replaces all `T` elements of `L` for which `mp_to_bool>` is `mp_true` with `W` and returns the result.
[endsect]
+[section `mp_replace_at_c`]
+ template using mp_replace_at_c = /*...*/;
+
+Replaces the element of `L` at zero-based index `I` with `W` and returns the result.
+[endsect]
+
+[section `mp_replace_at`]
+ template using mp_replace_at = /*...*/;
+
+Same as `mp_replace_at_c`, but with a type argument `I`. `I::value` must be a nonnegative number.
+[endsect]
+
[section `mp_copy_if`]
template class P> using mp_copy_if = /*...*/;
diff --git a/doc/mp11/list.qbk b/doc/mp11/list.qbk
index 2f972ad..19f1677 100644
--- a/doc/mp11/list.qbk
+++ b/doc/mp11/list.qbk
@@ -92,4 +92,31 @@ is an alias for `L`.
is an alias for `mp_list<>`. `mp_append, L2, ..., Ln>` is an alias for `L1`.
[endsect]
+[section `mp_replace_front`]
+ template using mp_replace_front = /*...*/;
+
+`mp_replace_front` replaces the first element of the list `L` with `T`. That is, `mp_replace_front, T>` is
+an alias for `L`.
+[endsect]
+
+[section `mp_replace_first`]
+ template using mp_replace_first = mp_replace_front;
+
+`mp_replace_first` is another name for `mp_replace_front`.
+[endsect]
+
+[section `mp_replace_second`]
+ template using mp_replace_second = /*...*/;
+
+`mp_replace_second` replaces the second element of the list `L` with `T`. That is, `mp_replace_second, T>`
+is an alias for `L`.
+[endsect]
+
+[section `mp_replace_third`]
+ template using mp_replace_third = /*...*/;
+
+`mp_replace_third` replaces the third element of the list `L` with `T`. That is, `mp_replace_third, T>`
+is an alias for `L`.
+[endsect]
+
[endsect]
diff --git a/include/boost/mp11/algorithm.hpp b/include/boost/mp11/algorithm.hpp
index 8930660..4a6cafe 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
@@ -791,6 +834,25 @@ template class P> using mp_none_of = mp_bool< mp_cou
// mp_any_of
template class P> using mp_any_of = mp_bool< mp_count_if::value != 0 >;
+// mp_replace_at_c
+namespace detail
+{
+
+template struct mp_replace_at_impl
+{
+ static_assert( I::value >= 0, "mp_replace_at: I must not be negative" );
+
+ template using _p = std::is_same>;
+ template using _f = W;
+
+ using type = mp_transform_if<_p, _f, L, mp_iota>>;
+};
+
+} // namespace detail
+
+template using mp_replace_at = typename detail::mp_replace_at_impl::type;
+template using mp_replace_at_c = typename detail::mp_replace_at_impl, W>::type;
+
} // namespace mp11
} // namespace boost
diff --git a/include/boost/mp11/list.hpp b/include/boost/mp11/list.hpp
index bb319d6..216d8c4 100644
--- a/include/boost/mp11/list.hpp
+++ b/include/boost/mp11/list.hpp
@@ -170,6 +170,54 @@ template class L1, class... T1, template class L2,
template using mp_append = typename detail::mp_append_impl::type;
+// mp_replace_front
+namespace detail
+{
+
+template struct mp_replace_front_impl;
+
+template class L, class U1, class... U, class T> struct mp_replace_front_impl, T>
+{
+ using type = L;
+};
+
+} // namespace detail
+
+template using mp_replace_front = typename detail::mp_replace_front_impl::type;
+
+// mp_replace_first
+template using mp_replace_first = typename detail::mp_replace_front_impl::type;
+
+// mp_replace_second
+namespace detail
+{
+
+template struct mp_replace_second_impl;
+
+template class L, class U1, class U2, class... U, class T> struct mp_replace_second_impl, T>
+{
+ using type = L;
+};
+
+} // namespace detail
+
+template using mp_replace_second = typename detail::mp_replace_second_impl::type;
+
+// mp_replace_third
+namespace detail
+{
+
+template struct mp_replace_third_impl;
+
+template class L, class U1, class U2, class U3, class... U, class T> struct mp_replace_third_impl, T>
+{
+ using type = L;
+};
+
+} // namespace detail
+
+template using mp_replace_third = typename detail::mp_replace_third_impl::type;
+
} // namespace mp11
} // namespace boost
diff --git a/test/Jamfile.v2 b/test/Jamfile.v2
index 29c916b..8819294 100644
--- a/test/Jamfile.v2
+++ b/test/Jamfile.v2
@@ -25,6 +25,9 @@ run mp_push_front.cpp : : : $(REQ) ;
run mp_push_back.cpp : : : $(REQ) ;
run mp_rename.cpp : : : $(REQ) ;
run mp_append.cpp : : : $(REQ) ;
+run mp_replace_front.cpp : : : $(REQ) ;
+run mp_replace_second.cpp : : : $(REQ) ;
+run mp_replace_third.cpp : : : $(REQ) ;
# algorithm
run mp_assign.cpp : : : $(REQ) ;
@@ -57,6 +60,8 @@ run mp_unique.cpp : : : $(REQ) ;
run mp_all_of.cpp : : : $(REQ) ;
run mp_any_of.cpp : : : $(REQ) ;
run mp_none_of.cpp : : : $(REQ) ;
+run mp_replace_at.cpp : : : $(REQ) ;
+run mp_replace_at_c.cpp : : : $(REQ) ;
# integral
run integral.cpp : : : $(REQ) ;
diff --git a/test/mp_replace_at.cpp b/test/mp_replace_at.cpp
new file mode 100644
index 0000000..faf2289
--- /dev/null
+++ b/test/mp_replace_at.cpp
@@ -0,0 +1,60 @@
+
+// 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
+
+struct X1 {};
+struct X2 {};
+struct X3 {};
+struct X4 {};
+struct X5 {};
+
+int main()
+{
+ using boost::mp11::mp_list;
+ using boost::mp11::mp_replace_at;
+ using boost::mp11::mp_int;
+ using boost::mp11::mp_true;
+ using boost::mp11::mp_false;
+
+ {
+ using L = mp_list;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same, void>, mp_list>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same, void>, mp_list>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same, void>, mp_list>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same, void>, mp_list>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same, void>, mp_list>));
+ }
+
+ {
+ using L = std::tuple;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same, void>, std::tuple>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same, void>, std::tuple>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same, void>, std::tuple>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same, void>, std::tuple>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same, void>, std::tuple>));
+ }
+
+ {
+ using L = std::pair;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same, std::pair>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same, std::pair>));
+ }
+
+ return boost::report_errors();
+}
diff --git a/test/mp_replace_at_c.cpp b/test/mp_replace_at_c.cpp
new file mode 100644
index 0000000..5a5bd54
--- /dev/null
+++ b/test/mp_replace_at_c.cpp
@@ -0,0 +1,56 @@
+
+// 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
+
+struct X1 {};
+struct X2 {};
+struct X3 {};
+struct X4 {};
+struct X5 {};
+
+int main()
+{
+ using boost::mp11::mp_list;
+ using boost::mp11::mp_replace_at_c;
+
+ {
+ using L = mp_list;
+
+ 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>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list>));
+ }
+
+ {
+ using L = std::tuple;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple>));
+ }
+
+ {
+ using L = std::pair;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same, std::pair>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same, std::pair>));
+ }
+
+ return boost::report_errors();
+}
diff --git a/test/mp_replace_front.cpp b/test/mp_replace_front.cpp
new file mode 100644
index 0000000..7d656d1
--- /dev/null
+++ b/test/mp_replace_front.cpp
@@ -0,0 +1,80 @@
+
+// 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
+
+struct X1 {};
+struct X2 {};
+struct X3 {};
+struct X4 {};
+
+int main()
+{
+ using boost::mp11::mp_list;
+ using boost::mp11::mp_replace_front;
+ using boost::mp11::mp_replace_first;
+
+ {
+ using L1 = mp_list;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list>));
+
+ using L2 = mp_list;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list>));
+
+ using L3 = mp_list;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list>));
+
+ using L4 = mp_list;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list>));
+ }
+
+ {
+ using L1 = std::tuple;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple>));
+
+ using L2 = std::tuple;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple>));
+
+ using L3 = std::tuple;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple>));
+
+ using L4 = std::tuple;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple