• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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