From d40d10aae72d1d6d04b818d2173e5c5f5a731384 Mon Sep 17 00:00:00 2001 From: Ali Mohammad Pur Date: Thu, 22 Jul 2021 19:11:00 +0430 Subject: [PATCH] AK: Implement {any,all}_of(IterableContainer&&, Predicate) This is a generally nicer-to-use version of the existing {any,all}_of() that doesn't require the user to explicitly provide two iterators. As a bonus, it also allows arbitrary iterators (as opposed to the hard requirement of providing SimpleIterators in the iterator version). --- AK/AllOf.h | 11 +++++++++++ AK/AnyOf.h | 11 +++++++++++ Tests/AK/TestAllOf.cpp | 38 ++++++++++++++++++++++++++++++++++++++ Tests/AK/TestAnyOf.cpp | 41 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 101 insertions(+) diff --git a/AK/AllOf.h b/AK/AllOf.h index 41a8095d1f..1248ddb471 100644 --- a/AK/AllOf.h +++ b/AK/AllOf.h @@ -6,6 +6,7 @@ #pragma once +#include #include namespace AK { @@ -24,6 +25,16 @@ constexpr bool all_of( return true; } +template +constexpr bool all_of(Container&& container, auto const& predicate) +{ + for (auto&& entry : container) { + if (!predicate(entry)) + return false; + } + return true; +} + } using AK::all_of; diff --git a/AK/AnyOf.h b/AK/AnyOf.h index 201a875fda..034c1d57ea 100644 --- a/AK/AnyOf.h +++ b/AK/AnyOf.h @@ -6,6 +6,7 @@ #pragma once +#include #include #include @@ -20,6 +21,16 @@ constexpr bool any_of( return find_if(begin, end, predicate) != end; } +template +constexpr bool any_of(Container&& container, auto const& predicate) +{ + for (auto&& entry : container) { + if (predicate(entry)) + return true; + } + return false; +} + } using AK::any_of; diff --git a/Tests/AK/TestAllOf.cpp b/Tests/AK/TestAllOf.cpp index 48f5d0f7aa..f8b23f71ce 100644 --- a/Tests/AK/TestAllOf.cpp +++ b/Tests/AK/TestAllOf.cpp @@ -19,3 +19,41 @@ TEST_CASE(should_determine_if_predicate_applies_to_all_elements_in_container) EXPECT(all_of(a.begin(), a.end(), [](auto elem) { return elem == 0; })); EXPECT(!all_of(a.begin(), a.end(), [](auto elem) { return elem == 1; })); } + +TEST_CASE(container_form) +{ + constexpr Array a { 10, 20, 30 }; + static_assert(all_of(a, [](auto elem) { return elem > 0; })); + static_assert(!all_of(a, [](auto elem) { return elem > 10; })); + EXPECT(all_of(a, [](auto elem) { return elem > 0; })); + EXPECT(!all_of(a, [](auto elem) { return elem > 10; })); + + Vector b { 10, 20, 30 }; + EXPECT(all_of(b, [](auto elem) { return elem > 0; })); + EXPECT(!all_of(b, [](auto elem) { return elem > 10; })); + + struct ArbitraryIterable { + struct ArbitraryIterator { + ArbitraryIterator(int v) + : value(v) + { + } + + bool operator==(ArbitraryIterator const&) const = default; + int operator*() const { return value; } + ArbitraryIterator& operator++() + { + ++value; + return *this; + } + + int value; + }; + ArbitraryIterator begin() const { return 0; } + ArbitraryIterator end() const { return 20; } + }; + + ArbitraryIterable c; + EXPECT(all_of(c, [](auto elem) { return elem < 20; })); + EXPECT(!all_of(c, [](auto elem) { return elem > 10; })); +} diff --git a/Tests/AK/TestAnyOf.cpp b/Tests/AK/TestAnyOf.cpp index 2fcfaf29e6..5b7400c5d2 100644 --- a/Tests/AK/TestAnyOf.cpp +++ b/Tests/AK/TestAnyOf.cpp @@ -21,3 +21,44 @@ TEST_CASE(should_determine_if_predicate_applies_to_any_element_in_container) EXPECT(any_of(a.begin(), a.end(), [](auto elem) { return elem == 1; })); EXPECT(!any_of(a.begin(), a.end(), [](auto elem) { return elem == 2; })); } + +TEST_CASE(container_form) +{ + constexpr Array a { 10, 20, 30 }; + static_assert(any_of(a, [](auto elem) { return elem == 10; })); + static_assert(any_of(a, [](auto elem) { return elem == 20; })); + static_assert(!any_of(a, [](auto elem) { return elem == 40; })); + + EXPECT(any_of(a, [](auto elem) { return elem == 10; })); + EXPECT(any_of(a, [](auto elem) { return elem == 20; })); + EXPECT(!any_of(a, [](auto elem) { return elem == 40; })); + + Vector b { 10, 20, 30 }; + EXPECT(any_of(b, [](auto elem) { return elem > 10; })); + EXPECT(!any_of(b, [](auto elem) { return elem > 40; })); + + struct ArbitraryIterable { + struct ArbitraryIterator { + ArbitraryIterator(int v) + : value(v) + { + } + + bool operator==(ArbitraryIterator const&) const = default; + int operator*() const { return value; } + ArbitraryIterator& operator++() + { + ++value; + return *this; + } + + int value; + }; + ArbitraryIterator begin() const { return 0; } + ArbitraryIterator end() const { return 20; } + }; + + ArbitraryIterable c; + EXPECT(any_of(c, [](auto elem) { return elem < 20; })); + EXPECT(!any_of(c, [](auto elem) { return elem > 31; })); +}