From 5de3bf8810edbc841e60d4ff5054fdc8e7f8e160 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Fri, 24 Jul 2015 02:11:40 +0300 Subject: [PATCH] Add mp_fold, mp_reverse_fold. --- include/boost/mp11/algorithm.hpp | 63 ++++++++++++++++++++++++++++++++ test/Jamfile.v2 | 2 + test/mp_fold.cpp | 57 +++++++++++++++++++++++++++++ test/mp_reverse_fold.cpp | 56 ++++++++++++++++++++++++++++ 4 files changed, 178 insertions(+) create mode 100644 test/mp_fold.cpp create mode 100644 test/mp_reverse_fold.cpp diff --git a/include/boost/mp11/algorithm.hpp b/include/boost/mp11/algorithm.hpp index 6745d70..6cdd387 100644 --- a/include/boost/mp11/algorithm.hpp +++ b/include/boost/mp11/algorithm.hpp @@ -714,7 +714,70 @@ template class L, class T1, class T2, class T3, class T4, cla template using mp_reverse = typename detail::mp_reverse_impl::type; // mp_fold +namespace detail +{ + +template class F> struct mp_fold_impl; + +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1800 ) + +template class L, class... T, class V, template class F> struct mp_fold_impl, V, F> +{ + static_assert( sizeof...(T) == 0, "T... must be empty" ); + using type = V; +}; + +#else + +template class L, class V, template class F> struct mp_fold_impl, V, F> +{ + using type = V; +}; + +#endif + +template class L, class T1, class... T, class V, template class F> struct mp_fold_impl, V, F> +{ + using type = typename mp_fold_impl, F, F>::type; +}; + +} // namespace detail + +template class F> using mp_fold = typename detail::mp_fold_impl::type; + // mp_reverse_fold +namespace detail +{ + +template class F> struct mp_reverse_fold_impl; + +#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1800 ) + +template class L, class... T, class V, template class F> struct mp_reverse_fold_impl, V, F> +{ + static_assert( sizeof...(T) == 0, "T... must be empty" ); + using type = V; +}; + +#else + +template class L, class V, template class F> struct mp_reverse_fold_impl, V, F> +{ + using type = V; +}; + +#endif + +template class L, class T1, class... T, class V, template class F> struct mp_reverse_fold_impl, V, F> +{ + using rest = typename mp_reverse_fold_impl, V, F>::type; + using type = F; +}; + +} // namespace detail + +template class F> using mp_reverse_fold = typename detail::mp_reverse_fold_impl::type; + // mp_unique } // namespace boost diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 30e9cc2..4237816 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -50,6 +50,8 @@ run mp_find_index_if.cpp : : : $(REQ) ; run mp_find.cpp : : : $(REQ) ; run mp_find_if.cpp : : : $(REQ) ; run mp_reverse.cpp : : : $(REQ) ; +run mp_fold.cpp : : : $(REQ) ; +run mp_reverse_fold.cpp : : : $(REQ) ; # integral run integral.cpp : : : $(REQ) ; diff --git a/test/mp_fold.cpp b/test/mp_fold.cpp new file mode 100644 index 0000000..eb5070a --- /dev/null +++ b/test/mp_fold.cpp @@ -0,0 +1,57 @@ + +// 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 {}; + +template struct F {}; + +int main() +{ + using boost::mp_list; + using boost::mp_fold; + + { + BOOST_TEST_TRAIT_TRUE((std::is_same, void, F>, void>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, void, F>, F>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, void, F>, F, X2>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, void, F>, F, X2>, X3>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, void, F>, F, X2>, X3>, X4>>)); + } + + { + BOOST_TEST_TRAIT_TRUE((std::is_same, void, F>, void>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, void, F>, F>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, void, F>, F, X2>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, void, F>, F, X2>, X3>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, void, F>, F, X2>, X3>, X4>>)); + } + + using boost::mp_push_back; + + { + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list<>, mp_push_back>, mp_list>)); + } + + using boost::mp_push_front; + + { + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list<>, mp_push_front>, mp_list>)); + } + + return boost::report_errors(); +} diff --git a/test/mp_reverse_fold.cpp b/test/mp_reverse_fold.cpp new file mode 100644 index 0000000..d646a11 --- /dev/null +++ b/test/mp_reverse_fold.cpp @@ -0,0 +1,56 @@ + +// 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 {}; + +template struct F {}; + +template using rev_push_back = boost::mp_push_back; +template using rev_push_front = boost::mp_push_front; + +int main() +{ + using boost::mp_list; + using boost::mp_reverse_fold; + + { + BOOST_TEST_TRAIT_TRUE((std::is_same, void, F>, void>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, void, F>, F>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, void, F>, F>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, void, F>, F>>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, void, F>, F>>>>)); + } + + { + BOOST_TEST_TRAIT_TRUE((std::is_same, void, F>, void>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, void, F>, F>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, void, F>, F>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, void, F>, F>>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, void, F>, F>>>>)); + } + + { + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list<>, rev_push_back>, mp_list>)); + } + + { + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_list<>, rev_push_front>, mp_list>)); + } + + return boost::report_errors(); +}