Skip to content

Commit 37ebde5

Browse files
Abseil Teamcopybara-github
authored andcommitted
Make c_begin, c_end, and c_distance conditionally constexpr.
This allows them to be used in constexpr expressions, such as the following: ``` constexpr int distance = absl::c_distance(std::array<int, 3>()); ``` Requires at least C++17 to be constexpr. PiperOrigin-RevId: 648435141 Change-Id: I8136e351a6dc4c25f06ef895fb449f4f11048480
1 parent a276623 commit 37ebde5

File tree

5 files changed

+44
-6
lines changed

5 files changed

+44
-6
lines changed

absl/algorithm/BUILD.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ cc_library(
6565
linkopts = ABSL_DEFAULT_LINKOPTS,
6666
deps = [
6767
":algorithm",
68+
"//absl/base:config",
6869
"//absl/base:core_headers",
6970
"//absl/base:nullability",
7071
"//absl/meta:type_traits",
@@ -79,6 +80,7 @@ cc_test(
7980
deps = [
8081
":container",
8182
"//absl/base",
83+
"//absl/base:config",
8284
"//absl/base:core_headers",
8385
"//absl/memory",
8486
"//absl/types:span",

absl/algorithm/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ absl_cc_library(
4848
${ABSL_DEFAULT_COPTS}
4949
DEPS
5050
absl::algorithm
51+
absl::config
5152
absl::core_headers
5253
absl::meta
5354
absl::nullability
@@ -64,6 +65,7 @@ absl_cc_test(
6465
DEPS
6566
absl::algorithm_container
6667
absl::base
68+
absl::config
6769
absl::core_headers
6870
absl::memory
6971
absl::span

absl/algorithm/container.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
#include <vector>
5353

5454
#include "absl/algorithm/algorithm.h"
55+
#include "absl/base/config.h"
5556
#include "absl/base/macros.h"
5657
#include "absl/base/nullability.h"
5758
#include "absl/meta/type_traits.h"
@@ -93,17 +94,17 @@ using ContainerPointerType =
9394
// using std::end;
9495
// std::foo(begin(c), end(c));
9596
// becomes
96-
// std::foo(container_algorithm_internal::begin(c),
97-
// container_algorithm_internal::end(c));
97+
// std::foo(container_algorithm_internal::c_begin(c),
98+
// container_algorithm_internal::c_end(c));
9899
// These are meant for internal use only.
99100

100101
template <typename C>
101-
ContainerIter<C> c_begin(C& c) {
102+
ABSL_CONSTEXPR_SINCE_CXX17 ContainerIter<C> c_begin(C& c) {
102103
return begin(c);
103104
}
104105

105106
template <typename C>
106-
ContainerIter<C> c_end(C& c) {
107+
ABSL_CONSTEXPR_SINCE_CXX17 ContainerIter<C> c_end(C& c) {
107108
return end(c);
108109
}
109110

@@ -146,8 +147,9 @@ bool c_linear_search(const C& c, EqualityComparable&& value) {
146147
// Container-based version of the <iterator> `std::distance()` function to
147148
// return the number of elements within a container.
148149
template <typename C>
149-
container_algorithm_internal::ContainerDifferenceType<const C> c_distance(
150-
const C& c) {
150+
ABSL_CONSTEXPR_SINCE_CXX17
151+
container_algorithm_internal::ContainerDifferenceType<const C>
152+
c_distance(const C& c) {
151153
return std::distance(container_algorithm_internal::c_begin(c),
152154
container_algorithm_internal::c_end(c));
153155
}

absl/algorithm/container_test.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "absl/algorithm/container.h"
1616

1717
#include <algorithm>
18+
#include <array>
1819
#include <functional>
1920
#include <initializer_list>
2021
#include <iterator>
@@ -31,6 +32,7 @@
3132
#include "gmock/gmock.h"
3233
#include "gtest/gtest.h"
3334
#include "absl/base/casts.h"
35+
#include "absl/base/config.h"
3436
#include "absl/base/macros.h"
3537
#include "absl/memory/memory.h"
3638
#include "absl/types/span.h"
@@ -1160,4 +1162,13 @@ TEST(MutatingTest, PermutationOperations) {
11601162
EXPECT_EQ(initial, permuted);
11611163
}
11621164

1165+
#if defined(ABSL_INTERNAL_CPLUSPLUS_LANG) && \
1166+
ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L
1167+
TEST(ConstexprTest, Distance) {
1168+
// Works at compile time with constexpr containers.
1169+
static_assert(absl::c_distance(std::array<int, 3>()) == 3);
1170+
}
1171+
#endif // defined(ABSL_INTERNAL_CPLUSPLUS_LANG) &&
1172+
// ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L
1173+
11631174
} // namespace

absl/base/config.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -941,6 +941,27 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
941941
#define ABSL_HAVE_CONSTANT_EVALUATED 1
942942
#endif
943943

944+
// ABSL_CONSTEXPR_SINCE_CXXYY is used to conditionally define constexpr for
945+
// different C++ versions.
946+
#if defined(ABSL_INTERNAL_CPLUSPLUS_LANG) && \
947+
ABSL_INTERNAL_CPLUSPLUS_LANG >= 201402L
948+
#define ABSL_CONSTEXPR_SINCE_CXX14 constexpr
949+
#else
950+
#define ABSL_CONSTEXPR_SINCE_CXX14
951+
#endif
952+
#if defined(ABSL_INTERNAL_CPLUSPLUS_LANG) && \
953+
ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L
954+
#define ABSL_CONSTEXPR_SINCE_CXX17 constexpr
955+
#else
956+
#define ABSL_CONSTEXPR_SINCE_CXX17
957+
#endif
958+
#if defined(ABSL_INTERNAL_CPLUSPLUS_LANG) && \
959+
ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
960+
#define ABSL_CONSTEXPR_SINCE_CXX20 constexpr
961+
#else
962+
#define ABSL_CONSTEXPR_SINCE_CXX20
963+
#endif
964+
944965
// ABSL_INTERNAL_EMSCRIPTEN_VERSION combines Emscripten's three version macros
945966
// into an integer that can be compared against.
946967
#ifdef ABSL_INTERNAL_EMSCRIPTEN_VERSION

0 commit comments

Comments
 (0)