diff --git a/doc/html/mp11.html b/doc/html/mp11.html index 8994454..f419f7b 100644 --- a/doc/html/mp11.html +++ b/doc/html/mp11.html @@ -69,6 +69,10 @@
mp_rename<L, Y>
mp_append<L...>
+
mp_replace_front<L, T>
+
mp_replace_first<L, T>
+
mp_replace_second<L, T>
+
mp_replace_third<L, T>
Utility Components, <boost/mp11/utility.hpp>
@@ -92,7 +96,7 @@
mp_assign<L1, L2>
mp_clear<L>
mp_transform<F, L...>
-
mp_transform_if<P, F, L>
+
mp_transform_if<P, F, L...>
mp_fill<L, V>
mp_count<L, V>
mp_count_if<L, P>
@@ -111,6 +115,8 @@
mp_take<L, N>
mp_replace<L, V, W>
mp_replace_if<L, P, W>
+
mp_replace_at_c<L, I, W>
+
mp_replace_at<L, I, W>
mp_copy_if<L, P>
mp_remove<L, V>
mp_remove_if<L, P>
@@ -705,6 +711,58 @@ is an alias for L1<T1..., T2..., ..., Tn...>.

+
+ +
template<class L, class T> using mp_replace_front = /*...*/;
+
+

+ mp_replace_front<L, T> replaces the first element of the list + L with T. + That is, mp_replace_front<L<U1, U...>, + T> + is an alias for L<T, U...>. +

+
+
+ +
template<class L, class T> using mp_replace_first = mp_replace_front<L, T>;
+
+

+ mp_replace_first is another + name for mp_replace_front. +

+
+
+ +
template<class L, class T> using mp_replace_second = /*...*/;
+
+

+ mp_replace_second<L, T> replaces the second element of the + list L with T. That is, mp_replace_second<L<U1, U2, U...>, + T> + is an alias for L<U1, T, U...>. +

+
+
+ +
template<class L, class T> using mp_replace_third = /*...*/;
+
+

+ mp_replace_third<L, T> replaces the third element of the list + L with T. + That is, mp_replace_third<L<U1, U2, U3, U...>, + T> + is an alias for L<U1, U2, T, U...>. +

+

@@ -892,15 +950,17 @@

-
template<template<class...> class P, template<class...> class F, class L> using mp_transform_if = /*...*/;
+
template<template<class...> class P, template<class...> class F, class L...> using mp_transform_if = /*...*/;
 

- mp_transform_if replaces - the elements T of L for which mp_to_bool<P<T>> is mp_true - with F<T>, - and returns the result. + mp_transform_if<P, F, L1, L2, ..., Ln> + replaces the elements T + of the list L1 for which + mp_to_bool<P<T1, T2, ..., Tn>> is mp_true + with F<T1, T2, ..., Tn>, and returns the result, where Ti are the corresponding elements of + Li.

@@ -1119,6 +1179,30 @@
+
template<class L, std::size_t I, class W> using mp_replace_at_c = /*...*/;
+
+

+ Replaces the element of L + at zero-based index I with + W and returns the result. +

+
+
+ +
template<class L, class I, class W> using mp_replace_at = /*...*/;
+
+

+ Same as mp_replace_at_c, + but with a type argument I. + I::value must be a nonnegative number. +

+
+
+
template<class L, template<class...> class P> using mp_copy_if = /*...*/;
@@ -1604,7 +1688,7 @@
 
- +

Last revised: March 17, 2017 at 03:26:57 GMT

Last revised: March 18, 2017 at 18:33:25 GMT


diff --git a/doc/mp11/algorithm.qbk b/doc/mp11/algorithm.qbk index ad25649..f03b5c4 100644 --- a/doc/mp11/algorithm.qbk +++ b/doc/mp11/algorithm.qbk @@ -26,10 +26,11 @@ `mp_transform, L2, ..., Ln>` applies `F` to each successive tuple of elements and returns `L1...>`. [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>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple>)); + } + + { + using L2 = 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_second.cpp b/test/mp_replace_second.cpp new file mode 100644 index 0000000..d7f1e86 --- /dev/null +++ b/test/mp_replace_second.cpp @@ -0,0 +1,62 @@ + +// 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_second; + + { + using L2 = mp_list; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list>)); + + using L3 = mp_list; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list>)); + + using L4 = 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::tuple; + + BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple>)); + + using L4 = std::tuple; + + BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple>)); + } + + { + using L2 = std::pair; + + BOOST_TEST_TRAIT_TRUE((std::is_same, std::pair>)); + } + + return boost::report_errors(); +} diff --git a/test/mp_replace_third.cpp b/test/mp_replace_third.cpp new file mode 100644 index 0000000..5532977 --- /dev/null +++ b/test/mp_replace_third.cpp @@ -0,0 +1,48 @@ + +// 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_third; + + { + using L3 = mp_list; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list>)); + + using L4 = mp_list; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list>)); + } + + { + using L3 = std::tuple; + + BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple>)); + + using L4 = std::tuple; + + BOOST_TEST_TRAIT_TRUE((std::is_same, std::tuple>)); + } + + return boost::report_errors(); +} 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(); }