From 1fac38b7bc66675882e1aeec6c3cd79ef171bf0f Mon Sep 17 00:00:00 2001 From: Louis Dionne Date: Sun, 18 May 2014 19:45:07 -0400 Subject: [PATCH] Add any, all, none and {any,all,none}_of. --- include/boost/hana/iterable.hpp | 73 +++++++++++++++++++++++++++++++++ test/iterable.cpp | 12 ++++++ 2 files changed, 85 insertions(+) diff --git a/include/boost/hana/iterable.hpp b/include/boost/hana/iterable.hpp index 1b2e5c3ca..94b789c21 100644 --- a/include/boost/hana/iterable.hpp +++ b/include/boost/hana/iterable.hpp @@ -63,6 +63,42 @@ namespace boost { namespace hana { { return Iterable::drop_impl(n, iterable); } } drop{}; + constexpr struct _any { + template + constexpr auto operator()(Pred pred, Iterable_ iterable) const + { return Iterable::any_impl(pred, iterable); } + } any{}; + + constexpr struct _any_of { + template + constexpr auto operator()(Iterable_ iterable) const + { return Iterable::any_of_impl(iterable); } + } any_of{}; + + constexpr struct _all { + template + constexpr auto operator()(Pred pred, Iterable_ iterable) const + { return Iterable::all_impl(pred, iterable); } + } all{}; + + constexpr struct _all_of { + template + constexpr auto operator()(Iterable_ iterable) const + { return Iterable::all_of_impl(iterable); } + } all_of{}; + + constexpr struct _none { + template + constexpr auto operator()(Pred pred, Iterable_ iterable) const + { return Iterable::none_impl(pred, iterable); } + } none{}; + + constexpr struct _none_of { + template + constexpr auto operator()(Iterable_ iterable) const + { return Iterable::none_of_impl(iterable); } + } none_of{}; + template <> struct defaults { @@ -114,6 +150,43 @@ namespace boost { namespace hana { return drop_helper(n, iterable, n == int_<0> || is_empty(iterable)); } + + // any, all, none + template + static constexpr Bool + any_helper(Pred pred, Iterable_ iterable, Bool) + { return {}; } + + template + static constexpr auto + any_helper(Pred pred, Iterable_ iterable, Bool) + { return pred(head(iterable)) || any(pred, tail(iterable)); } + + template + static constexpr auto any_impl(Pred pred, Iterable_ iterable) + { return any_helper(pred, iterable, is_empty(iterable)); } + + template + static constexpr auto all_impl(Pred pred, Iterable_ iterable) + { return !any([=](auto x) { return !pred(x); }, iterable); } + + template + static constexpr auto none_impl(Pred pred, Iterable_ iterable) + { return !any(pred, iterable); } + + + // any_of, all_of, none_of + template + static constexpr auto any_of_impl(Iterable_ iterable) + { return any([](auto x) { return x; }, iterable); } + + template + static constexpr auto all_of_impl(Iterable_ iterable) + { return all([](auto x) { return x; }, iterable); } + + template + static constexpr auto none_of_impl(Iterable_ iterable) + { return none([](auto x) { return x; }, iterable); } }; }} // end namespace boost::hana diff --git a/test/iterable.cpp b/test/iterable.cpp index 66d7c82ca..21d594422 100644 --- a/test/iterable.cpp +++ b/test/iterable.cpp @@ -53,9 +53,21 @@ void test_drop() { BOOST_HANA_STATIC_ASSERT(drop(int_<2>, iterable(int_<0>, int_<1>)) == iterable()); } +void test_all_of() { + BOOST_HANA_STATIC_ASSERT(all_of(iterable())); + BOOST_HANA_STATIC_ASSERT(all_of(iterable(true_))); + BOOST_HANA_STATIC_ASSERT(all_of(iterable(true_, true_))); + BOOST_HANA_STATIC_ASSERT(!all_of(iterable(true_, true_, false_))); + BOOST_HANA_STATIC_ASSERT(!all_of(iterable(false_, true_, true_))); + + BOOST_HANA_STATIC_ASSERT(all_of(iterable(true, true))); + BOOST_HANA_STATIC_ASSERT(!all_of(iterable(true, true, false))); +} + int main() { test_at(); test_last(); test_length(); test_drop(); + test_all_of(); }