1 //
2 // Copyright 2017 The Abseil Authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // https://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 // -----------------------------------------------------------------------------
17 // span.h
18 // -----------------------------------------------------------------------------
19 //
20 // This header file defines a `Span<T>` type for holding a reference to existing
21 // array data. The `Span` object, much like the `absl::string_view` object,
22 // does not own such data itself, and the data being referenced by the span must
23 // outlive the span itself. Unlike `view` type references, a span can hold a
24 // reference to mutable data (and can mutate it for underlying types of
25 // non-const T.) A span provides a lightweight way to pass a reference to such
26 // data.
27 //
28 // Additionally, this header file defines `MakeSpan()` and `MakeConstSpan()`
29 // factory functions, for clearly creating spans of type `Span<T>` or read-only
30 // `Span<const T>` when such types may be difficult to identify due to issues
31 // with implicit conversion.
32 //
33 // The C++20 draft standard includes a `std::span` type. As of June 2020, the
34 // differences between `absl::Span` and `std::span` are:
35 // * `absl::Span` has `operator==` (which is likely a design bug,
36 // per https://abseil.io/blog/20180531-regular-types)
37 // * `absl::Span` has the factory functions `MakeSpan()` and
38 // `MakeConstSpan()`
39 // * bounds-checked access to `absl::Span` is accomplished with `at()`
40 // * `absl::Span` has compiler-provided move and copy constructors and
41 // assignment. This is due to them being specified as `constexpr`, but that
42 // implies const in C++11.
43 // * A read-only `absl::Span<const T>` can be implicitly constructed from an
44 // initializer list.
45 // * `absl::Span` has no `bytes()`, `size_bytes()`, `as_bytes()`, or
46 // `as_mutable_bytes()` methods
47 // * `absl::Span` has no static extent template parameter, nor constructors
48 // which exist only because of the static extent parameter.
49 // * `absl::Span` has an explicit mutable-reference constructor
50 //
51 // For more information, see the class comments below.
52 #ifndef ABSL_TYPES_SPAN_H_
53 #define ABSL_TYPES_SPAN_H_
54
55 #include <algorithm>
56 #include <cassert>
57 #include <cstddef>
58 #include <initializer_list>
59 #include <iterator>
60 #include <type_traits>
61 #include <utility>
62
63 #include "absl/base/attributes.h"
64 #include "absl/base/internal/throw_delegate.h"
65 #include "absl/base/macros.h"
66 #include "absl/base/nullability.h"
67 #include "absl/base/optimization.h"
68 #include "absl/base/port.h" // TODO(strel): remove this include
69 #include "absl/meta/type_traits.h"
70 #include "absl/types/internal/span.h"
71
72 namespace absl {
73 ABSL_NAMESPACE_BEGIN
74
75 //------------------------------------------------------------------------------
76 // Span
77 //------------------------------------------------------------------------------
78 //
79 // A `Span` is an "array reference" type for holding a reference of contiguous
80 // array data; the `Span` object does not and cannot own such data itself. A
81 // span provides an easy way to provide overloads for anything operating on
82 // contiguous sequences without needing to manage pointers and array lengths
83 // manually.
84
85 // A span is conceptually a pointer (ptr) and a length (size) into an already
86 // existing array of contiguous memory; the array it represents references the
87 // elements "ptr[0] .. ptr[size-1]". Passing a properly-constructed `Span`
88 // instead of raw pointers avoids many issues related to index out of bounds
89 // errors.
90 //
91 // Spans may also be constructed from containers holding contiguous sequences.
92 // Such containers must supply `data()` and `size() const` methods (e.g
93 // `std::vector<T>`, `absl::InlinedVector<T, N>`). All implicit conversions to
94 // `absl::Span` from such containers will create spans of type `const T`;
95 // spans which can mutate their values (of type `T`) must use explicit
96 // constructors.
97 //
98 // A `Span<T>` is somewhat analogous to an `absl::string_view`, but for an array
99 // of elements of type `T`, and unlike an `absl::string_view`, a span can hold a
100 // reference to mutable data. A user of `Span` must ensure that the data being
101 // pointed to outlives the `Span` itself.
102 //
103 // You can construct a `Span<T>` in several ways:
104 //
105 // * Explicitly from a reference to a container type
106 // * Explicitly from a pointer and size
107 // * Implicitly from a container type (but only for spans of type `const T`)
108 // * Using the `MakeSpan()` or `MakeConstSpan()` factory functions.
109 //
110 // Examples:
111 //
112 // // Construct a Span explicitly from a container:
113 // std::vector<int> v = {1, 2, 3, 4, 5};
114 // auto span = absl::Span<const int>(v);
115 //
116 // // Construct a Span explicitly from a C-style array:
117 // int a[5] = {1, 2, 3, 4, 5};
118 // auto span = absl::Span<const int>(a);
119 //
120 // // Construct a Span implicitly from a container
121 // void MyRoutine(absl::Span<const int> a) {
122 // ...
123 // }
124 // std::vector v = {1,2,3,4,5};
125 // MyRoutine(v) // convert to Span<const T>
126 //
127 // Note that `Span` objects, in addition to requiring that the memory they
128 // point to remains alive, must also ensure that such memory does not get
129 // reallocated. Therefore, to avoid undefined behavior, containers with
130 // associated spans should not invoke operations that may reallocate memory
131 // (such as resizing) or invalidate iterators into the container.
132 //
133 // One common use for a `Span` is when passing arguments to a routine that can
134 // accept a variety of array types (e.g. a `std::vector`, `absl::InlinedVector`,
135 // a C-style array, etc.). Instead of creating overloads for each case, you
136 // can simply specify a `Span` as the argument to such a routine.
137 //
138 // Example:
139 //
140 // void MyRoutine(absl::Span<const int> a) {
141 // ...
142 // }
143 //
144 // std::vector v = {1,2,3,4,5};
145 // MyRoutine(v);
146 //
147 // absl::InlinedVector<int, 4> my_inline_vector;
148 // MyRoutine(my_inline_vector);
149 //
150 // // Explicit constructor from pointer,size
151 // int* my_array = new int[10];
152 // MyRoutine(absl::Span<const int>(my_array, 10));
153 template <typename T>
154 class Span {
155 private:
156 // Used to determine whether a Span can be constructed from a container of
157 // type C.
158 template <typename C>
159 using EnableIfConvertibleFrom =
160 typename std::enable_if<span_internal::HasData<T, C>::value &&
161 span_internal::HasSize<C>::value>::type;
162
163 // Used to SFINAE-enable a function when the slice elements are const.
164 template <typename U>
165 using EnableIfValueIsConst =
166 typename std::enable_if<std::is_const<T>::value, U>::type;
167
168 // Used to SFINAE-enable a function when the slice elements are mutable.
169 template <typename U>
170 using EnableIfValueIsMutable =
171 typename std::enable_if<!std::is_const<T>::value, U>::type;
172
173 public:
174 using element_type = T;
175 using value_type = absl::remove_cv_t<T>;
176 // TODO(b/316099902) - pointer should be Nullable<T*>, but this makes it hard
177 // to recognize foreach loops as safe.
178 using pointer = T*;
179 using const_pointer = const T*;
180 using reference = T&;
181 using const_reference = const T&;
182 using iterator = pointer;
183 using const_iterator = const_pointer;
184 using reverse_iterator = std::reverse_iterator<iterator>;
185 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
186 using size_type = size_t;
187 using difference_type = ptrdiff_t;
188
189 static const size_type npos = ~(size_type(0));
190
Span()191 constexpr Span() noexcept : Span(nullptr, 0) {}
Span(pointer array,size_type length)192 constexpr Span(pointer array, size_type length) noexcept
193 : ptr_(array), len_(length) {}
194
195 // Implicit conversion constructors
196 template <size_t N>
Span(T (& a)[N])197 constexpr Span(T (&a)[N]) noexcept // NOLINT(runtime/explicit)
198 : Span(a, N) {}
199
200 // Explicit reference constructor for a mutable `Span<T>` type. Can be
201 // replaced with MakeSpan() to infer the type parameter.
202 template <typename V, typename = EnableIfConvertibleFrom<V>,
203 typename = EnableIfValueIsMutable<V>,
204 typename = span_internal::EnableIfNotIsView<V>>
Span(V & v ABSL_ATTRIBUTE_LIFETIME_BOUND)205 explicit Span(
206 V& v
207 ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept // NOLINT(runtime/references)
208 : Span(span_internal::GetData(v), v.size()) {}
209
210 // Implicit reference constructor for a read-only `Span<const T>` type
211 template <typename V, typename = EnableIfConvertibleFrom<V>,
212 typename = EnableIfValueIsConst<V>,
213 typename = span_internal::EnableIfNotIsView<V>>
Span(const V & v ABSL_ATTRIBUTE_LIFETIME_BOUND)214 constexpr Span(
215 const V& v
216 ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept // NOLINT(runtime/explicit)
217 : Span(span_internal::GetData(v), v.size()) {}
218
219 // Overloads of the above two functions that are only enabled for view types.
220 // This is so we can drop the ABSL_ATTRIBUTE_LIFETIME_BOUND annotation. These
221 // overloads must be made unique by using a different template parameter list
222 // (hence the = 0 for the IsView enabler).
223 template <typename V, typename = EnableIfConvertibleFrom<V>,
224 typename = EnableIfValueIsMutable<V>,
225 span_internal::EnableIfIsView<V> = 0>
Span(V & v)226 explicit Span(V& v) noexcept // NOLINT(runtime/references)
227 : Span(span_internal::GetData(v), v.size()) {}
228 template <typename V, typename = EnableIfConvertibleFrom<V>,
229 typename = EnableIfValueIsConst<V>,
230 span_internal::EnableIfIsView<V> = 0>
Span(const V & v)231 constexpr Span(const V& v) noexcept // NOLINT(runtime/explicit)
232 : Span(span_internal::GetData(v), v.size()) {}
233
234 // Implicit constructor from an initializer list, making it possible to pass a
235 // brace-enclosed initializer list to a function expecting a `Span`. Such
236 // spans constructed from an initializer list must be of type `Span<const T>`.
237 //
238 // void Process(absl::Span<const int> x);
239 // Process({1, 2, 3});
240 //
241 // Note that as always the array referenced by the span must outlive the span.
242 // Since an initializer list constructor acts as if it is fed a temporary
243 // array (cf. C++ standard [dcl.init.list]/5), it's safe to use this
244 // constructor only when the `std::initializer_list` itself outlives the span.
245 // In order to meet this requirement it's sufficient to ensure that neither
246 // the span nor a copy of it is used outside of the expression in which it's
247 // created:
248 //
249 // // Assume that this function uses the array directly, not retaining any
250 // // copy of the span or pointer to any of its elements.
251 // void Process(absl::Span<const int> ints);
252 //
253 // // Okay: the std::initializer_list<int> will reference a temporary array
254 // // that isn't destroyed until after the call to Process returns.
255 // Process({ 17, 19 });
256 //
257 // // Not okay: the storage used by the std::initializer_list<int> is not
258 // // allowed to be referenced after the first line.
259 // absl::Span<const int> ints = { 17, 19 };
260 // Process(ints);
261 //
262 // // Not okay for the same reason as above: even when the elements of the
263 // // initializer list expression are not temporaries the underlying array
264 // // is, so the initializer list must still outlive the span.
265 // const int foo = 17;
266 // absl::Span<const int> ints = { foo };
267 // Process(ints);
268 //
269 template <typename LazyT = T,
270 typename = EnableIfValueIsConst<LazyT>>
Span(std::initializer_list<value_type> v ABSL_ATTRIBUTE_LIFETIME_BOUND)271 Span(std::initializer_list<value_type> v
272 ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept // NOLINT(runtime/explicit)
273 : Span(v.begin(), v.size()) {}
274
275 // Accessors
276
277 // Span::data()
278 //
279 // Returns a pointer to the span's underlying array of data (which is held
280 // outside the span).
data()281 constexpr pointer data() const noexcept { return ptr_; }
282
283 // Span::size()
284 //
285 // Returns the size of this span.
size()286 constexpr size_type size() const noexcept { return len_; }
287
288 // Span::length()
289 //
290 // Returns the length (size) of this span.
length()291 constexpr size_type length() const noexcept { return size(); }
292
293 // Span::empty()
294 //
295 // Returns a boolean indicating whether or not this span is considered empty.
empty()296 constexpr bool empty() const noexcept { return size() == 0; }
297
298 // Span::operator[]
299 //
300 // Returns a reference to the i'th element of this span.
301 constexpr reference operator[](size_type i) const noexcept {
302 return ABSL_HARDENING_ASSERT(i < size()), ptr_[i];
303 }
304
305 // Span::at()
306 //
307 // Returns a reference to the i'th element of this span.
at(size_type i)308 constexpr reference at(size_type i) const {
309 return ABSL_PREDICT_TRUE(i < size()) //
310 ? *(data() + i)
311 : (base_internal::ThrowStdOutOfRange(
312 "Span::at failed bounds check"),
313 *(data() + i));
314 }
315
316 // Span::front()
317 //
318 // Returns a reference to the first element of this span. The span must not
319 // be empty.
front()320 constexpr reference front() const noexcept {
321 return ABSL_HARDENING_ASSERT(size() > 0), *data();
322 }
323
324 // Span::back()
325 //
326 // Returns a reference to the last element of this span. The span must not
327 // be empty.
back()328 constexpr reference back() const noexcept {
329 return ABSL_HARDENING_ASSERT(size() > 0), *(data() + size() - 1);
330 }
331
332 // Span::begin()
333 //
334 // Returns an iterator pointing to the first element of this span, or `end()`
335 // if the span is empty.
begin()336 constexpr iterator begin() const noexcept { return data(); }
337
338 // Span::cbegin()
339 //
340 // Returns a const iterator pointing to the first element of this span, or
341 // `end()` if the span is empty.
cbegin()342 constexpr const_iterator cbegin() const noexcept { return begin(); }
343
344 // Span::end()
345 //
346 // Returns an iterator pointing just beyond the last element at the
347 // end of this span. This iterator acts as a placeholder; attempting to
348 // access it results in undefined behavior.
end()349 constexpr iterator end() const noexcept { return data() + size(); }
350
351 // Span::cend()
352 //
353 // Returns a const iterator pointing just beyond the last element at the
354 // end of this span. This iterator acts as a placeholder; attempting to
355 // access it results in undefined behavior.
cend()356 constexpr const_iterator cend() const noexcept { return end(); }
357
358 // Span::rbegin()
359 //
360 // Returns a reverse iterator pointing to the last element at the end of this
361 // span, or `rend()` if the span is empty.
rbegin()362 constexpr reverse_iterator rbegin() const noexcept {
363 return reverse_iterator(end());
364 }
365
366 // Span::crbegin()
367 //
368 // Returns a const reverse iterator pointing to the last element at the end of
369 // this span, or `crend()` if the span is empty.
crbegin()370 constexpr const_reverse_iterator crbegin() const noexcept { return rbegin(); }
371
372 // Span::rend()
373 //
374 // Returns a reverse iterator pointing just before the first element
375 // at the beginning of this span. This pointer acts as a placeholder;
376 // attempting to access its element results in undefined behavior.
rend()377 constexpr reverse_iterator rend() const noexcept {
378 return reverse_iterator(begin());
379 }
380
381 // Span::crend()
382 //
383 // Returns a reverse const iterator pointing just before the first element
384 // at the beginning of this span. This pointer acts as a placeholder;
385 // attempting to access its element results in undefined behavior.
crend()386 constexpr const_reverse_iterator crend() const noexcept { return rend(); }
387
388 // Span mutations
389
390 // Span::remove_prefix()
391 //
392 // Removes the first `n` elements from the span.
remove_prefix(size_type n)393 void remove_prefix(size_type n) noexcept {
394 ABSL_HARDENING_ASSERT(size() >= n);
395 ptr_ += n;
396 len_ -= n;
397 }
398
399 // Span::remove_suffix()
400 //
401 // Removes the last `n` elements from the span.
remove_suffix(size_type n)402 void remove_suffix(size_type n) noexcept {
403 ABSL_HARDENING_ASSERT(size() >= n);
404 len_ -= n;
405 }
406
407 // Span::subspan()
408 //
409 // Returns a `Span` starting at element `pos` and of length `len`. Both `pos`
410 // and `len` are of type `size_type` and thus non-negative. Parameter `pos`
411 // must be <= size(). Any `len` value that points past the end of the span
412 // will be trimmed to at most size() - `pos`. A default `len` value of `npos`
413 // ensures the returned subspan continues until the end of the span.
414 //
415 // Examples:
416 //
417 // std::vector<int> vec = {10, 11, 12, 13};
418 // absl::MakeSpan(vec).subspan(1, 2); // {11, 12}
419 // absl::MakeSpan(vec).subspan(2, 8); // {12, 13}
420 // absl::MakeSpan(vec).subspan(1); // {11, 12, 13}
421 // absl::MakeSpan(vec).subspan(4); // {}
422 // absl::MakeSpan(vec).subspan(5); // throws std::out_of_range
423 constexpr Span subspan(size_type pos = 0, size_type len = npos) const {
424 return (pos <= size())
425 ? Span(data() + pos, (std::min)(size() - pos, len))
426 : (base_internal::ThrowStdOutOfRange("pos > size()"), Span());
427 }
428
429 // Span::first()
430 //
431 // Returns a `Span` containing first `len` elements. Parameter `len` is of
432 // type `size_type` and thus non-negative. `len` value must be <= size().
433 //
434 // Examples:
435 //
436 // std::vector<int> vec = {10, 11, 12, 13};
437 // absl::MakeSpan(vec).first(1); // {10}
438 // absl::MakeSpan(vec).first(3); // {10, 11, 12}
439 // absl::MakeSpan(vec).first(5); // throws std::out_of_range
first(size_type len)440 constexpr Span first(size_type len) const {
441 return (len <= size())
442 ? Span(data(), len)
443 : (base_internal::ThrowStdOutOfRange("len > size()"), Span());
444 }
445
446 // Span::last()
447 //
448 // Returns a `Span` containing last `len` elements. Parameter `len` is of
449 // type `size_type` and thus non-negative. `len` value must be <= size().
450 //
451 // Examples:
452 //
453 // std::vector<int> vec = {10, 11, 12, 13};
454 // absl::MakeSpan(vec).last(1); // {13}
455 // absl::MakeSpan(vec).last(3); // {11, 12, 13}
456 // absl::MakeSpan(vec).last(5); // throws std::out_of_range
last(size_type len)457 constexpr Span last(size_type len) const {
458 return (len <= size())
459 ? Span(size() - len + data(), len)
460 : (base_internal::ThrowStdOutOfRange("len > size()"), Span());
461 }
462
463 // Support for absl::Hash.
464 template <typename H>
AbslHashValue(H h,Span v)465 friend H AbslHashValue(H h, Span v) {
466 return H::combine(H::combine_contiguous(std::move(h), v.data(), v.size()),
467 v.size());
468 }
469
470 private:
471 pointer ptr_;
472 size_type len_;
473 };
474
475 template <typename T>
476 const typename Span<T>::size_type Span<T>::npos;
477
478 // Span relationals
479
480 // Equality is compared element-by-element, while ordering is lexicographical.
481 // We provide three overloads for each operator to cover any combination on the
482 // left or right hand side of mutable Span<T>, read-only Span<const T>, and
483 // convertible-to-read-only Span<T>.
484 // TODO(zhangxy): Due to MSVC overload resolution bug with partial ordering
485 // template functions, 5 overloads per operator is needed as a workaround. We
486 // should update them to 3 overloads per operator using non-deduced context like
487 // string_view, i.e.
488 // - (Span<T>, Span<T>)
489 // - (Span<T>, non_deduced<Span<const T>>)
490 // - (non_deduced<Span<const T>>, Span<T>)
491
492 // operator==
493 template <typename T>
494 bool operator==(Span<T> a, Span<T> b) {
495 return span_internal::EqualImpl<Span, const T>(a, b);
496 }
497 template <typename T>
498 bool operator==(Span<const T> a, Span<T> b) {
499 return span_internal::EqualImpl<Span, const T>(a, b);
500 }
501 template <typename T>
502 bool operator==(Span<T> a, Span<const T> b) {
503 return span_internal::EqualImpl<Span, const T>(a, b);
504 }
505 template <
506 typename T, typename U,
507 typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
508 bool operator==(const U& a, Span<T> b) {
509 return span_internal::EqualImpl<Span, const T>(a, b);
510 }
511 template <
512 typename T, typename U,
513 typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
514 bool operator==(Span<T> a, const U& b) {
515 return span_internal::EqualImpl<Span, const T>(a, b);
516 }
517
518 // operator!=
519 template <typename T>
520 bool operator!=(Span<T> a, Span<T> b) {
521 return !(a == b);
522 }
523 template <typename T>
524 bool operator!=(Span<const T> a, Span<T> b) {
525 return !(a == b);
526 }
527 template <typename T>
528 bool operator!=(Span<T> a, Span<const T> b) {
529 return !(a == b);
530 }
531 template <
532 typename T, typename U,
533 typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
534 bool operator!=(const U& a, Span<T> b) {
535 return !(a == b);
536 }
537 template <
538 typename T, typename U,
539 typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
540 bool operator!=(Span<T> a, const U& b) {
541 return !(a == b);
542 }
543
544 // operator<
545 template <typename T>
546 bool operator<(Span<T> a, Span<T> b) {
547 return span_internal::LessThanImpl<Span, const T>(a, b);
548 }
549 template <typename T>
550 bool operator<(Span<const T> a, Span<T> b) {
551 return span_internal::LessThanImpl<Span, const T>(a, b);
552 }
553 template <typename T>
554 bool operator<(Span<T> a, Span<const T> b) {
555 return span_internal::LessThanImpl<Span, const T>(a, b);
556 }
557 template <
558 typename T, typename U,
559 typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
560 bool operator<(const U& a, Span<T> b) {
561 return span_internal::LessThanImpl<Span, const T>(a, b);
562 }
563 template <
564 typename T, typename U,
565 typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
566 bool operator<(Span<T> a, const U& b) {
567 return span_internal::LessThanImpl<Span, const T>(a, b);
568 }
569
570 // operator>
571 template <typename T>
572 bool operator>(Span<T> a, Span<T> b) {
573 return b < a;
574 }
575 template <typename T>
576 bool operator>(Span<const T> a, Span<T> b) {
577 return b < a;
578 }
579 template <typename T>
580 bool operator>(Span<T> a, Span<const T> b) {
581 return b < a;
582 }
583 template <
584 typename T, typename U,
585 typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
586 bool operator>(const U& a, Span<T> b) {
587 return b < a;
588 }
589 template <
590 typename T, typename U,
591 typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
592 bool operator>(Span<T> a, const U& b) {
593 return b < a;
594 }
595
596 // operator<=
597 template <typename T>
598 bool operator<=(Span<T> a, Span<T> b) {
599 return !(b < a);
600 }
601 template <typename T>
602 bool operator<=(Span<const T> a, Span<T> b) {
603 return !(b < a);
604 }
605 template <typename T>
606 bool operator<=(Span<T> a, Span<const T> b) {
607 return !(b < a);
608 }
609 template <
610 typename T, typename U,
611 typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
612 bool operator<=(const U& a, Span<T> b) {
613 return !(b < a);
614 }
615 template <
616 typename T, typename U,
617 typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
618 bool operator<=(Span<T> a, const U& b) {
619 return !(b < a);
620 }
621
622 // operator>=
623 template <typename T>
624 bool operator>=(Span<T> a, Span<T> b) {
625 return !(a < b);
626 }
627 template <typename T>
628 bool operator>=(Span<const T> a, Span<T> b) {
629 return !(a < b);
630 }
631 template <typename T>
632 bool operator>=(Span<T> a, Span<const T> b) {
633 return !(a < b);
634 }
635 template <
636 typename T, typename U,
637 typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
638 bool operator>=(const U& a, Span<T> b) {
639 return !(a < b);
640 }
641 template <
642 typename T, typename U,
643 typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
644 bool operator>=(Span<T> a, const U& b) {
645 return !(a < b);
646 }
647
648 // MakeSpan()
649 //
650 // Constructs a mutable `Span<T>`, deducing `T` automatically from either a
651 // container or pointer+size.
652 //
653 // Because a read-only `Span<const T>` is implicitly constructed from container
654 // types regardless of whether the container itself is a const container,
655 // constructing mutable spans of type `Span<T>` from containers requires
656 // explicit constructors. The container-accepting version of `MakeSpan()`
657 // deduces the type of `T` by the constness of the pointer received from the
658 // container's `data()` member. Similarly, the pointer-accepting version returns
659 // a `Span<const T>` if `T` is `const`, and a `Span<T>` otherwise.
660 //
661 // Examples:
662 //
663 // void MyRoutine(absl::Span<MyComplicatedType> a) {
664 // ...
665 // };
666 // // my_vector is a container of non-const types
667 // std::vector<MyComplicatedType> my_vector;
668 //
669 // // Constructing a Span implicitly attempts to create a Span of type
670 // // `Span<const T>`
671 // MyRoutine(my_vector); // error, type mismatch
672 //
673 // // Explicitly constructing the Span is verbose
674 // MyRoutine(absl::Span<MyComplicatedType>(my_vector));
675 //
676 // // Use MakeSpan() to make an absl::Span<T>
677 // MyRoutine(absl::MakeSpan(my_vector));
678 //
679 // // Construct a span from an array ptr+size
680 // absl::Span<T> my_span() {
681 // return absl::MakeSpan(&array[0], num_elements_);
682 // }
683 //
684 template <int&... ExplicitArgumentBarrier, typename T>
MakeSpan(absl::Nullable<T * > ptr,size_t size)685 constexpr Span<T> MakeSpan(absl::Nullable<T*> ptr, size_t size) noexcept {
686 return Span<T>(ptr, size);
687 }
688
689 template <int&... ExplicitArgumentBarrier, typename T>
MakeSpan(absl::Nullable<T * > begin,absl::Nullable<T * > end)690 Span<T> MakeSpan(absl::Nullable<T*> begin, absl::Nullable<T*> end) noexcept {
691 return ABSL_HARDENING_ASSERT(begin <= end),
692 Span<T>(begin, static_cast<size_t>(end - begin));
693 }
694
695 template <int&... ExplicitArgumentBarrier, typename C>
696 constexpr auto MakeSpan(C& c) noexcept // NOLINT(runtime/references)
697 -> decltype(absl::MakeSpan(span_internal::GetData(c), c.size())) {
698 return MakeSpan(span_internal::GetData(c), c.size());
699 }
700
701 template <int&... ExplicitArgumentBarrier, typename T, size_t N>
MakeSpan(T (& array)[N])702 constexpr Span<T> MakeSpan(T (&array)[N]) noexcept {
703 return Span<T>(array, N);
704 }
705
706 // MakeConstSpan()
707 //
708 // Constructs a `Span<const T>` as with `MakeSpan`, deducing `T` automatically,
709 // but always returning a `Span<const T>`.
710 //
711 // Examples:
712 //
713 // void ProcessInts(absl::Span<const int> some_ints);
714 //
715 // // Call with a pointer and size.
716 // int array[3] = { 0, 0, 0 };
717 // ProcessInts(absl::MakeConstSpan(&array[0], 3));
718 //
719 // // Call with a [begin, end) pair.
720 // ProcessInts(absl::MakeConstSpan(&array[0], &array[3]));
721 //
722 // // Call directly with an array.
723 // ProcessInts(absl::MakeConstSpan(array));
724 //
725 // // Call with a contiguous container.
726 // std::vector<int> some_ints = ...;
727 // ProcessInts(absl::MakeConstSpan(some_ints));
728 // ProcessInts(absl::MakeConstSpan(std::vector<int>{ 0, 0, 0 }));
729 //
730 template <int&... ExplicitArgumentBarrier, typename T>
MakeConstSpan(absl::Nullable<T * > ptr,size_t size)731 constexpr Span<const T> MakeConstSpan(absl::Nullable<T*> ptr,
732 size_t size) noexcept {
733 return Span<const T>(ptr, size);
734 }
735
736 template <int&... ExplicitArgumentBarrier, typename T>
MakeConstSpan(absl::Nullable<T * > begin,absl::Nullable<T * > end)737 Span<const T> MakeConstSpan(absl::Nullable<T*> begin,
738 absl::Nullable<T*> end) noexcept {
739 return ABSL_HARDENING_ASSERT(begin <= end), Span<const T>(begin, end - begin);
740 }
741
742 template <int&... ExplicitArgumentBarrier, typename C>
743 constexpr auto MakeConstSpan(const C& c) noexcept -> decltype(MakeSpan(c)) {
744 return MakeSpan(c);
745 }
746
747 template <int&... ExplicitArgumentBarrier, typename T, size_t N>
MakeConstSpan(const T (& array)[N])748 constexpr Span<const T> MakeConstSpan(const T (&array)[N]) noexcept {
749 return Span<const T>(array, N);
750 }
751 ABSL_NAMESPACE_END
752 } // namespace absl
753 #endif // ABSL_TYPES_SPAN_H_
754