From a7f937543e0988fe834ff577b51cc33633262b53 Mon Sep 17 00:00:00 2001
From: Peter Kasting <pkasting@chromium.org>
Date: Thu, 24 Oct 2024 22:15:40 +0000
Subject: [PATCH] Move span opt-ins for enable_view/enable_borrowed_range above
 def.

I don't believe this has a practical effect right now, but it is safer,
and it will have a practical effect in the future as I'm planning to
modify how the span range constructors work; this will ensure any
constraints that check whether base::span is a borrowed range will give
the correct answer.

This also fixes the oversight that we omitted these from the PRESUBMIT
allowlist; understandably, since they're not listed in any of the
categories on the various cppreference.com ranges pages. I had to do
this to allow this change to pass PRESUBMIT :)

Bug: 364987728
Change-Id: I8ff30b686350797a868bf15b250172aa0c24342f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5962876
Auto-Submit: Peter Kasting <pkasting@chromium.org>
Commit-Queue: Daniel Cheng <dcheng@chromium.org>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1373610}
---
 PRESUBMIT.py           |  4 ++++
 base/containers/span.h | 20 +++++++++++++-------
 2 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index 51bb4461e40db..84ef538437578 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -1309,6 +1309,10 @@ _BANNED_CPP_FUNCTIONS: Sequence[BanRule] = (
             # Banned: Views
             # Banned: Range factories
             # Banned: Range adaptors
+            # Incidentally listed on
+            # https://en.cppreference.com/w/cpp/header/ranges:
+            'enable_borrowed_range',
+            'enable_view',
             # From https://en.cppreference.com/w/cpp/algorithm/ranges:
             # Constrained algorithms: non-modifying sequence operations
             'all_of',
diff --git a/base/containers/span.h b/base/containers/span.h
index 21f9d39b915c6..a599327525a7b 100644
--- a/base/containers/span.h
+++ b/base/containers/span.h
@@ -37,6 +37,19 @@ template <typename T,
           typename InternalPtrType = T*>
 class span;
 
+}  // namespace base
+
+// Mark `span` as satisfying the `view` and `borrowed_range` concepts. This
+// should be done before the definition of `span`, so that any inlined calls to
+// range functionality use the correct specializations.
+template <typename T, size_t N, typename Ptr>
+inline constexpr bool std::ranges::enable_view<base::span<T, N, Ptr>> = true;
+template <typename T, size_t N, typename Ptr>
+inline constexpr bool
+    std::ranges::enable_borrowed_range<base::span<T, N, Ptr>> = true;
+
+namespace base {
+
 namespace internal {
 
 template <typename From, typename To>
@@ -1757,13 +1770,6 @@ constexpr std::ostream& operator<<(std::ostream& l, span<T, N> r) {
 
 }  // namespace base
 
-template <typename T, size_t N, typename Ptr>
-inline constexpr bool
-    std::ranges::enable_borrowed_range<base::span<T, N, Ptr>> = true;
-
-template <typename T, size_t N, typename Ptr>
-inline constexpr bool std::ranges::enable_view<base::span<T, N, Ptr>> = true;
-
 // EXTENT returns the size of any type that can be converted to a |base::span|
 // with definite extent, i.e. everything that is a contiguous storage of some
 // sort with static size. Specifically, this works for std::array in a constexpr