From 67ef9ab3fbcb462eb788ae10454e334e9da97af4 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Fri, 24 Jul 2015 01:17:16 +0300 Subject: [PATCH] Add mp_remove, mp_reverse. --- include/boost/mp11/algorithm.hpp | 95 +++++++++++++++++++++++++++++++- test/Jamfile.v2 | 2 + test/mp_remove.cpp | 52 +++++++++++++++++ test/mp_reverse.cpp | 62 +++++++++++++++++++++ 4 files changed, 210 insertions(+), 1 deletion(-) create mode 100644 test/mp_remove.cpp create mode 100644 test/mp_reverse.cpp diff --git a/include/boost/mp11/algorithm.hpp b/include/boost/mp11/algorithm.hpp index b079624..6745d70 100644 --- a/include/boost/mp11/algorithm.hpp +++ b/include/boost/mp11/algorithm.hpp @@ -387,6 +387,44 @@ template class L, class T1, class... T, template cl template class P> using mp_copy_if = typename detail::mp_copy_if_impl::type; +// mp_remove +namespace detail +{ + +template struct mp_remove_impl; + +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1800 ) + +template class L, class... T, class V> struct mp_remove_impl, V> +{ + static_assert( sizeof...(T) == 0, "T... must be empty" ); + using type = L<>; +}; + +#else + +template class L, class V> struct mp_remove_impl, V> +{ + using type = L<>; +}; + +#endif + +template class L, class T1, class... T> struct mp_remove_impl, T1> +{ + using type = typename mp_remove_impl, T1>::type; +}; + +template class L, class T1, class... T, class V> struct mp_remove_impl, V> +{ + using rest = typename mp_remove_impl, V>::type; + using type = mp_push_front; +}; + +} // namespace detail + +template using mp_remove = typename detail::mp_remove_impl::type; + // mp_remove_if namespace detail { @@ -619,10 +657,65 @@ template using mp_find = mp_drop>; template class P> using mp_find_if = mp_drop>; // mp_reverse +namespace detail +{ + +template struct mp_reverse_impl; + +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1800 ) + +template class L, class... T> struct mp_reverse_impl> +{ + static_assert( sizeof...(T) == 0, "T... must be empty" ); + using type = L<>; +}; + +#else + +template class L> struct mp_reverse_impl> +{ + using type = L<>; +}; + +#endif + +template class L, class T1> struct mp_reverse_impl> +{ + using type = L; +}; + +template class L, class T1, class T2> struct mp_reverse_impl> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3> struct mp_reverse_impl> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4> struct mp_reverse_impl> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4, class T5> struct mp_reverse_impl> +{ + using type = L; +}; + +template class L, class T1, class T2, class T3, class T4, class T5, class T6, class... T> struct mp_reverse_impl> +{ + using type = mp_push_back>::type, T6, T5, T4, T3, T2, T1>; +}; + +} // namespace detail + +template using mp_reverse = typename detail::mp_reverse_impl::type; + // mp_fold // mp_reverse_fold // mp_unique -// mp_remove } // namespace boost diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index dfff4fe..30e9cc2 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -41,6 +41,7 @@ run mp_take.cpp : : : $(REQ) ; run mp_replace.cpp : : : $(REQ) ; run mp_replace_if.cpp : : : $(REQ) ; run mp_copy_if.cpp : : : $(REQ) ; +run mp_remove.cpp : : : $(REQ) ; run mp_remove_if.cpp : : : $(REQ) ; run mp_partition.cpp : : : $(REQ) ; run mp_sort.cpp : : : $(REQ) ; @@ -48,6 +49,7 @@ run mp_find_index.cpp : : : $(REQ) ; run mp_find_index_if.cpp : : : $(REQ) ; run mp_find.cpp : : : $(REQ) ; run mp_find_if.cpp : : : $(REQ) ; +run mp_reverse.cpp : : : $(REQ) ; # integral run integral.cpp : : : $(REQ) ; diff --git a/test/mp_remove.cpp b/test/mp_remove.cpp new file mode 100644 index 0000000..8daff77 --- /dev/null +++ b/test/mp_remove.cpp @@ -0,0 +1,52 @@ + +// 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 + +struct X1 {}; +struct X2 {}; +struct X3 {}; + +int main() +{ + using boost::mp_list; + using boost::mp_remove; + + { + using L1 = mp_list<>; + + BOOST_TEST_TRAIT_TRUE((std::is_same, L1>)); + + using L2 = mp_list; + + BOOST_TEST_TRAIT_TRUE((std::is_same, L2>)); + 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 L1 = std::tuple<>; + + BOOST_TEST_TRAIT_TRUE((std::is_same, L1>)); + + using L2 = std::tuple; + + BOOST_TEST_TRAIT_TRUE((std::is_same, L2>)); + 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>)); + } + + return boost::report_errors(); +} diff --git a/test/mp_reverse.cpp b/test/mp_reverse.cpp new file mode 100644 index 0000000..740716c --- /dev/null +++ b/test/mp_reverse.cpp @@ -0,0 +1,62 @@ + +// 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 + +struct X1 {}; +struct X2 {}; +struct X3 {}; +struct X4 {}; +struct X5 {}; +struct X6 {}; +struct X7 {}; +struct X8 {}; +struct X9 {}; + +int main() +{ + using boost::mp_list; + using boost::mp_reverse; + + { + 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>)); + 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>)); + } + + { + 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>)); + 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>)); + } + + { + BOOST_TEST_TRAIT_TRUE((std::is_same>, std::pair>)); + } + + return boost::report_errors(); +}