diff options
author | Benjamin Barenblat <bbaren@google.com> | 2024-09-03 11:49:29 -0400 |
---|---|---|
committer | Benjamin Barenblat <bbaren@google.com> | 2024-09-03 11:49:29 -0400 |
commit | c1afa8b8238c25591ca80d068477aa7d4ce05fc8 (patch) | |
tree | 284a9f8b319de5783ff83ad004a9e390cb60fd0d /absl/algorithm | |
parent | 23778b53f420f54eebc195dd8430e79bda165e5b (diff) | |
parent | 4447c7562e3bc702ade25105912dce503f0c4010 (diff) | |
download | abseil-c1afa8b8238c25591ca80d068477aa7d4ce05fc8.tar.gz abseil-c1afa8b8238c25591ca80d068477aa7d4ce05fc8.tar.bz2 abseil-c1afa8b8238c25591ca80d068477aa7d4ce05fc8.zip |
Merge new upstream LTS 20240722.0
Diffstat (limited to 'absl/algorithm')
-rw-r--r-- | absl/algorithm/BUILD.bazel | 2 | ||||
-rw-r--r-- | absl/algorithm/CMakeLists.txt | 2 | ||||
-rw-r--r-- | absl/algorithm/container.h | 75 | ||||
-rw-r--r-- | absl/algorithm/container_test.cc | 63 |
4 files changed, 124 insertions, 18 deletions
diff --git a/absl/algorithm/BUILD.bazel b/absl/algorithm/BUILD.bazel index ddf9e11f..f20e7290 100644 --- a/absl/algorithm/BUILD.bazel +++ b/absl/algorithm/BUILD.bazel @@ -65,6 +65,7 @@ cc_library( linkopts = ABSL_DEFAULT_LINKOPTS, deps = [ ":algorithm", + "//absl/base:config", "//absl/base:core_headers", "//absl/base:nullability", "//absl/meta:type_traits", @@ -79,6 +80,7 @@ cc_test( deps = [ ":container", "//absl/base", + "//absl/base:config", "//absl/base:core_headers", "//absl/memory", "//absl/types:span", diff --git a/absl/algorithm/CMakeLists.txt b/absl/algorithm/CMakeLists.txt index 5577164d..252b6b20 100644 --- a/absl/algorithm/CMakeLists.txt +++ b/absl/algorithm/CMakeLists.txt @@ -48,6 +48,7 @@ absl_cc_library( ${ABSL_DEFAULT_COPTS} DEPS absl::algorithm + absl::config absl::core_headers absl::meta absl::nullability @@ -64,6 +65,7 @@ absl_cc_test( DEPS absl::algorithm_container absl::base + absl::config absl::core_headers absl::memory absl::span diff --git a/absl/algorithm/container.h b/absl/algorithm/container.h index c7bafae1..6bbe3b5a 100644 --- a/absl/algorithm/container.h +++ b/absl/algorithm/container.h @@ -44,6 +44,7 @@ #include <cassert> #include <iterator> #include <numeric> +#include <random> #include <type_traits> #include <unordered_map> #include <unordered_set> @@ -51,6 +52,7 @@ #include <vector> #include "absl/algorithm/algorithm.h" +#include "absl/base/config.h" #include "absl/base/macros.h" #include "absl/base/nullability.h" #include "absl/meta/type_traits.h" @@ -92,17 +94,17 @@ using ContainerPointerType = // using std::end; // std::foo(begin(c), end(c)); // becomes -// std::foo(container_algorithm_internal::begin(c), -// container_algorithm_internal::end(c)); +// std::foo(container_algorithm_internal::c_begin(c), +// container_algorithm_internal::c_end(c)); // These are meant for internal use only. template <typename C> -ContainerIter<C> c_begin(C& c) { +ABSL_INTERNAL_CONSTEXPR_SINCE_CXX17 ContainerIter<C> c_begin(C& c) { return begin(c); } template <typename C> -ContainerIter<C> c_end(C& c) { +ABSL_INTERNAL_CONSTEXPR_SINCE_CXX17 ContainerIter<C> c_end(C& c) { return end(c); } @@ -145,8 +147,9 @@ bool c_linear_search(const C& c, EqualityComparable&& value) { // Container-based version of the <iterator> `std::distance()` function to // return the number of elements within a container. template <typename C> -container_algorithm_internal::ContainerDifferenceType<const C> c_distance( - const C& c) { +ABSL_INTERNAL_CONSTEXPR_SINCE_CXX17 + container_algorithm_internal::ContainerDifferenceType<const C> + c_distance(const C& c) { return std::distance(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c)); } @@ -210,6 +213,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 @@ -426,6 +439,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 @@ -1500,8 +1533,9 @@ c_is_heap_until(RandomAccessContainer& sequence, LessThan&& comp) { // to return an iterator pointing to the element with the smallest value, using // `operator<` to make the comparisons. template <typename Sequence> -container_algorithm_internal::ContainerIter<Sequence> c_min_element( - Sequence& sequence) { +ABSL_INTERNAL_CONSTEXPR_SINCE_CXX17 + container_algorithm_internal::ContainerIter<Sequence> + c_min_element(Sequence& sequence) { return std::min_element(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence)); } @@ -1509,8 +1543,9 @@ container_algorithm_internal::ContainerIter<Sequence> c_min_element( // Overload of c_min_element() for performing a `comp` comparison other than // `operator<`. template <typename Sequence, typename LessThan> -container_algorithm_internal::ContainerIter<Sequence> c_min_element( - Sequence& sequence, LessThan&& comp) { +ABSL_INTERNAL_CONSTEXPR_SINCE_CXX17 + container_algorithm_internal::ContainerIter<Sequence> + c_min_element(Sequence& sequence, LessThan&& comp) { return std::min_element(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), std::forward<LessThan>(comp)); @@ -1522,8 +1557,9 @@ container_algorithm_internal::ContainerIter<Sequence> c_min_element( // to return an iterator pointing to the element with the largest value, using // `operator<` to make the comparisons. template <typename Sequence> -container_algorithm_internal::ContainerIter<Sequence> c_max_element( - Sequence& sequence) { +ABSL_INTERNAL_CONSTEXPR_SINCE_CXX17 + container_algorithm_internal::ContainerIter<Sequence> + c_max_element(Sequence& sequence) { return std::max_element(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence)); } @@ -1531,8 +1567,9 @@ container_algorithm_internal::ContainerIter<Sequence> c_max_element( // Overload of c_max_element() for performing a `comp` comparison other than // `operator<`. template <typename Sequence, typename LessThan> -container_algorithm_internal::ContainerIter<Sequence> c_max_element( - Sequence& sequence, LessThan&& comp) { +ABSL_INTERNAL_CONSTEXPR_SINCE_CXX17 + container_algorithm_internal::ContainerIter<Sequence> + c_max_element(Sequence& sequence, LessThan&& comp) { return std::max_element(container_algorithm_internal::c_begin(sequence), container_algorithm_internal::c_end(sequence), std::forward<LessThan>(comp)); @@ -1545,8 +1582,9 @@ container_algorithm_internal::ContainerIter<Sequence> c_max_element( // smallest and largest values, respectively, using `operator<` to make the // comparisons. template <typename C> -container_algorithm_internal::ContainerIterPairType<C, C> c_minmax_element( - C& c) { +ABSL_INTERNAL_CONSTEXPR_SINCE_CXX17 + container_algorithm_internal::ContainerIterPairType<C, C> + c_minmax_element(C& c) { return std::minmax_element(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c)); } @@ -1554,8 +1592,9 @@ container_algorithm_internal::ContainerIterPairType<C, C> c_minmax_element( // Overload of c_minmax_element() for performing `comp` comparisons other than // `operator<`. template <typename C, typename LessThan> -container_algorithm_internal::ContainerIterPairType<C, C> c_minmax_element( - C& c, LessThan&& comp) { +ABSL_INTERNAL_CONSTEXPR_SINCE_CXX17 + container_algorithm_internal::ContainerIterPairType<C, C> + c_minmax_element(C& c, LessThan&& comp) { return std::minmax_element(container_algorithm_internal::c_begin(c), container_algorithm_internal::c_end(c), std::forward<LessThan>(comp)); diff --git a/absl/algorithm/container_test.cc b/absl/algorithm/container_test.cc index c01f5fc0..50122249 100644 --- a/absl/algorithm/container_test.cc +++ b/absl/algorithm/container_test.cc @@ -15,6 +15,7 @@ #include "absl/algorithm/container.h" #include <algorithm> +#include <array> #include <functional> #include <initializer_list> #include <iterator> @@ -31,6 +32,7 @@ #include "gmock/gmock.h" #include "gtest/gtest.h" #include "absl/base/casts.h" +#include "absl/base/config.h" #include "absl/base/macros.h" #include "absl/memory/memory.h" #include "absl/types/span.h" @@ -113,6 +115,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 +312,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) { @@ -1144,4 +1162,49 @@ TEST(MutatingTest, PermutationOperations) { EXPECT_EQ(initial, permuted); } +#if defined(ABSL_INTERNAL_CPLUSPLUS_LANG) && \ + ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L +TEST(ConstexprTest, Distance) { + // Works at compile time with constexpr containers. + static_assert(absl::c_distance(std::array<int, 3>()) == 3); +} + +TEST(ConstexprTest, MinElement) { + constexpr std::array<int, 3> kArray = {1, 2, 3}; + static_assert(*absl::c_min_element(kArray) == 1); +} + +TEST(ConstexprTest, MinElementWithPredicate) { + constexpr std::array<int, 3> kArray = {1, 2, 3}; + static_assert(*absl::c_min_element(kArray, std::greater<int>()) == 3); +} + +TEST(ConstexprTest, MaxElement) { + constexpr std::array<int, 3> kArray = {1, 2, 3}; + static_assert(*absl::c_max_element(kArray) == 3); +} + +TEST(ConstexprTest, MaxElementWithPredicate) { + constexpr std::array<int, 3> kArray = {1, 2, 3}; + static_assert(*absl::c_max_element(kArray, std::greater<int>()) == 1); +} + +TEST(ConstexprTest, MinMaxElement) { + static constexpr std::array<int, 3> kArray = {1, 2, 3}; + constexpr auto kMinMaxPair = absl::c_minmax_element(kArray); + static_assert(*kMinMaxPair.first == 1); + static_assert(*kMinMaxPair.second == 3); +} + +TEST(ConstexprTest, MinMaxElementWithPredicate) { + static constexpr std::array<int, 3> kArray = {1, 2, 3}; + constexpr auto kMinMaxPair = + absl::c_minmax_element(kArray, std::greater<int>()); + static_assert(*kMinMaxPair.first == 3); + static_assert(*kMinMaxPair.second == 1); +} + +#endif // defined(ABSL_INTERNAL_CPLUSPLUS_LANG) && + // ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L + } // namespace |