summaryrefslogtreecommitdiff
path: root/absl
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2024-07-03 22:07:51 -0700
committerGravatar Copybara-Service <copybara-worker@google.com>2024-07-03 22:08:39 -0700
commit074a32af66648c74dd0104e251e44ace5b59f7fa (patch)
treea7ffd02d87db9a565627000ac9afbb59fa32d974 /absl
parenteb46a63d77d7d1c1d30e2c9243099f89c629003c (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.h36
-rw-r--r--absl/algorithm/container_test.cc36
-rw-r--r--absl/base/config.h24
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