diff options
author | Abseil Team <absl-team@google.com> | 2024-07-03 22:07:51 -0700 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2024-07-03 22:08:39 -0700 |
commit | 074a32af66648c74dd0104e251e44ace5b59f7fa (patch) | |
tree | a7ffd02d87db9a565627000ac9afbb59fa32d974 /absl | |
parent | eb46a63d77d7d1c1d30e2c9243099f89c629003c (diff) |
Mark c_min_element, c_max_element, and c_minmax_element as constexpr in C++17.
This allows them to be used in constant expressions, such as static_asserts.
PiperOrigin-RevId: 649292841
Change-Id: I76e31a94b933fa357276fee534b81c00c28c8b23
Diffstat (limited to 'absl')
-rw-r--r-- | absl/algorithm/container.h | 36 | ||||
-rw-r--r-- | absl/algorithm/container_test.cc | 36 | ||||
-rw-r--r-- | absl/base/config.h | 24 |
3 files changed, 69 insertions, 27 deletions
diff --git a/absl/algorithm/container.h b/absl/algorithm/container.h index 352ac46c..6bbe3b5a 100644 --- a/absl/algorithm/container.h +++ b/absl/algorithm/container.h @@ -99,12 +99,12 @@ using ContainerPointerType = // These are meant for internal use only. template <typename C> -ABSL_CONSTEXPR_SINCE_CXX17 ContainerIter<C> c_begin(C& c) { +ABSL_INTERNAL_CONSTEXPR_SINCE_CXX17 ContainerIter<C> c_begin(C& c) { return begin(c); } template <typename C> -ABSL_CONSTEXPR_SINCE_CXX17 ContainerIter<C> c_end(C& c) { +ABSL_INTERNAL_CONSTEXPR_SINCE_CXX17 ContainerIter<C> c_end(C& c) { return end(c); } @@ -147,7 +147,7 @@ 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> -ABSL_CONSTEXPR_SINCE_CXX17 +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), @@ -1533,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)); } @@ -1542,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)); @@ -1555,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)); } @@ -1564,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)); @@ -1578,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)); } @@ -1587,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 e5e2bf3d..50122249 100644 --- a/absl/algorithm/container_test.cc +++ b/absl/algorithm/container_test.cc @@ -1168,6 +1168,42 @@ 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 diff --git a/absl/base/config.h b/absl/base/config.h index 13263f9d..97c9a22a 100644 --- a/absl/base/config.h +++ b/absl/base/config.h @@ -941,25 +941,25 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || #define ABSL_HAVE_CONSTANT_EVALUATED 1 #endif -// ABSL_CONSTEXPR_SINCE_CXXYY is used to conditionally define constexpr for -// different C++ versions. -#if defined(ABSL_INTERNAL_CPLUSPLUS_LANG) && \ - ABSL_INTERNAL_CPLUSPLUS_LANG >= 201402L -#define ABSL_CONSTEXPR_SINCE_CXX14 constexpr -#else -#define ABSL_CONSTEXPR_SINCE_CXX14 -#endif +// ABSL_INTERNAL_CONSTEXPR_SINCE_CXXYY is used to conditionally define constexpr +// for different C++ versions. +// +// These macros are an implementation detail and will be unconditionally removed +// once the minimum supported C++ version catches up to a given version. +// +// For this reason, this symbol is considered INTERNAL and code outside of +// Abseil must not use it. #if defined(ABSL_INTERNAL_CPLUSPLUS_LANG) && \ ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L -#define ABSL_CONSTEXPR_SINCE_CXX17 constexpr +#define ABSL_INTERNAL_CONSTEXPR_SINCE_CXX17 constexpr #else -#define ABSL_CONSTEXPR_SINCE_CXX17 +#define ABSL_INTERNAL_CONSTEXPR_SINCE_CXX17 #endif #if defined(ABSL_INTERNAL_CPLUSPLUS_LANG) && \ ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L -#define ABSL_CONSTEXPR_SINCE_CXX20 constexpr +#define ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 constexpr #else -#define ABSL_CONSTEXPR_SINCE_CXX20 +#define ABSL_INTERNAL_CONSTEXPR_SINCE_CXX20 #endif // ABSL_INTERNAL_EMSCRIPTEN_VERSION combines Emscripten's three version macros |