summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2024-06-26 14:45:44 -0700
committerGravatar Copybara-Service <copybara-worker@google.com>2024-06-26 14:46:45 -0700
commit63d4b2fe1e0d4bd6a7b916f398643db40c35624b (patch)
treec2e28b160f1e3a942ccb0799e893999ae144dfea
parentc98bd9c8840f9ded87cf1fd1238455468d325628 (diff)
Add `c_contains()` and `c_contains_subrange()` to `absl/algorithm/container.h`.
These functions are based on the C++23's `std::ranges::contains()` and `std::ranges::contains_subrange()` functions, see: https://en.cppreference.com/w/cpp/algorithm/ranges/contains PiperOrigin-RevId: 647084955 Change-Id: If5a01784e3cf1cc4d88e7f2fef92a3701fafc886
-rw-r--r--absl/algorithm/container.h30
-rw-r--r--absl/algorithm/container_test.cc16
2 files changed, 46 insertions, 0 deletions
diff --git a/absl/algorithm/container.h b/absl/algorithm/container.h
index a2d126b7..5a025e46 100644
--- a/absl/algorithm/container.h
+++ b/absl/algorithm/container.h
@@ -211,6 +211,16 @@ container_algorithm_internal::ContainerIter<C> c_find(C& c, T&& value) {
std::forward<T>(value));
}
+// c_contains()
+//
+// Container-based version of the <algorithm> `std::ranges::contains()` C++23
+// function to search a container for a value.
+template <typename Sequence, typename T>
+bool c_contains(const Sequence& sequence, T&& value) {
+ return absl::c_find(sequence, std::forward<T>(value)) !=
+ container_algorithm_internal::c_end(sequence);
+}
+
// c_find_if()
//
// Container-based version of the <algorithm> `std::find_if()` function to find
@@ -427,6 +437,26 @@ container_algorithm_internal::ContainerIter<Sequence1> c_search(
std::forward<BinaryPredicate>(pred));
}
+// c_contains_subrange()
+//
+// Container-based version of the <algorithm> `std::ranges::contains_subrange()`
+// C++23 function to search a container for a subsequence.
+template <typename Sequence1, typename Sequence2>
+bool c_contains_subrange(Sequence1& sequence, Sequence2& subsequence) {
+ return absl::c_search(sequence, subsequence) !=
+ container_algorithm_internal::c_end(sequence);
+}
+
+// Overload of c_contains_subrange() for using a predicate evaluation other than
+// `==` as the function's test condition.
+template <typename Sequence1, typename Sequence2, typename BinaryPredicate>
+bool c_contains_subrange(Sequence1& sequence, Sequence2& subsequence,
+ BinaryPredicate&& pred) {
+ return absl::c_search(sequence, subsequence,
+ std::forward<BinaryPredicate>(pred)) !=
+ container_algorithm_internal::c_end(sequence);
+}
+
// c_search_n()
//
// Container-based version of the <algorithm> `std::search_n()` function to
diff --git a/absl/algorithm/container_test.cc b/absl/algorithm/container_test.cc
index c01f5fc0..7e54e2b2 100644
--- a/absl/algorithm/container_test.cc
+++ b/absl/algorithm/container_test.cc
@@ -113,6 +113,11 @@ TEST_F(NonMutatingTest, FindReturnsCorrectType) {
absl::c_find(absl::implicit_cast<const std::list<int>&>(sequence_), 3);
}
+TEST_F(NonMutatingTest, Contains) {
+ EXPECT_TRUE(absl::c_contains(container_, 3));
+ EXPECT_FALSE(absl::c_contains(container_, 4));
+}
+
TEST_F(NonMutatingTest, FindIf) { absl::c_find_if(container_, Predicate); }
TEST_F(NonMutatingTest, FindIfNot) {
@@ -305,6 +310,17 @@ TEST_F(NonMutatingTest, SearchWithPredicate) {
absl::c_search(vector_, sequence_, BinPredicate);
}
+TEST_F(NonMutatingTest, ContainsSubrange) {
+ EXPECT_TRUE(absl::c_contains_subrange(sequence_, vector_));
+ EXPECT_TRUE(absl::c_contains_subrange(vector_, sequence_));
+ EXPECT_TRUE(absl::c_contains_subrange(array_, sequence_));
+}
+
+TEST_F(NonMutatingTest, ContainsSubrangeWithPredicate) {
+ EXPECT_TRUE(absl::c_contains_subrange(sequence_, vector_, Equals));
+ EXPECT_TRUE(absl::c_contains_subrange(vector_, sequence_, Equals));
+}
+
TEST_F(NonMutatingTest, SearchN) { absl::c_search_n(sequence_, 3, 1); }
TEST_F(NonMutatingTest, SearchNWithPredicate) {