xref: /aosp_15_r20/external/pdfium/third_party/base/containers/span.h (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1*3ac0a46fSAndroid Build Coastguard Worker // Copyright 2017 The Chromium Authors. All rights reserved.
2*3ac0a46fSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*3ac0a46fSAndroid Build Coastguard Worker // found in the LICENSE file.
4*3ac0a46fSAndroid Build Coastguard Worker 
5*3ac0a46fSAndroid Build Coastguard Worker #ifndef THIRD_PARTY_BASE_CONTAINERS_SPAN_H_
6*3ac0a46fSAndroid Build Coastguard Worker #define THIRD_PARTY_BASE_CONTAINERS_SPAN_H_
7*3ac0a46fSAndroid Build Coastguard Worker 
8*3ac0a46fSAndroid Build Coastguard Worker #include <stddef.h>
9*3ac0a46fSAndroid Build Coastguard Worker 
10*3ac0a46fSAndroid Build Coastguard Worker #include <algorithm>
11*3ac0a46fSAndroid Build Coastguard Worker #include <array>
12*3ac0a46fSAndroid Build Coastguard Worker #include <iterator>
13*3ac0a46fSAndroid Build Coastguard Worker #include <type_traits>
14*3ac0a46fSAndroid Build Coastguard Worker #include <utility>
15*3ac0a46fSAndroid Build Coastguard Worker 
16*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/unowned_ptr.h"
17*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/base/check.h"
18*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/base/compiler_specific.h"
19*3ac0a46fSAndroid Build Coastguard Worker 
20*3ac0a46fSAndroid Build Coastguard Worker namespace pdfium {
21*3ac0a46fSAndroid Build Coastguard Worker 
22*3ac0a46fSAndroid Build Coastguard Worker constexpr size_t dynamic_extent = static_cast<size_t>(-1);
23*3ac0a46fSAndroid Build Coastguard Worker 
24*3ac0a46fSAndroid Build Coastguard Worker template <typename T>
25*3ac0a46fSAndroid Build Coastguard Worker class span;
26*3ac0a46fSAndroid Build Coastguard Worker 
27*3ac0a46fSAndroid Build Coastguard Worker namespace internal {
28*3ac0a46fSAndroid Build Coastguard Worker 
29*3ac0a46fSAndroid Build Coastguard Worker template <typename T>
30*3ac0a46fSAndroid Build Coastguard Worker struct IsSpanImpl : std::false_type {};
31*3ac0a46fSAndroid Build Coastguard Worker 
32*3ac0a46fSAndroid Build Coastguard Worker template <typename T>
33*3ac0a46fSAndroid Build Coastguard Worker struct IsSpanImpl<span<T>> : std::true_type {};
34*3ac0a46fSAndroid Build Coastguard Worker 
35*3ac0a46fSAndroid Build Coastguard Worker template <typename T>
36*3ac0a46fSAndroid Build Coastguard Worker using IsSpan = IsSpanImpl<typename std::decay<T>::type>;
37*3ac0a46fSAndroid Build Coastguard Worker 
38*3ac0a46fSAndroid Build Coastguard Worker template <typename T>
39*3ac0a46fSAndroid Build Coastguard Worker struct IsStdArrayImpl : std::false_type {};
40*3ac0a46fSAndroid Build Coastguard Worker 
41*3ac0a46fSAndroid Build Coastguard Worker template <typename T, size_t N>
42*3ac0a46fSAndroid Build Coastguard Worker struct IsStdArrayImpl<std::array<T, N>> : std::true_type {};
43*3ac0a46fSAndroid Build Coastguard Worker 
44*3ac0a46fSAndroid Build Coastguard Worker template <typename T>
45*3ac0a46fSAndroid Build Coastguard Worker using IsStdArray = IsStdArrayImpl<typename std::decay<T>::type>;
46*3ac0a46fSAndroid Build Coastguard Worker 
47*3ac0a46fSAndroid Build Coastguard Worker template <typename From, typename To>
48*3ac0a46fSAndroid Build Coastguard Worker using IsLegalSpanConversion = std::is_convertible<From*, To*>;
49*3ac0a46fSAndroid Build Coastguard Worker 
50*3ac0a46fSAndroid Build Coastguard Worker template <typename Container, typename T>
51*3ac0a46fSAndroid Build Coastguard Worker using ContainerHasConvertibleData =
52*3ac0a46fSAndroid Build Coastguard Worker     IsLegalSpanConversion<typename std::remove_pointer<decltype(
53*3ac0a46fSAndroid Build Coastguard Worker                               std::declval<Container>().data())>::type,
54*3ac0a46fSAndroid Build Coastguard Worker                           T>;
55*3ac0a46fSAndroid Build Coastguard Worker template <typename Container>
56*3ac0a46fSAndroid Build Coastguard Worker using ContainerHasIntegralSize =
57*3ac0a46fSAndroid Build Coastguard Worker     std::is_integral<decltype(std::declval<Container>().size())>;
58*3ac0a46fSAndroid Build Coastguard Worker 
59*3ac0a46fSAndroid Build Coastguard Worker template <typename From, typename To>
60*3ac0a46fSAndroid Build Coastguard Worker using EnableIfLegalSpanConversion =
61*3ac0a46fSAndroid Build Coastguard Worker     typename std::enable_if<IsLegalSpanConversion<From, To>::value>::type;
62*3ac0a46fSAndroid Build Coastguard Worker 
63*3ac0a46fSAndroid Build Coastguard Worker // SFINAE check if Container can be converted to a span<T>. Note that the
64*3ac0a46fSAndroid Build Coastguard Worker // implementation details of this check differ slightly from the requirements in
65*3ac0a46fSAndroid Build Coastguard Worker // the working group proposal: in particular, the proposal also requires that
66*3ac0a46fSAndroid Build Coastguard Worker // the container conversion constructor participate in overload resolution only
67*3ac0a46fSAndroid Build Coastguard Worker // if two additional conditions are true:
68*3ac0a46fSAndroid Build Coastguard Worker //
69*3ac0a46fSAndroid Build Coastguard Worker //   1. Container implements operator[].
70*3ac0a46fSAndroid Build Coastguard Worker //   2. Container::value_type matches remove_const_t<element_type>.
71*3ac0a46fSAndroid Build Coastguard Worker //
72*3ac0a46fSAndroid Build Coastguard Worker // The requirements are relaxed slightly here: in particular, not requiring (2)
73*3ac0a46fSAndroid Build Coastguard Worker // means that an immutable span can be easily constructed from a mutable
74*3ac0a46fSAndroid Build Coastguard Worker // container.
75*3ac0a46fSAndroid Build Coastguard Worker template <typename Container, typename T>
76*3ac0a46fSAndroid Build Coastguard Worker using EnableIfSpanCompatibleContainer =
77*3ac0a46fSAndroid Build Coastguard Worker     typename std::enable_if<!internal::IsSpan<Container>::value &&
78*3ac0a46fSAndroid Build Coastguard Worker                             !internal::IsStdArray<Container>::value &&
79*3ac0a46fSAndroid Build Coastguard Worker                             ContainerHasConvertibleData<Container, T>::value &&
80*3ac0a46fSAndroid Build Coastguard Worker                             ContainerHasIntegralSize<Container>::value>::type;
81*3ac0a46fSAndroid Build Coastguard Worker 
82*3ac0a46fSAndroid Build Coastguard Worker template <typename Container, typename T>
83*3ac0a46fSAndroid Build Coastguard Worker using EnableIfConstSpanCompatibleContainer =
84*3ac0a46fSAndroid Build Coastguard Worker     typename std::enable_if<std::is_const<T>::value &&
85*3ac0a46fSAndroid Build Coastguard Worker                             !internal::IsSpan<Container>::value &&
86*3ac0a46fSAndroid Build Coastguard Worker                             !internal::IsStdArray<Container>::value &&
87*3ac0a46fSAndroid Build Coastguard Worker                             ContainerHasConvertibleData<Container, T>::value &&
88*3ac0a46fSAndroid Build Coastguard Worker                             ContainerHasIntegralSize<Container>::value>::type;
89*3ac0a46fSAndroid Build Coastguard Worker 
90*3ac0a46fSAndroid Build Coastguard Worker }  // namespace internal
91*3ac0a46fSAndroid Build Coastguard Worker 
92*3ac0a46fSAndroid Build Coastguard Worker // A span is a value type that represents an array of elements of type T. Since
93*3ac0a46fSAndroid Build Coastguard Worker // it only consists of a pointer to memory with an associated size, it is very
94*3ac0a46fSAndroid Build Coastguard Worker // light-weight. It is cheap to construct, copy, move and use spans, so that
95*3ac0a46fSAndroid Build Coastguard Worker // users are encouraged to use it as a pass-by-value parameter. A span does not
96*3ac0a46fSAndroid Build Coastguard Worker // own the underlying memory, so care must be taken to ensure that a span does
97*3ac0a46fSAndroid Build Coastguard Worker // not outlive the backing store.
98*3ac0a46fSAndroid Build Coastguard Worker //
99*3ac0a46fSAndroid Build Coastguard Worker // span is somewhat analogous to StringPiece, but with arbitrary element types,
100*3ac0a46fSAndroid Build Coastguard Worker // allowing mutation if T is non-const.
101*3ac0a46fSAndroid Build Coastguard Worker //
102*3ac0a46fSAndroid Build Coastguard Worker // span is implicitly convertible from C++ arrays, as well as most [1]
103*3ac0a46fSAndroid Build Coastguard Worker // container-like types that provide a data() and size() method (such as
104*3ac0a46fSAndroid Build Coastguard Worker // std::vector<T>). A mutable span<T> can also be implicitly converted to an
105*3ac0a46fSAndroid Build Coastguard Worker // immutable span<const T>.
106*3ac0a46fSAndroid Build Coastguard Worker //
107*3ac0a46fSAndroid Build Coastguard Worker // Consider using a span for functions that take a data pointer and size
108*3ac0a46fSAndroid Build Coastguard Worker // parameter: it allows the function to still act on an array-like type, while
109*3ac0a46fSAndroid Build Coastguard Worker // allowing the caller code to be a bit more concise.
110*3ac0a46fSAndroid Build Coastguard Worker //
111*3ac0a46fSAndroid Build Coastguard Worker // For read-only data access pass a span<const T>: the caller can supply either
112*3ac0a46fSAndroid Build Coastguard Worker // a span<const T> or a span<T>, while the callee will have a read-only view.
113*3ac0a46fSAndroid Build Coastguard Worker // For read-write access a mutable span<T> is required.
114*3ac0a46fSAndroid Build Coastguard Worker //
115*3ac0a46fSAndroid Build Coastguard Worker // Without span:
116*3ac0a46fSAndroid Build Coastguard Worker //   Read-Only:
117*3ac0a46fSAndroid Build Coastguard Worker //     // std::string HexEncode(const uint8_t* data, size_t size);
118*3ac0a46fSAndroid Build Coastguard Worker //     std::vector<uint8_t> data_buffer = GenerateData();
119*3ac0a46fSAndroid Build Coastguard Worker //     std::string r = HexEncode(data_buffer.data(), data_buffer.size());
120*3ac0a46fSAndroid Build Coastguard Worker //
121*3ac0a46fSAndroid Build Coastguard Worker //  Mutable:
122*3ac0a46fSAndroid Build Coastguard Worker //     // ssize_t SafeSNPrintf(char* buf, size_t N, const char* fmt, Args...);
123*3ac0a46fSAndroid Build Coastguard Worker //     char str_buffer[100];
124*3ac0a46fSAndroid Build Coastguard Worker //     SafeSNPrintf(str_buffer, sizeof(str_buffer), "Pi ~= %lf", 3.14);
125*3ac0a46fSAndroid Build Coastguard Worker //
126*3ac0a46fSAndroid Build Coastguard Worker // With span:
127*3ac0a46fSAndroid Build Coastguard Worker //   Read-Only:
128*3ac0a46fSAndroid Build Coastguard Worker //     // std::string HexEncode(base::span<const uint8_t> data);
129*3ac0a46fSAndroid Build Coastguard Worker //     std::vector<uint8_t> data_buffer = GenerateData();
130*3ac0a46fSAndroid Build Coastguard Worker //     std::string r = HexEncode(data_buffer);
131*3ac0a46fSAndroid Build Coastguard Worker //
132*3ac0a46fSAndroid Build Coastguard Worker //  Mutable:
133*3ac0a46fSAndroid Build Coastguard Worker //     // ssize_t SafeSNPrintf(base::span<char>, const char* fmt, Args...);
134*3ac0a46fSAndroid Build Coastguard Worker //     char str_buffer[100];
135*3ac0a46fSAndroid Build Coastguard Worker //     SafeSNPrintf(str_buffer, "Pi ~= %lf", 3.14);
136*3ac0a46fSAndroid Build Coastguard Worker //
137*3ac0a46fSAndroid Build Coastguard Worker // Spans with "const" and pointers
138*3ac0a46fSAndroid Build Coastguard Worker // -------------------------------
139*3ac0a46fSAndroid Build Coastguard Worker //
140*3ac0a46fSAndroid Build Coastguard Worker // Const and pointers can get confusing. Here are vectors of pointers and their
141*3ac0a46fSAndroid Build Coastguard Worker // corresponding spans (you can always make the span "more const" too):
142*3ac0a46fSAndroid Build Coastguard Worker //
143*3ac0a46fSAndroid Build Coastguard Worker //   const std::vector<int*>        =>  base::span<int* const>
144*3ac0a46fSAndroid Build Coastguard Worker //   std::vector<const int*>        =>  base::span<const int*>
145*3ac0a46fSAndroid Build Coastguard Worker //   const std::vector<const int*>  =>  base::span<const int* const>
146*3ac0a46fSAndroid Build Coastguard Worker //
147*3ac0a46fSAndroid Build Coastguard Worker // Differences from the working group proposal
148*3ac0a46fSAndroid Build Coastguard Worker // -------------------------------------------
149*3ac0a46fSAndroid Build Coastguard Worker //
150*3ac0a46fSAndroid Build Coastguard Worker // https://wg21.link/P0122 is the latest working group proposal, Chromium
151*3ac0a46fSAndroid Build Coastguard Worker // currently implements R6. The biggest difference is span does not support a
152*3ac0a46fSAndroid Build Coastguard Worker // static extent template parameter. Other differences are documented in
153*3ac0a46fSAndroid Build Coastguard Worker // subsections below.
154*3ac0a46fSAndroid Build Coastguard Worker //
155*3ac0a46fSAndroid Build Coastguard Worker // Differences in constants and types:
156*3ac0a46fSAndroid Build Coastguard Worker // - no element_type type alias
157*3ac0a46fSAndroid Build Coastguard Worker // - no index_type type alias
158*3ac0a46fSAndroid Build Coastguard Worker // - no different_type type alias
159*3ac0a46fSAndroid Build Coastguard Worker // - no extent constant
160*3ac0a46fSAndroid Build Coastguard Worker //
161*3ac0a46fSAndroid Build Coastguard Worker // Differences from [span.cons]:
162*3ac0a46fSAndroid Build Coastguard Worker // - no constructor from a pointer range
163*3ac0a46fSAndroid Build Coastguard Worker //
164*3ac0a46fSAndroid Build Coastguard Worker // Differences from [span.sub]:
165*3ac0a46fSAndroid Build Coastguard Worker // - no templated first()
166*3ac0a46fSAndroid Build Coastguard Worker // - no templated last()
167*3ac0a46fSAndroid Build Coastguard Worker // - no templated subspan()
168*3ac0a46fSAndroid Build Coastguard Worker // - using size_t instead of ptrdiff_t for indexing
169*3ac0a46fSAndroid Build Coastguard Worker //
170*3ac0a46fSAndroid Build Coastguard Worker // Differences from [span.obs]:
171*3ac0a46fSAndroid Build Coastguard Worker // - using size_t instead of ptrdiff_t to represent size()
172*3ac0a46fSAndroid Build Coastguard Worker //
173*3ac0a46fSAndroid Build Coastguard Worker // Differences from [span.elem]:
174*3ac0a46fSAndroid Build Coastguard Worker // - no operator ()()
175*3ac0a46fSAndroid Build Coastguard Worker // - using size_t instead of ptrdiff_t for indexing
176*3ac0a46fSAndroid Build Coastguard Worker 
177*3ac0a46fSAndroid Build Coastguard Worker // [span], class template span
178*3ac0a46fSAndroid Build Coastguard Worker template <typename T>
179*3ac0a46fSAndroid Build Coastguard Worker class TRIVIAL_ABI GSL_POINTER span {
180*3ac0a46fSAndroid Build Coastguard Worker  public:
181*3ac0a46fSAndroid Build Coastguard Worker   using value_type = typename std::remove_cv<T>::type;
182*3ac0a46fSAndroid Build Coastguard Worker   using pointer = T*;
183*3ac0a46fSAndroid Build Coastguard Worker   using reference = T&;
184*3ac0a46fSAndroid Build Coastguard Worker   using iterator = T*;
185*3ac0a46fSAndroid Build Coastguard Worker   using const_iterator = const T*;
186*3ac0a46fSAndroid Build Coastguard Worker   using reverse_iterator = std::reverse_iterator<iterator>;
187*3ac0a46fSAndroid Build Coastguard Worker   using const_reverse_iterator = std::reverse_iterator<const_iterator>;
188*3ac0a46fSAndroid Build Coastguard Worker 
189*3ac0a46fSAndroid Build Coastguard Worker   // [span.cons], span constructors, copy, assignment, and destructor
190*3ac0a46fSAndroid Build Coastguard Worker   constexpr span() noexcept : data_(nullptr), size_(0) {}
191*3ac0a46fSAndroid Build Coastguard Worker   constexpr span(T* data, size_t size) noexcept : data_(data), size_(size) {
192*3ac0a46fSAndroid Build Coastguard Worker     DCHECK(data_ || size_ == 0);
193*3ac0a46fSAndroid Build Coastguard Worker   }
194*3ac0a46fSAndroid Build Coastguard Worker 
195*3ac0a46fSAndroid Build Coastguard Worker   // TODO(dcheng): Implement construction from a |begin| and |end| pointer.
196*3ac0a46fSAndroid Build Coastguard Worker   template <size_t N>
197*3ac0a46fSAndroid Build Coastguard Worker   constexpr span(T (&array)[N]) noexcept : span(array, N) {}
198*3ac0a46fSAndroid Build Coastguard Worker 
199*3ac0a46fSAndroid Build Coastguard Worker   template <size_t N>
200*3ac0a46fSAndroid Build Coastguard Worker   constexpr span(std::array<T, N>& array) noexcept : span(array.data(), N) {}
201*3ac0a46fSAndroid Build Coastguard Worker 
202*3ac0a46fSAndroid Build Coastguard Worker   // Conversion from a container that provides |T* data()| and |integral_type
203*3ac0a46fSAndroid Build Coastguard Worker   // size()|. Note that |data()| may not return nullptr for some empty
204*3ac0a46fSAndroid Build Coastguard Worker   // containers, which can lead to container overflow errors when probing
205*3ac0a46fSAndroid Build Coastguard Worker   // unowned ptrs.
206*3ac0a46fSAndroid Build Coastguard Worker #if defined(ADDRESS_SANITIZER) && defined(UNOWNED_PTR_IS_BASE_RAW_PTR)
207*3ac0a46fSAndroid Build Coastguard Worker   template <typename Container,
208*3ac0a46fSAndroid Build Coastguard Worker             typename = internal::EnableIfSpanCompatibleContainer<Container, T>>
209*3ac0a46fSAndroid Build Coastguard Worker   constexpr span(Container& container)
210*3ac0a46fSAndroid Build Coastguard Worker       : span(container.size() ? container.data() : nullptr, container.size()) {}
211*3ac0a46fSAndroid Build Coastguard Worker #else
212*3ac0a46fSAndroid Build Coastguard Worker   template <typename Container,
213*3ac0a46fSAndroid Build Coastguard Worker             typename = internal::EnableIfSpanCompatibleContainer<Container, T>>
214*3ac0a46fSAndroid Build Coastguard Worker   constexpr span(Container& container)
215*3ac0a46fSAndroid Build Coastguard Worker       : span(container.data(), container.size()) {}
216*3ac0a46fSAndroid Build Coastguard Worker #endif
217*3ac0a46fSAndroid Build Coastguard Worker 
218*3ac0a46fSAndroid Build Coastguard Worker   template <
219*3ac0a46fSAndroid Build Coastguard Worker       typename Container,
220*3ac0a46fSAndroid Build Coastguard Worker       typename = internal::EnableIfConstSpanCompatibleContainer<Container, T>>
221*3ac0a46fSAndroid Build Coastguard Worker   span(const Container& container) : span(container.data(), container.size()) {}
222*3ac0a46fSAndroid Build Coastguard Worker 
223*3ac0a46fSAndroid Build Coastguard Worker   constexpr span(const span& other) noexcept = default;
224*3ac0a46fSAndroid Build Coastguard Worker 
225*3ac0a46fSAndroid Build Coastguard Worker   // Conversions from spans of compatible types: this allows a span<T> to be
226*3ac0a46fSAndroid Build Coastguard Worker   // seamlessly used as a span<const T>, but not the other way around.
227*3ac0a46fSAndroid Build Coastguard Worker   template <typename U, typename = internal::EnableIfLegalSpanConversion<U, T>>
228*3ac0a46fSAndroid Build Coastguard Worker   constexpr span(const span<U>& other) : span(other.data(), other.size()) {}
229*3ac0a46fSAndroid Build Coastguard Worker   span& operator=(const span& other) noexcept {
230*3ac0a46fSAndroid Build Coastguard Worker     if (this != &other) {
231*3ac0a46fSAndroid Build Coastguard Worker       ReleaseEmptySpan();
232*3ac0a46fSAndroid Build Coastguard Worker       data_ = other.data_;
233*3ac0a46fSAndroid Build Coastguard Worker       size_ = other.size_;
234*3ac0a46fSAndroid Build Coastguard Worker     }
235*3ac0a46fSAndroid Build Coastguard Worker     return *this;
236*3ac0a46fSAndroid Build Coastguard Worker   }
237*3ac0a46fSAndroid Build Coastguard Worker   ~span() noexcept { ReleaseEmptySpan(); }
238*3ac0a46fSAndroid Build Coastguard Worker 
239*3ac0a46fSAndroid Build Coastguard Worker   // [span.sub], span subviews
240*3ac0a46fSAndroid Build Coastguard Worker   const span first(size_t count) const {
241*3ac0a46fSAndroid Build Coastguard Worker     CHECK(count <= size_);
242*3ac0a46fSAndroid Build Coastguard Worker     return span(static_cast<T*>(data_), count);
243*3ac0a46fSAndroid Build Coastguard Worker   }
244*3ac0a46fSAndroid Build Coastguard Worker 
245*3ac0a46fSAndroid Build Coastguard Worker   const span last(size_t count) const {
246*3ac0a46fSAndroid Build Coastguard Worker     CHECK(count <= size_);
247*3ac0a46fSAndroid Build Coastguard Worker     return span(static_cast<T*>(data_) + (size_ - count), count);
248*3ac0a46fSAndroid Build Coastguard Worker   }
249*3ac0a46fSAndroid Build Coastguard Worker 
250*3ac0a46fSAndroid Build Coastguard Worker   const span subspan(size_t pos, size_t count = dynamic_extent) const {
251*3ac0a46fSAndroid Build Coastguard Worker     CHECK(pos <= size_);
252*3ac0a46fSAndroid Build Coastguard Worker     CHECK(count == dynamic_extent || count <= size_ - pos);
253*3ac0a46fSAndroid Build Coastguard Worker     return span(static_cast<T*>(data_) + pos,
254*3ac0a46fSAndroid Build Coastguard Worker                 count == dynamic_extent ? size_ - pos : count);
255*3ac0a46fSAndroid Build Coastguard Worker   }
256*3ac0a46fSAndroid Build Coastguard Worker 
257*3ac0a46fSAndroid Build Coastguard Worker   // [span.obs], span observers
258*3ac0a46fSAndroid Build Coastguard Worker   constexpr size_t size() const noexcept { return size_; }
259*3ac0a46fSAndroid Build Coastguard Worker   constexpr size_t size_bytes() const noexcept { return size() * sizeof(T); }
260*3ac0a46fSAndroid Build Coastguard Worker   constexpr bool empty() const noexcept { return size_ == 0; }
261*3ac0a46fSAndroid Build Coastguard Worker 
262*3ac0a46fSAndroid Build Coastguard Worker   // [span.elem], span element access
263*3ac0a46fSAndroid Build Coastguard Worker   T& operator[](size_t index) const noexcept {
264*3ac0a46fSAndroid Build Coastguard Worker     CHECK(index < size_);
265*3ac0a46fSAndroid Build Coastguard Worker     return static_cast<T*>(data_)[index];
266*3ac0a46fSAndroid Build Coastguard Worker   }
267*3ac0a46fSAndroid Build Coastguard Worker 
268*3ac0a46fSAndroid Build Coastguard Worker   constexpr T& front() const noexcept {
269*3ac0a46fSAndroid Build Coastguard Worker     CHECK(!empty());
270*3ac0a46fSAndroid Build Coastguard Worker     return *data();
271*3ac0a46fSAndroid Build Coastguard Worker   }
272*3ac0a46fSAndroid Build Coastguard Worker 
273*3ac0a46fSAndroid Build Coastguard Worker   constexpr T& back() const noexcept {
274*3ac0a46fSAndroid Build Coastguard Worker     CHECK(!empty());
275*3ac0a46fSAndroid Build Coastguard Worker     return *(data() + size() - 1);
276*3ac0a46fSAndroid Build Coastguard Worker   }
277*3ac0a46fSAndroid Build Coastguard Worker 
278*3ac0a46fSAndroid Build Coastguard Worker   constexpr T* data() const noexcept { return static_cast<T*>(data_); }
279*3ac0a46fSAndroid Build Coastguard Worker 
280*3ac0a46fSAndroid Build Coastguard Worker   // [span.iter], span iterator support
281*3ac0a46fSAndroid Build Coastguard Worker   constexpr iterator begin() const noexcept { return static_cast<T*>(data_); }
282*3ac0a46fSAndroid Build Coastguard Worker   constexpr iterator end() const noexcept { return begin() + size_; }
283*3ac0a46fSAndroid Build Coastguard Worker 
284*3ac0a46fSAndroid Build Coastguard Worker   constexpr const_iterator cbegin() const noexcept { return begin(); }
285*3ac0a46fSAndroid Build Coastguard Worker   constexpr const_iterator cend() const noexcept { return end(); }
286*3ac0a46fSAndroid Build Coastguard Worker 
287*3ac0a46fSAndroid Build Coastguard Worker   constexpr reverse_iterator rbegin() const noexcept {
288*3ac0a46fSAndroid Build Coastguard Worker     return reverse_iterator(end());
289*3ac0a46fSAndroid Build Coastguard Worker   }
290*3ac0a46fSAndroid Build Coastguard Worker   constexpr reverse_iterator rend() const noexcept {
291*3ac0a46fSAndroid Build Coastguard Worker     return reverse_iterator(begin());
292*3ac0a46fSAndroid Build Coastguard Worker   }
293*3ac0a46fSAndroid Build Coastguard Worker 
294*3ac0a46fSAndroid Build Coastguard Worker   constexpr const_reverse_iterator crbegin() const noexcept {
295*3ac0a46fSAndroid Build Coastguard Worker     return const_reverse_iterator(cend());
296*3ac0a46fSAndroid Build Coastguard Worker   }
297*3ac0a46fSAndroid Build Coastguard Worker   constexpr const_reverse_iterator crend() const noexcept {
298*3ac0a46fSAndroid Build Coastguard Worker     return const_reverse_iterator(cbegin());
299*3ac0a46fSAndroid Build Coastguard Worker   }
300*3ac0a46fSAndroid Build Coastguard Worker 
301*3ac0a46fSAndroid Build Coastguard Worker  private:
302*3ac0a46fSAndroid Build Coastguard Worker   void ReleaseEmptySpan() noexcept {
303*3ac0a46fSAndroid Build Coastguard Worker #if defined(ADDRESS_SANITIZER) && !defined(UNOWNED_PTR_IS_BASE_RAW_PTR)
304*3ac0a46fSAndroid Build Coastguard Worker     // Empty spans might point to byte N+1 of a N-byte object, legal for
305*3ac0a46fSAndroid Build Coastguard Worker     // C pointers but not UnownedPtrs.
306*3ac0a46fSAndroid Build Coastguard Worker     if (!size_)
307*3ac0a46fSAndroid Build Coastguard Worker       data_.ReleaseBadPointer();
308*3ac0a46fSAndroid Build Coastguard Worker #endif
309*3ac0a46fSAndroid Build Coastguard Worker   }
310*3ac0a46fSAndroid Build Coastguard Worker 
311*3ac0a46fSAndroid Build Coastguard Worker #if defined(UNOWNED_PTR_IS_BASE_RAW_PTR)
312*3ac0a46fSAndroid Build Coastguard Worker   raw_ptr<T, AllowPtrArithmetic> data_ = nullptr;
313*3ac0a46fSAndroid Build Coastguard Worker #else
314*3ac0a46fSAndroid Build Coastguard Worker   UnownedPtr<T> data_;
315*3ac0a46fSAndroid Build Coastguard Worker #endif
316*3ac0a46fSAndroid Build Coastguard Worker   size_t size_;
317*3ac0a46fSAndroid Build Coastguard Worker };
318*3ac0a46fSAndroid Build Coastguard Worker 
319*3ac0a46fSAndroid Build Coastguard Worker // [span.comparison], span comparison operators
320*3ac0a46fSAndroid Build Coastguard Worker // Relational operators. Equality is a element-wise comparison.
321*3ac0a46fSAndroid Build Coastguard Worker template <typename T>
322*3ac0a46fSAndroid Build Coastguard Worker constexpr bool operator==(span<T> lhs, span<T> rhs) noexcept {
323*3ac0a46fSAndroid Build Coastguard Worker   return lhs.size() == rhs.size() &&
324*3ac0a46fSAndroid Build Coastguard Worker          std::equal(lhs.cbegin(), lhs.cend(), rhs.cbegin());
325*3ac0a46fSAndroid Build Coastguard Worker }
326*3ac0a46fSAndroid Build Coastguard Worker 
327*3ac0a46fSAndroid Build Coastguard Worker template <typename T>
328*3ac0a46fSAndroid Build Coastguard Worker constexpr bool operator!=(span<T> lhs, span<T> rhs) noexcept {
329*3ac0a46fSAndroid Build Coastguard Worker   return !(lhs == rhs);
330*3ac0a46fSAndroid Build Coastguard Worker }
331*3ac0a46fSAndroid Build Coastguard Worker 
332*3ac0a46fSAndroid Build Coastguard Worker template <typename T>
333*3ac0a46fSAndroid Build Coastguard Worker constexpr bool operator<(span<T> lhs, span<T> rhs) noexcept {
334*3ac0a46fSAndroid Build Coastguard Worker   return std::lexicographical_compare(lhs.cbegin(), lhs.cend(), rhs.cbegin(),
335*3ac0a46fSAndroid Build Coastguard Worker                                       rhs.cend());
336*3ac0a46fSAndroid Build Coastguard Worker }
337*3ac0a46fSAndroid Build Coastguard Worker 
338*3ac0a46fSAndroid Build Coastguard Worker template <typename T>
339*3ac0a46fSAndroid Build Coastguard Worker constexpr bool operator<=(span<T> lhs, span<T> rhs) noexcept {
340*3ac0a46fSAndroid Build Coastguard Worker   return !(rhs < lhs);
341*3ac0a46fSAndroid Build Coastguard Worker }
342*3ac0a46fSAndroid Build Coastguard Worker 
343*3ac0a46fSAndroid Build Coastguard Worker template <typename T>
344*3ac0a46fSAndroid Build Coastguard Worker constexpr bool operator>(span<T> lhs, span<T> rhs) noexcept {
345*3ac0a46fSAndroid Build Coastguard Worker   return rhs < lhs;
346*3ac0a46fSAndroid Build Coastguard Worker }
347*3ac0a46fSAndroid Build Coastguard Worker 
348*3ac0a46fSAndroid Build Coastguard Worker template <typename T>
349*3ac0a46fSAndroid Build Coastguard Worker constexpr bool operator>=(span<T> lhs, span<T> rhs) noexcept {
350*3ac0a46fSAndroid Build Coastguard Worker   return !(lhs < rhs);
351*3ac0a46fSAndroid Build Coastguard Worker }
352*3ac0a46fSAndroid Build Coastguard Worker 
353*3ac0a46fSAndroid Build Coastguard Worker // [span.objectrep], views of object representation
354*3ac0a46fSAndroid Build Coastguard Worker template <typename T>
355*3ac0a46fSAndroid Build Coastguard Worker span<const uint8_t> as_bytes(span<T> s) noexcept {
356*3ac0a46fSAndroid Build Coastguard Worker   return {reinterpret_cast<const uint8_t*>(s.data()), s.size_bytes()};
357*3ac0a46fSAndroid Build Coastguard Worker }
358*3ac0a46fSAndroid Build Coastguard Worker 
359*3ac0a46fSAndroid Build Coastguard Worker template <typename T,
360*3ac0a46fSAndroid Build Coastguard Worker           typename U = typename std::enable_if<!std::is_const<T>::value>::type>
361*3ac0a46fSAndroid Build Coastguard Worker span<uint8_t> as_writable_bytes(span<T> s) noexcept {
362*3ac0a46fSAndroid Build Coastguard Worker   return {reinterpret_cast<uint8_t*>(s.data()), s.size_bytes()};
363*3ac0a46fSAndroid Build Coastguard Worker }
364*3ac0a46fSAndroid Build Coastguard Worker 
365*3ac0a46fSAndroid Build Coastguard Worker // Type-deducing helpers for constructing a span.
366*3ac0a46fSAndroid Build Coastguard Worker template <typename T>
367*3ac0a46fSAndroid Build Coastguard Worker constexpr span<T> make_span(T* data, size_t size) noexcept {
368*3ac0a46fSAndroid Build Coastguard Worker   return span<T>(data, size);
369*3ac0a46fSAndroid Build Coastguard Worker }
370*3ac0a46fSAndroid Build Coastguard Worker 
371*3ac0a46fSAndroid Build Coastguard Worker template <typename T, size_t N>
372*3ac0a46fSAndroid Build Coastguard Worker constexpr span<T> make_span(T (&array)[N]) noexcept {
373*3ac0a46fSAndroid Build Coastguard Worker   return span<T>(array);
374*3ac0a46fSAndroid Build Coastguard Worker }
375*3ac0a46fSAndroid Build Coastguard Worker 
376*3ac0a46fSAndroid Build Coastguard Worker template <typename T, size_t N>
377*3ac0a46fSAndroid Build Coastguard Worker constexpr span<T> make_span(std::array<T, N>& array) noexcept {
378*3ac0a46fSAndroid Build Coastguard Worker   return span<T>(array);
379*3ac0a46fSAndroid Build Coastguard Worker }
380*3ac0a46fSAndroid Build Coastguard Worker 
381*3ac0a46fSAndroid Build Coastguard Worker template <typename Container,
382*3ac0a46fSAndroid Build Coastguard Worker           typename T = typename Container::value_type,
383*3ac0a46fSAndroid Build Coastguard Worker           typename = internal::EnableIfSpanCompatibleContainer<Container, T>>
384*3ac0a46fSAndroid Build Coastguard Worker constexpr span<T> make_span(Container& container) {
385*3ac0a46fSAndroid Build Coastguard Worker   return span<T>(container);
386*3ac0a46fSAndroid Build Coastguard Worker }
387*3ac0a46fSAndroid Build Coastguard Worker 
388*3ac0a46fSAndroid Build Coastguard Worker template <
389*3ac0a46fSAndroid Build Coastguard Worker     typename Container,
390*3ac0a46fSAndroid Build Coastguard Worker     typename T = typename std::add_const<typename Container::value_type>::type,
391*3ac0a46fSAndroid Build Coastguard Worker     typename = internal::EnableIfConstSpanCompatibleContainer<Container, T>>
392*3ac0a46fSAndroid Build Coastguard Worker constexpr span<T> make_span(const Container& container) {
393*3ac0a46fSAndroid Build Coastguard Worker   return span<T>(container);
394*3ac0a46fSAndroid Build Coastguard Worker }
395*3ac0a46fSAndroid Build Coastguard Worker 
396*3ac0a46fSAndroid Build Coastguard Worker }  // namespace pdfium
397*3ac0a46fSAndroid Build Coastguard Worker 
398*3ac0a46fSAndroid Build Coastguard Worker #endif  // THIRD_PARTY_BASE_CONTAINERS_SPAN_H_
399