From aa115778121297416a6b925df72727605bb076cb Mon Sep 17 00:00:00 2001 From: Kris Jusiak Date: Tue, 3 Dec 2019 13:08:32 -0700 Subject: [PATCH] :new: [mp_unique_if] Support for `mp_unique` with a predicate Problem: - `mp_unique` doesn't support custom predicates. Solution: - Add `mp_unique_if` and `mp_unique_if_q` which allow to remove duplicates elements with a predicate. --- doc/mp11/algorithm.adoc | 12 +++++++ include/boost/mp11/algorithm.hpp | 16 ++++++++++ test/Jamfile | 2 ++ test/mp_unique_if.cpp | 54 ++++++++++++++++++++++++++++++++ test/mp_unique_if_q.cpp | 51 ++++++++++++++++++++++++++++++ 5 files changed, 135 insertions(+) create mode 100644 test/mp_unique_if.cpp create mode 100644 test/mp_unique_if_q.cpp diff --git a/doc/mp11/algorithm.adoc b/doc/mp11/algorithm.adoc index 6dcf9a3..86158be 100644 --- a/doc/mp11/algorithm.adoc +++ b/doc/mp11/algorithm.adoc @@ -659,6 +659,18 @@ As `mp_reverse_fold`, but takes a quoted metafunction. `mp_unique` returns a list of the same form as `L` with the duplicate elements removed. +## mp_unique_if + + template using mp_unique_if = /*...*/; + +`mp_unique_if` returns a list of the same form as `L` with the duplicate elements removed for which `mp_to_bool>` is `mp_true`. + +## mp_unique_if + + template using mp_unique_if = mp_unique_if; + +As `mp_unique_if`, but takes a quoted metafunction. + ## mp_all_of template class P> using mp_all_of = diff --git a/include/boost/mp11/algorithm.hpp b/include/boost/mp11/algorithm.hpp index b8719d6..e874c77 100644 --- a/include/boost/mp11/algorithm.hpp +++ b/include/boost/mp11/algorithm.hpp @@ -950,6 +950,22 @@ template class L, class... T> struct mp_unique_impl> template using mp_unique = typename detail::mp_unique_impl::type; +namespace detail { +template class P> struct mp_unique_if_push_back { + template struct impl; + template class L, class... Ts, class T> + struct impl, T> { + using type = mp_if...>, L, L>; + }; + template using fn = typename impl::type; +}; +} // namespace detail + +// mp_unique_if +template class P> +using mp_unique_if = mp_fold_q, detail::mp_unique_if_push_back

>; +template using mp_unique_if_q = mp_unique_if; + // mp_all_of template class P> using mp_all_of = mp_bool< mp_count_if::value == mp_size::value >; template using mp_all_of_q = mp_all_of; diff --git a/test/Jamfile b/test/Jamfile index e2df961..542221f 100644 --- a/test/Jamfile +++ b/test/Jamfile @@ -92,6 +92,8 @@ run mp_fold_q.cpp ; run mp_reverse_fold.cpp ; run mp_reverse_fold_q.cpp ; run mp_unique.cpp ; +run mp_unique_if.cpp ; +run mp_unique_if_q.cpp ; run mp_all_of.cpp ; run mp_all_of_q.cpp ; run mp_any_of.cpp ; diff --git a/test/mp_unique_if.cpp b/test/mp_unique_if.cpp new file mode 100644 index 0000000..db527df --- /dev/null +++ b/test/mp_unique_if.cpp @@ -0,0 +1,54 @@ +// Copyright 2015 Peter Dimov. +// Copyright 2019 Kris Jusiak. +// +// 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 + +int main() +{ + using boost::mp11::mp_list; + using boost::mp11::mp_unique_if; + + { + BOOST_TEST_TRAIT_TRUE((std::is_same, std::is_same>,mp_list<>>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same, std::is_same>,mp_list>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, std::is_same>,mp_list>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, std::is_same>,mp_list>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, std::is_same>,mp_list>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same, std::is_same>,mp_list>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, std::is_same>,mp_list>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, std::is_same>,mp_list>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same, std::is_same>,mp_list>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, std::is_same>,mp_list>)); + } + + { + BOOST_TEST_TRAIT_TRUE((std::is_same, std::is_same>,std::tuple<>>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same, std::is_same>,std::tuple>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, std::is_same>,std::tuple>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, std::is_same>,std::tuple>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, std::is_same>,std::tuple>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same, std::is_same>,std::tuple>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, std::is_same>,std::tuple>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, std::is_same>,std::tuple>)); + + BOOST_TEST_TRAIT_TRUE((std::is_same, std::is_same>,std::tuple>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, std::is_same>,std::tuple>)); + } + + return boost::report_errors(); +} diff --git a/test/mp_unique_if_q.cpp b/test/mp_unique_if_q.cpp new file mode 100644 index 0000000..55805e3 --- /dev/null +++ b/test/mp_unique_if_q.cpp @@ -0,0 +1,51 @@ +// Copyright 2015 Peter Dimov. +// Copyright 2019 Kris Jusiak. +// +// 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 is_same_size +{ + template + struct impl : boost::mp11::mp_bool {}; + template using fn = typename impl::type; +}; + +int main() +{ + using boost::mp11::mp_list; + using boost::mp11::mp_unique_if_q; + + { + BOOST_TEST_TRAIT_TRUE((std::is_same, is_same_size>, mp_list<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, is_same_size>, mp_list>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, is_same_size>, mp_list>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, is_same_size>, mp_list>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, is_same_size>, mp_list>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, is_same_size>, mp_list>)); + struct foo{}; + BOOST_TEST_TRAIT_TRUE((std::is_same, is_same_size>, mp_list>)); + } + + { + BOOST_TEST_TRAIT_TRUE((std::is_same, is_same_size>, std::tuple<>>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, is_same_size>, std::tuple>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, is_same_size>, std::tuple>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, is_same_size>, std::tuple>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, is_same_size>, std::tuple>)); + BOOST_TEST_TRAIT_TRUE((std::is_same, is_same_size>, std::tuple>)); + struct foo{}; + BOOST_TEST_TRAIT_TRUE((std::is_same, is_same_size>, std::tuple>)); + } + + return boost::report_errors(); +}