Commit 87831365 by Abseil Team Committed by Copybara-Service

Marks absl::Span as view and borrowed_range, like std::span.

This allows containers that either optimize based on these
concepts or produce lifetime warnings based on them to
handle absl::Span appropriately. An example is Chromium's
base::span, which warns more aggressively about construction
from rvalues that are not borrowed ranges.

This only has an effect for codebases using C++20. While
many such codebases will presumably also be using std::span
directly, they may use absl::Span for backwards compat, or
compile against libraries that do so.

Also fixes lint's that fired when I tried to edit this.

PiperOrigin-RevId: 688552975
Change-Id: I603e04cd74d60ac6b65754ac73037d7f0ab457fe
parent 8c495b5b
......@@ -117,6 +117,7 @@ cc_library(
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
"//absl/algorithm",
"//absl/base:config",
"//absl/base:core_headers",
"//absl/base:nullability",
"//absl/base:throw_delegate",
......
......@@ -114,6 +114,7 @@ absl_cc_library(
${ABSL_DEFAULT_COPTS}
DEPS
absl::algorithm
absl::config
absl::core_headers
absl::nullability
absl::throw_delegate
......
......@@ -61,6 +61,7 @@
#include <utility>
#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/internal/throw_delegate.h"
#include "absl/base/macros.h"
#include "absl/base/nullability.h"
......@@ -72,6 +73,33 @@
namespace absl {
ABSL_NAMESPACE_BEGIN
template <typename T>
class Span;
ABSL_NAMESPACE_END
} // namespace absl
// If std::ranges is available, mark Span as satisfying the `view` and
// `borrowed_range` concepts, just like std::span.
#if !defined(__has_include)
#define __has_include(header) 0
#endif
#if __has_include(<version>)
#include <version> // NOLINT(misc-include-cleaner)
#endif
#if defined(__cpp_lib_ranges) && __cpp_lib_ranges >= 201911L
#include <ranges> // NOLINT(build/c++20)
template <typename T>
// NOLINTNEXTLINE(build/c++20)
inline constexpr bool std::ranges::enable_view<absl::Span<T>> = true;
template <typename T>
// NOLINTNEXTLINE(build/c++20)
inline constexpr bool std::ranges::enable_borrowed_range<absl::Span<T>> = true;
#endif
namespace absl {
ABSL_NAMESPACE_BEGIN
//------------------------------------------------------------------------------
// Span
//------------------------------------------------------------------------------
......@@ -187,6 +215,7 @@ class ABSL_ATTRIBUTE_VIEW Span {
using difference_type = ptrdiff_t;
using absl_internal_is_view = std::true_type;
// NOLINTNEXTLINE
static const size_type npos = ~(size_type(0));
constexpr Span() noexcept : Span(nullptr, 0) {}
......@@ -195,7 +224,7 @@ class ABSL_ATTRIBUTE_VIEW Span {
// Implicit conversion constructors
template <size_t N>
constexpr Span(T (&a)[N]) noexcept // NOLINT(runtime/explicit)
constexpr Span(T (&a)[N]) noexcept // NOLINT(google-explicit-constructor)
: Span(a, N) {}
// Explicit reference constructor for a mutable `Span<T>` type. Can be
......@@ -212,9 +241,8 @@ class ABSL_ATTRIBUTE_VIEW Span {
template <typename V, typename = EnableIfConvertibleFrom<V>,
typename = EnableIfValueIsConst<V>,
typename = span_internal::EnableIfNotIsView<V>>
constexpr Span(
const V& v
ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept // NOLINT(runtime/explicit)
// NOLINTNEXTLINE(google-explicit-constructor)
constexpr Span(const V& v ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept
: Span(span_internal::GetData(v), v.size()) {}
// Overloads of the above two functions that are only enabled for view types.
......@@ -229,7 +257,7 @@ class ABSL_ATTRIBUTE_VIEW Span {
template <typename V, typename = EnableIfConvertibleFrom<V>,
typename = EnableIfValueIsConst<V>,
span_internal::EnableIfIsView<V> = 0>
constexpr Span(const V& v) noexcept // NOLINT(runtime/explicit)
constexpr Span(const V& v) noexcept // NOLINT(google-explicit-constructor)
: Span(span_internal::GetData(v), v.size()) {}
// Implicit constructor from an initializer list, making it possible to pass a
......
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