Split implementations of raw_span from span.

Only raw_span<> will participate in BRP schemes. This is in keeping
with what Chromium has done to be performant.

Change-Id: I8aa34409dc012f818364f9ca2c173f9e0d67df28
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/117132
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
Reviewed-by: Thomas Sepez <tsepez@google.com>
diff --git a/core/fxcrt/pdfium_span_unittest.cpp b/core/fxcrt/pdfium_span_unittest.cpp
index 0228fb2..7626eea 100644
--- a/core/fxcrt/pdfium_span_unittest.cpp
+++ b/core/fxcrt/pdfium_span_unittest.cpp
@@ -4,6 +4,7 @@
 
 #include <vector>
 
+#include "core/fxcrt/raw_span.h"
 #include "core/fxcrt/span.h"
 #include "core/fxcrt/unowned_ptr.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -57,7 +58,7 @@
 namespace {
 
 void CreateDanglingSpan() {
-  pdfium::span<int> data_span;
+  pdfium::raw_span<int> data_span;
   {
     std::vector<int> data(4);
     data_span = pdfium::make_span(data);
diff --git a/core/fxcrt/span.h b/core/fxcrt/span.h
index d7ecc9d..0a2ce62 100644
--- a/core/fxcrt/span.h
+++ b/core/fxcrt/span.h
@@ -16,29 +16,17 @@
 
 #include "core/fxcrt/check.h"
 #include "core/fxcrt/compiler_specific.h"
+#include "core/fxcrt/unowned_ptr_exclusion.h"
 
 // SAFETY: TODO(crbug.com/pdfium/2085): this entire file is to be replaced
 // with the fully annotated one that is being prepared in base/.
 
-#if defined(PDF_USE_PARTITION_ALLOC)
-UNSAFE_BUFFERS_INCLUDE_BEGIN
-#include "partition_alloc/pointers/raw_ptr.h"
-UNSAFE_BUFFERS_INCLUDE_END
-#else
-#include "core/fxcrt/unowned_ptr_exclusion.h"
-#endif
-
 namespace pdfium {
 
 constexpr size_t dynamic_extent = static_cast<size_t>(-1);
 
-#if defined(PDF_USE_PARTITION_ALLOC)
-template <typename T>
-using DefaultSpanInternalPtr = raw_ptr<T, AllowPtrArithmetic>;
-#else
 template <typename T>
 using DefaultSpanInternalPtr = UNOWNED_PTR_EXCLUSION T*;
-#endif
 
 template <typename T,
           size_t Extent = dynamic_extent,
@@ -257,8 +245,13 @@
 
   // Conversions from spans of compatible types: this allows a span<T> to be
   // seamlessly used as a span<const T>, but not the other way around.
-  template <typename U, typename = internal::EnableIfLegalSpanConversion<U, T>>
-  constexpr span(const span<U>& other) : span(other.data(), other.size()) {}
+  template <typename U,
+            size_t M,
+            typename R,
+            typename = internal::EnableIfLegalSpanConversion<U, T>>
+  constexpr span(const span<U, M, R>& other)
+      : span(other.data(), other.size()) {}
+
   span& operator=(const span& other) noexcept {
     if (this != &other) {
       data_ = other.data_;
@@ -338,25 +331,29 @@
 };
 
 // [span.objectrep], views of object representation
-template <typename T>
-span<const uint8_t> as_bytes(span<T> s) noexcept {
+template <typename T, size_t N, typename P>
+span<const uint8_t> as_bytes(span<T, N, P> s) noexcept {
   return {reinterpret_cast<const uint8_t*>(s.data()), s.size_bytes()};
 }
 
 template <typename T,
+          size_t N,
+          typename P,
           typename U = typename std::enable_if<!std::is_const<T>::value>::type>
-span<uint8_t> as_writable_bytes(span<T> s) noexcept {
+span<uint8_t> as_writable_bytes(span<T, N, P> s) noexcept {
   return {reinterpret_cast<uint8_t*>(s.data()), s.size_bytes()};
 }
 
-template <typename T>
-span<const char> as_chars(span<T> s) noexcept {
+template <typename T, size_t N, typename P>
+span<const char> as_chars(span<T, N, P> s) noexcept {
   return {reinterpret_cast<const char*>(s.data()), s.size_bytes()};
 }
 
 template <typename T,
+          size_t N,
+          typename P,
           typename U = typename std::enable_if<!std::is_const<T>::value>::type>
-span<char> as_writable_chars(span<T> s) noexcept {
+span<char> as_writable_chars(span<T, N, P> s) noexcept {
   return {reinterpret_cast<char*>(s.data()), s.size_bytes()};
 }
 
diff --git a/core/fxcrt/span_util.h b/core/fxcrt/span_util.h
index 65f32a0..936d956 100644
--- a/core/fxcrt/span_util.h
+++ b/core/fxcrt/span_util.h
@@ -18,12 +18,17 @@
 
 // Bounds-checked byte-for-byte copies from spans into spans. Returns a
 // span describing the remaining portion of the destination span.
-template <typename T,
-          typename U,
-          typename = std::enable_if_t<sizeof(T) == sizeof(U) &&
-                                      std::is_trivially_copyable_v<T> &&
-                                      std::is_trivially_copyable_v<U>>>
-pdfium::span<T> spancpy(pdfium::span<T> dst, pdfium::span<U> src) {
+template <typename T1,
+          typename T2,
+          size_t N1,
+          size_t N2,
+          typename P1,
+          typename P2,
+          typename = std::enable_if_t<sizeof(T1) == sizeof(T2) &&
+                                      std::is_trivially_copyable_v<T1> &&
+                                      std::is_trivially_copyable_v<T2>>>
+inline pdfium::span<T1> spancpy(pdfium::span<T1, N1, P1> dst,
+                                pdfium::span<T2, N2, P2> src) {
   CHECK_GE(dst.size(), src.size());
   FXSYS_memcpy(dst.data(), src.data(), src.size_bytes());
   return dst.subspan(src.size());
@@ -31,12 +36,17 @@
 
 // Bounds-checked byte-for-byte moves from spans into spans. Returns a
 // span describing the remaining portion of the destination span.
-template <typename T,
-          typename U,
-          typename = std::enable_if_t<sizeof(T) == sizeof(U) &&
-                                      std::is_trivially_copyable_v<T> &&
-                                      std::is_trivially_copyable_v<U>>>
-pdfium::span<T> spanmove(pdfium::span<T> dst, pdfium::span<U> src) {
+template <typename T1,
+          typename T2,
+          size_t N1,
+          size_t N2,
+          typename P1,
+          typename P2,
+          typename = std::enable_if_t<sizeof(T1) == sizeof(T2) &&
+                                      std::is_trivially_copyable_v<T1> &&
+                                      std::is_trivially_copyable_v<T2>>>
+pdfium::span<T1> spanmove(pdfium::span<T1, N1, P1> dst,
+                          pdfium::span<T2, N2, P2> src) {
   CHECK_GE(dst.size(), src.size());
   FXSYS_memmove(dst.data(), src.data(), src.size_bytes());
   return dst.subspan(src.size());
@@ -44,28 +54,36 @@
 
 // Bounds-checked sets into spans.
 template <typename T,
+          size_t N,
+          typename P,
           typename = std::enable_if_t<std::is_trivially_constructible_v<T> &&
                                       std::is_trivially_destructible_v<T>>>
-void spanset(pdfium::span<T> dst, uint8_t val) {
+void spanset(pdfium::span<T, N, P> dst, uint8_t val) {
   FXSYS_memset(dst.data(), val, dst.size_bytes());
 }
 
 // Bounds-checked zeroing of spans.
 template <typename T,
+          size_t N,
+          typename P,
           typename = std::enable_if_t<std::is_trivially_constructible_v<T> &&
                                       std::is_trivially_destructible_v<T>>>
-void spanclr(pdfium::span<T> dst) {
+void spanclr(pdfium::span<T, N, P> dst) {
   FXSYS_memset(dst.data(), 0, dst.size_bytes());
 }
 
 // Bounds-checked byte-for-byte equality of same-sized spans. This is
 // helpful because span does not (yet) have an operator==().
-template <typename T,
-          typename U,
-          typename = std::enable_if_t<sizeof(T) == sizeof(U) &&
-                                      std::is_trivially_copyable_v<T> &&
-                                      std::is_trivially_copyable_v<U>>>
-bool span_equals(pdfium::span<T> s1, pdfium::span<U> s2) {
+template <typename T1,
+          typename T2,
+          size_t N1,
+          size_t N2,
+          typename P1,
+          typename P2,
+          typename = std::enable_if_t<sizeof(T1) == sizeof(T2) &&
+                                      std::is_trivially_copyable_v<T1> &&
+                                      std::is_trivially_copyable_v<T2>>>
+bool span_equals(pdfium::span<T1, N1, P1> s1, pdfium::span<T2, N2, P2> s2) {
   return s1.size_bytes() == s2.size_bytes() &&
          FXSYS_memcmp(s1.data(), s2.data(), s1.size_bytes()) == 0;
 }