mirror of
https://github.com/abseil/abseil-cpp.git
synced 2026-06-04 12:07:05 +08:00
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
This commit is contained in:
committed by
Copybara-Service
parent
a27662352e
commit
37ebde53cf
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -52,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"
|
||||
@@ -93,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_CONSTEXPR_SINCE_CXX17 ContainerIter<C> c_begin(C& c) {
|
||||
return begin(c);
|
||||
}
|
||||
|
||||
template <typename C>
|
||||
ContainerIter<C> c_end(C& c) {
|
||||
ABSL_CONSTEXPR_SINCE_CXX17 ContainerIter<C> c_end(C& c) {
|
||||
return end(c);
|
||||
}
|
||||
|
||||
@@ -146,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_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));
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
@@ -1160,4 +1162,13 @@ 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);
|
||||
}
|
||||
#endif // defined(ABSL_INTERNAL_CPLUSPLUS_LANG) &&
|
||||
// ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -941,6 +941,27 @@ 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
|
||||
#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
|
||||
// into an integer that can be compared against.
|
||||
#ifdef ABSL_INTERNAL_EMSCRIPTEN_VERSION
|
||||
|
||||
Reference in New Issue
Block a user