diff --git a/include/boost/mp11/algorithm.hpp b/include/boost/mp11/algorithm.hpp index e717368..a25f48f 100644 --- a/include/boost/mp11/algorithm.hpp +++ b/include/boost/mp11/algorithm.hpp @@ -1,7 +1,7 @@ #ifndef BOOST_MP11_ALGORITHM_HPP_INCLUDED #define BOOST_MP11_ALGORITHM_HPP_INCLUDED -// Copyright 2015, 2016 Peter Dimov. +// Copyright 2015-2017 Peter Dimov. // // Distributed under the Boost Software License, Version 1.0. // @@ -69,6 +69,31 @@ 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 +namespace detail +{ + +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> +{ +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1910 ) + + template struct _f { using type = mp_eval_if>, U, F, U>; }; + using type = L::type...>; + +#else + + template using _f = mp_eval_if>, U, F, U>; + using type = L<_f...>; + +#endif +}; + +} // namespace detail + +template class P, template class F, class L> using mp_transform_if = typename detail::mp_transform_if_impl::type; + // mp_fill namespace detail { diff --git a/include/boost/mp11/map.hpp b/include/boost/mp11/map.hpp index 30c4a64..9350b70 100644 --- a/include/boost/mp11/map.hpp +++ b/include/boost/mp11/map.hpp @@ -1,7 +1,7 @@ #ifndef BOOST_MP11_MAP_HPP_INCLUDED #define BOOST_MP11_MAP_HPP_INCLUDED -// Copyright 2015, 2016 Peter Dimov. +// Copyright 2015-2017 Peter Dimov. // // Distributed under the Boost Software License, Version 1.0. // @@ -46,6 +46,26 @@ template class M, class... U, class T> struct mp_map_replace_ template using mp_map_replace = typename detail::mp_map_replace_impl::type; // mp_map_update +namespace detail +{ + +template class F> struct mp_map_update_impl +{ + template using _f = std::is_same, mp_first>; + + // _f2> -> F + // _f2> -> F + template using _f2 = mp_rename>, F>; + + // _f3> -> L> + template using _f3 = mp_assign, _f2>>; + + using type = mp_if< mp_map_contains>, mp_transform_if<_f, _f3, M>, mp_push_back >; +}; + +} // namespace detail + +template class F> using mp_map_update = typename detail::mp_map_update_impl::type; // mp_map_erase namespace detail diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 48b993b..b00e64c 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -30,6 +30,7 @@ run mp_append.cpp : : : $(REQ) ; run mp_assign.cpp : : : $(REQ) ; run mp_clear.cpp : : : $(REQ) ; run mp_transform.cpp : : : $(REQ) ; +run mp_transform_if.cpp : : : $(REQ) ; run mp_fill.cpp : : : $(REQ) ; run mp_count.cpp : : : $(REQ) ; run mp_count_if.cpp : : : $(REQ) ; @@ -95,3 +96,4 @@ run mp_map_contains.cpp : : : $(REQ) ; run mp_map_insert.cpp : : : $(REQ) ; run mp_map_replace.cpp : : : $(REQ) ; run mp_map_erase.cpp : : : $(REQ) ; +run mp_map_update.cpp : : : $(REQ) ; diff --git a/test/mp_map_erase.cpp b/test/mp_map_erase.cpp index c03ffc8..466f4c9 100644 --- a/test/mp_map_erase.cpp +++ b/test/mp_map_erase.cpp @@ -18,7 +18,6 @@ int main() { using boost::mp_map_erase; using boost::mp_list; - using boost::mp_push_back; BOOST_TEST_TRAIT_TRUE((std::is_same, void>, mp_list<>>)); BOOST_TEST_TRAIT_TRUE((std::is_same, int>, std::tuple<>>)); diff --git a/test/mp_map_update.cpp b/test/mp_map_update.cpp new file mode 100644 index 0000000..d957806 --- /dev/null +++ b/test/mp_map_update.cpp @@ -0,0 +1,48 @@ + +// Copyright 2016, 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 + +using boost::mp_int; + +template using inc = mp_int; + +int main() +{ + using boost::mp_map_update; + using boost::mp_list; + + using M1 = mp_list<>; + + using M2 = mp_map_update< M1, std::pair>, inc >; + BOOST_TEST_TRAIT_TRUE((std::is_same>>>)); + + using M3 = mp_map_update< M2, std::pair>, inc >; + BOOST_TEST_TRAIT_TRUE((std::is_same>>>)); + + using M4 = mp_map_update< M3, std::pair>, inc >; + BOOST_TEST_TRAIT_TRUE((std::is_same>, std::pair>>>)); + + using M5 = mp_map_update< M4, std::pair>, inc >; + BOOST_TEST_TRAIT_TRUE((std::is_same>, std::pair>, std::pair>>>)); + + using M6 = mp_map_update< M5, std::pair>, inc >; + BOOST_TEST_TRAIT_TRUE((std::is_same>, std::pair>, std::pair>>>)); + + using M7 = mp_map_update< M6, std::pair>, inc >; + BOOST_TEST_TRAIT_TRUE((std::is_same>, std::pair>, std::pair>>>)); + + return boost::report_errors(); +} diff --git a/test/mp_transform_if.cpp b/test/mp_transform_if.cpp new file mode 100644 index 0000000..99b6bb7 --- /dev/null +++ b/test/mp_transform_if.cpp @@ -0,0 +1,46 @@ + +// 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 {}; + +template using add_pointer = T*; +template using is_not_ref = boost::mp_not>; + +int main() +{ + using boost::mp_list; + using boost::mp_transform_if; + + 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>)); + + // + + return boost::report_errors(); +}