Skip to content

Commit

Permalink
Marks absl::Span as view and borrowed_range, like std::span.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Abseil Team authored and copybara-github committed Oct 22, 2024
1 parent 8c495b5 commit 8783136
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 5 deletions.
1 change: 1 addition & 0 deletions absl/types/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
1 change: 1 addition & 0 deletions absl/types/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ absl_cc_library(
${ABSL_DEFAULT_COPTS}
DEPS
absl::algorithm
absl::config
absl::core_headers
absl::nullability
absl::throw_delegate
Expand Down
38 changes: 33 additions & 5 deletions absl/types/span.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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
//------------------------------------------------------------------------------
Expand Down Expand Up @@ -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) {}
Expand All @@ -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
Expand All @@ -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.
Expand All @@ -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
Expand Down

0 comments on commit 8783136

Please sign in to comment.