From 247ffe8afe9c7fb119cb095e3d57a84c8b3d58d4 Mon Sep 17 00:00:00 2001 From: Braden Ganetsky Date: Sun, 30 Jul 2023 12:12:10 -0500 Subject: [PATCH 1/3] Add mp_sliding_fold --- include/boost/mp11/algorithm.hpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/include/boost/mp11/algorithm.hpp b/include/boost/mp11/algorithm.hpp index be377f5..b58ce12 100644 --- a/include/boost/mp11/algorithm.hpp +++ b/include/boost/mp11/algorithm.hpp @@ -1261,6 +1261,27 @@ template using mp_pairwise_fold_impl = mp_transform_q using mp_pairwise_fold_q = mp_eval_if, mp_clear, detail::mp_pairwise_fold_impl, L, Q>; template class F> using mp_pairwise_fold = mp_pairwise_fold_q>; +// mp_sliding_fold +namespace detail +{ + +template struct mp_sliding_fold_impl; + +template struct mp_sliding_fold_impl> +{ + using type = mp_transform_q::value - (sizeof...(Ints) - Ints - 1)>, Ints>...>; +}; + +template struct mp_sliding_fold_impl +{ + using type = mp_clear; +}; + +} // namespace detail + +template using mp_sliding_fold_q = typename detail::mp_sliding_fold_impl::value >= N::value>, L, Q, make_index_sequence>::type; +template class F> using mp_sliding_fold = mp_sliding_fold_q>; + // mp_intersperse namespace detail { From 70ff01c85f20b1af5e2fee6c49ada1e30c1f36a9 Mon Sep 17 00:00:00 2001 From: Braden Ganetsky Date: Sun, 30 Jul 2023 12:48:11 -0500 Subject: [PATCH 2/3] Add mp_sliding_fold to the adoc file --- doc/mp11/algorithm.adoc | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/doc/mp11/algorithm.adoc b/doc/mp11/algorithm.adoc index 95b9d73..a3b4553 100644 --- a/doc/mp11/algorithm.adoc +++ b/doc/mp11/algorithm.adoc @@ -846,6 +846,39 @@ template class P> using is_sorted = mp_none_of>, mp_to_bool>; ---- +## mp_sliding_fold + + template class F> using mp_sliding_fold = /*...*/; + +`mp_sliding_fold` returns a list of the same form as `L` whose elements are +the result of the application of the n-ary metafunction `F` to each n-tuple of adjacent +elements of `L`. That is, `mp_sliding_fold, mp_size_t<3>, F>` is +`L, F>`. + +The result has `N-1` fewer elements than the original. +If `L` has fewer than `N::value` elements, the result is an empty list. + +.Using mp_sliding_fold +---- +template using local_maximum = + mp_sliding_fold; +---- + +## mp_sliding_fold_q + + template using mp_sliding_fold_q = + mp_sliding_fold; + +As `mp_sliding_fold`, but takes a quoted metafunction. + +.Using mp_sliding_fold_q +---- +struct average { template using fn = mp_int::value / sizeof...(C)>; }; + +template using moving_average = + mp_sliding_fold_q; +---- + ## mp_iterate template class F, template class R> From d16fb0201cac235821972cd16639aeade5487b3f Mon Sep 17 00:00:00 2001 From: Braden Ganetsky Date: Sun, 30 Jul 2023 22:42:05 -0500 Subject: [PATCH 3/3] Add mp_sliding_fold tests --- test/Jamfile | 2 + test/mp_sliding_fold.cpp | 100 +++++++++++++++++++++++++++++++++++ test/mp_sliding_fold_q.cpp | 104 +++++++++++++++++++++++++++++++++++++ 3 files changed, 206 insertions(+) create mode 100644 test/mp_sliding_fold.cpp create mode 100644 test/mp_sliding_fold_q.cpp diff --git a/test/Jamfile b/test/Jamfile index 335c812..510da30 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -158,6 +158,8 @@ run mp_partial_sum.cpp ; run mp_iterate.cpp ; run mp_pairwise_fold.cpp ; run mp_pairwise_fold_q.cpp ; +run mp_sliding_fold.cpp ; +run mp_sliding_fold_q.cpp ; run mp_intersperse.cpp ; run mp_split.cpp ; run mp_join.cpp ; diff --git a/test/mp_sliding_fold.cpp b/test/mp_sliding_fold.cpp new file mode 100644 index 0000000..5eacc35 --- /dev/null +++ b/test/mp_sliding_fold.cpp @@ -0,0 +1,100 @@ +// Copyright 2023 Braden Ganetsky (braden.ganetsky@gmail.com) +// +// 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 + +struct X1 {}; +struct X2 {}; +struct X3 {}; +struct X4 {}; +struct X5 {}; + +template using average = boost::mp11::mp_int::value / sizeof...(C)>; + +int main() +{ + using boost::mp11::mp_list; + using boost::mp11::mp_list_c; + using boost::mp11::mp_plus; + using boost::mp11::mp_size_t; + using boost::mp11::mp_sliding_fold; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<1>, mp_list>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<1>, mp_list>, mp_list>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<1>, mp_list>, mp_list, mp_list>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<1>, mp_list>, mp_list, mp_list, mp_list>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<1>, mp_list>, mp_list, mp_list, mp_list, mp_list>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<1>, mp_list>, mp_list, mp_list, mp_list, mp_list, mp_list>>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, mp_list>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, mp_list>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, mp_list>, mp_list>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, mp_list>, mp_list, mp_list>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, mp_list>, mp_list, mp_list, mp_list>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, mp_list>, mp_list, mp_list, mp_list, mp_list>>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<3>, mp_list>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<3>, mp_list>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<3>, mp_list>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<3>, mp_list>, mp_list>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<3>, mp_list>, mp_list, mp_list>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<3>, mp_list>, mp_list, mp_list, mp_list>>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<4>, mp_list>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<4>, mp_list>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<4>, mp_list>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<4>, mp_list>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<4>, mp_list>, mp_list>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<4>, mp_list>, mp_list, mp_list>>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<5>, mp_list>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<5>, mp_list>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<5>, mp_list>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<5>, mp_list>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<5>, mp_list>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<5>, mp_list>, mp_list>>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<6>, mp_list>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<6>, mp_list>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<6>, mp_list>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<6>, mp_list>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<6>, mp_list>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<6>, mp_list>, mp_list<>>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, std::pair>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, std::pair>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, std::pair>, mp_list>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, std::pair>, mp_list, std::pair>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, std::pair>, mp_list, std::pair, std::pair>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, std::pair>, mp_list, std::pair, std::pair, std::pair>>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, std::pair>, std::tuple<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, std::pair>, std::tuple<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, std::pair>, std::tuple>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, std::pair>, std::tuple, std::pair>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, std::pair>, std::tuple, std::pair, std::pair>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, std::pair>, std::tuple, std::pair, std::pair, std::pair>>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<1>, mp_plus>, mp_list_c>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, mp_plus>, mp_list_c>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<3>, mp_plus>, mp_list_c>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<4>, mp_plus>, mp_list_c>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<5>, mp_plus>, mp_list_c>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<6>, mp_plus>, mp_list_c>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<1>, average>, mp_list_c>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, average>, mp_list_c>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<3>, average>, mp_list_c>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<4>, average>, mp_list_c>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<5>, average>, mp_list_c>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<6>, average>, mp_list_c>)); + + return boost::report_errors(); +} diff --git a/test/mp_sliding_fold_q.cpp b/test/mp_sliding_fold_q.cpp new file mode 100644 index 0000000..ac68f09 --- /dev/null +++ b/test/mp_sliding_fold_q.cpp @@ -0,0 +1,104 @@ +// Copyright 2023 Braden Ganetsky (braden.ganetsky@gmail.com) +// +// 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 + +struct X1 {}; +struct X2 {}; +struct X3 {}; +struct X4 {}; +struct X5 {}; + +struct average +{ + template using fn = boost::mp11::mp_int::value / sizeof...(C)>; +}; + +int main() +{ + using boost::mp11::mp_list; + using boost::mp11::mp_list_c; + using boost::mp11::mp_plus; + using boost::mp11::mp_quote; + using boost::mp11::mp_size_t; + using boost::mp11::mp_sliding_fold_q; + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<1>, mp_quote>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<1>, mp_quote>, mp_list>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<1>, mp_quote>, mp_list, mp_list>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<1>, mp_quote>, mp_list, mp_list, mp_list>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<1>, mp_quote>, mp_list, mp_list, mp_list, mp_list>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<1>, mp_quote>, mp_list, mp_list, mp_list, mp_list, mp_list>>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, mp_quote>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, mp_quote>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, mp_quote>, mp_list>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, mp_quote>, mp_list, mp_list>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, mp_quote>, mp_list, mp_list, mp_list>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, mp_quote>, mp_list, mp_list, mp_list, mp_list>>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<3>, mp_quote>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<3>, mp_quote>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<3>, mp_quote>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<3>, mp_quote>, mp_list>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<3>, mp_quote>, mp_list, mp_list>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<3>, mp_quote>, mp_list, mp_list, mp_list>>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<4>, mp_quote>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<4>, mp_quote>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<4>, mp_quote>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<4>, mp_quote>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<4>, mp_quote>, mp_list>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<4>, mp_quote>, mp_list, mp_list>>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<5>, mp_quote>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<5>, mp_quote>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<5>, mp_quote>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<5>, mp_quote>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<5>, mp_quote>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<5>, mp_quote>, mp_list>>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<6>, mp_quote>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<6>, mp_quote>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<6>, mp_quote>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<6>, mp_quote>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<6>, mp_quote>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<6>, mp_quote>, mp_list<>>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, mp_quote>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, mp_quote>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, mp_quote>, mp_list>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, mp_quote>, mp_list, std::pair>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, mp_quote>, mp_list, std::pair, std::pair>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, mp_quote>, mp_list, std::pair, std::pair, std::pair>>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, mp_quote>, std::tuple<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, mp_quote>, std::tuple<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, mp_quote>, std::tuple>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, mp_quote>, std::tuple, std::pair>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, mp_quote>, std::tuple, std::pair, std::pair>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, mp_quote>, std::tuple, std::pair, std::pair, std::pair>>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<1>, mp_quote>, mp_list_c>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, mp_quote>, mp_list_c>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<3>, mp_quote>, mp_list_c>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<4>, mp_quote>, mp_list_c>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<5>, mp_quote>, mp_list_c>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<6>, mp_quote>, mp_list_c>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<1>, average>, mp_list_c>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<2>, average>, mp_list_c>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<3>, average>, mp_list_c>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<4>, average>, mp_list_c>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<5>, average>, mp_list_c>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, mp_size_t<6>, average>, mp_list_c>)); + + return boost::report_errors(); +}