Commit 37ebde53 by Abseil Team Committed by Copybara-Service

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
parent a2766235
...@@ -65,6 +65,7 @@ cc_library( ...@@ -65,6 +65,7 @@ cc_library(
linkopts = ABSL_DEFAULT_LINKOPTS, linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [ deps = [
":algorithm", ":algorithm",
"//absl/base:config",
"//absl/base:core_headers", "//absl/base:core_headers",
"//absl/base:nullability", "//absl/base:nullability",
"//absl/meta:type_traits", "//absl/meta:type_traits",
...@@ -79,6 +80,7 @@ cc_test( ...@@ -79,6 +80,7 @@ cc_test(
deps = [ deps = [
":container", ":container",
"//absl/base", "//absl/base",
"//absl/base:config",
"//absl/base:core_headers", "//absl/base:core_headers",
"//absl/memory", "//absl/memory",
"//absl/types:span", "//absl/types:span",
......
...@@ -48,6 +48,7 @@ absl_cc_library( ...@@ -48,6 +48,7 @@ absl_cc_library(
${ABSL_DEFAULT_COPTS} ${ABSL_DEFAULT_COPTS}
DEPS DEPS
absl::algorithm absl::algorithm
absl::config
absl::core_headers absl::core_headers
absl::meta absl::meta
absl::nullability absl::nullability
...@@ -64,6 +65,7 @@ absl_cc_test( ...@@ -64,6 +65,7 @@ absl_cc_test(
DEPS DEPS
absl::algorithm_container absl::algorithm_container
absl::base absl::base
absl::config
absl::core_headers absl::core_headers
absl::memory absl::memory
absl::span absl::span
......
...@@ -52,6 +52,7 @@ ...@@ -52,6 +52,7 @@
#include <vector> #include <vector>
#include "absl/algorithm/algorithm.h" #include "absl/algorithm/algorithm.h"
#include "absl/base/config.h"
#include "absl/base/macros.h" #include "absl/base/macros.h"
#include "absl/base/nullability.h" #include "absl/base/nullability.h"
#include "absl/meta/type_traits.h" #include "absl/meta/type_traits.h"
...@@ -93,17 +94,17 @@ using ContainerPointerType = ...@@ -93,17 +94,17 @@ using ContainerPointerType =
// using std::end; // using std::end;
// std::foo(begin(c), end(c)); // std::foo(begin(c), end(c));
// becomes // becomes
// std::foo(container_algorithm_internal::begin(c), // std::foo(container_algorithm_internal::c_begin(c),
// container_algorithm_internal::end(c)); // container_algorithm_internal::c_end(c));
// These are meant for internal use only. // These are meant for internal use only.
template <typename C> template <typename C>
ContainerIter<C> c_begin(C& c) { ABSL_CONSTEXPR_SINCE_CXX17 ContainerIter<C> c_begin(C& c) {
return begin(c); return begin(c);
} }
template <typename C> template <typename C>
ContainerIter<C> c_end(C& c) { ABSL_CONSTEXPR_SINCE_CXX17 ContainerIter<C> c_end(C& c) {
return end(c); return end(c);
} }
...@@ -146,8 +147,9 @@ bool c_linear_search(const C& c, EqualityComparable&& value) { ...@@ -146,8 +147,9 @@ bool c_linear_search(const C& c, EqualityComparable&& value) {
// Container-based version of the <iterator> `std::distance()` function to // Container-based version of the <iterator> `std::distance()` function to
// return the number of elements within a container. // return the number of elements within a container.
template <typename C> template <typename C>
container_algorithm_internal::ContainerDifferenceType<const C> c_distance( ABSL_CONSTEXPR_SINCE_CXX17
const C& c) { container_algorithm_internal::ContainerDifferenceType<const C>
c_distance(const C& c) {
return std::distance(container_algorithm_internal::c_begin(c), return std::distance(container_algorithm_internal::c_begin(c),
container_algorithm_internal::c_end(c)); container_algorithm_internal::c_end(c));
} }
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "absl/algorithm/container.h" #include "absl/algorithm/container.h"
#include <algorithm> #include <algorithm>
#include <array>
#include <functional> #include <functional>
#include <initializer_list> #include <initializer_list>
#include <iterator> #include <iterator>
...@@ -31,6 +32,7 @@ ...@@ -31,6 +32,7 @@
#include "gmock/gmock.h" #include "gmock/gmock.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "absl/base/casts.h" #include "absl/base/casts.h"
#include "absl/base/config.h"
#include "absl/base/macros.h" #include "absl/base/macros.h"
#include "absl/memory/memory.h" #include "absl/memory/memory.h"
#include "absl/types/span.h" #include "absl/types/span.h"
...@@ -1160,4 +1162,13 @@ TEST(MutatingTest, PermutationOperations) { ...@@ -1160,4 +1162,13 @@ TEST(MutatingTest, PermutationOperations) {
EXPECT_EQ(initial, permuted); 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);
}
#endif // defined(ABSL_INTERNAL_CPLUSPLUS_LANG) &&
// ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L
} // namespace } // namespace
...@@ -941,6 +941,27 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' || ...@@ -941,6 +941,27 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
#define ABSL_HAVE_CONSTANT_EVALUATED 1 #define ABSL_HAVE_CONSTANT_EVALUATED 1
#endif #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
#if defined(ABSL_INTERNAL_CPLUSPLUS_LANG) && \
ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L
#define ABSL_CONSTEXPR_SINCE_CXX17 constexpr
#else
#define ABSL_CONSTEXPR_SINCE_CXX17
#endif
#if defined(ABSL_INTERNAL_CPLUSPLUS_LANG) && \
ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L
#define ABSL_CONSTEXPR_SINCE_CXX20 constexpr
#else
#define ABSL_CONSTEXPR_SINCE_CXX20
#endif
// ABSL_INTERNAL_EMSCRIPTEN_VERSION combines Emscripten's three version macros // ABSL_INTERNAL_EMSCRIPTEN_VERSION combines Emscripten's three version macros
// into an integer that can be compared against. // into an integer that can be compared against.
#ifdef ABSL_INTERNAL_EMSCRIPTEN_VERSION #ifdef ABSL_INTERNAL_EMSCRIPTEN_VERSION
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment