Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 09:41:58

0001 //
0002 // Copyright 2017 The Abseil Authors.
0003 //
0004 // Licensed under the Apache License, Version 2.0 (the "License");
0005 // you may not use this file except in compliance with the License.
0006 // You may obtain a copy of the License at
0007 //
0008 //      https://www.apache.org/licenses/LICENSE-2.0
0009 //
0010 // Unless required by applicable law or agreed to in writing, software
0011 // distributed under the License is distributed on an "AS IS" BASIS,
0012 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0013 // See the License for the specific language governing permissions and
0014 // limitations under the License.
0015 //
0016 // -----------------------------------------------------------------------------
0017 // span.h
0018 // -----------------------------------------------------------------------------
0019 //
0020 // This header file defines a `Span<T>` type for holding a reference to existing
0021 // array data. The `Span` object, much like the `absl::string_view` object,
0022 // does not own such data itself, and the data being referenced by the span must
0023 // outlive the span itself. Unlike `view` type references, a span can hold a
0024 // reference to mutable data (and can mutate it for underlying types of
0025 // non-const T.) A span provides a lightweight way to pass a reference to such
0026 // data.
0027 //
0028 // Additionally, this header file defines `MakeSpan()` and `MakeConstSpan()`
0029 // factory functions, for clearly creating spans of type `Span<T>` or read-only
0030 // `Span<const T>` when such types may be difficult to identify due to issues
0031 // with implicit conversion.
0032 //
0033 // The C++20 draft standard includes a `std::span` type. As of June 2020, the
0034 // differences between `absl::Span` and `std::span` are:
0035 //    * `absl::Span` has `operator==` (which is likely a design bug,
0036 //       per https://abseil.io/blog/20180531-regular-types)
0037 //    * `absl::Span` has the factory functions `MakeSpan()` and
0038 //      `MakeConstSpan()`
0039 //    * bounds-checked access to `absl::Span` is accomplished with `at()`
0040 //    * `absl::Span` has compiler-provided move and copy constructors and
0041 //      assignment. This is due to them being specified as `constexpr`, but that
0042 //      implies const in C++11.
0043 //    * A read-only `absl::Span<const T>` can be implicitly constructed from an
0044 //      initializer list.
0045 //    * `absl::Span` has no `bytes()`, `size_bytes()`, `as_bytes()`, or
0046 //      `as_writable_bytes()` methods
0047 //    * `absl::Span` has no static extent template parameter, nor constructors
0048 //      which exist only because of the static extent parameter.
0049 //    * `absl::Span` has an explicit mutable-reference constructor
0050 //
0051 // For more information, see the class comments below.
0052 #ifndef ABSL_TYPES_SPAN_H_
0053 #define ABSL_TYPES_SPAN_H_
0054 
0055 #include <algorithm>
0056 #include <cassert>
0057 #include <cstddef>
0058 #include <initializer_list>
0059 #include <iterator>
0060 #include <type_traits>
0061 #include <utility>
0062 
0063 #include "absl/base/attributes.h"
0064 #include "absl/base/internal/throw_delegate.h"
0065 #include "absl/base/macros.h"
0066 #include "absl/base/nullability.h"
0067 #include "absl/base/optimization.h"
0068 #include "absl/base/port.h"    // TODO(strel): remove this include
0069 #include "absl/meta/type_traits.h"
0070 #include "absl/types/internal/span.h"
0071 
0072 namespace absl {
0073 ABSL_NAMESPACE_BEGIN
0074 
0075 //------------------------------------------------------------------------------
0076 // Span
0077 //------------------------------------------------------------------------------
0078 //
0079 // A `Span` is an "array reference" type for holding a reference of contiguous
0080 // array data; the `Span` object does not and cannot own such data itself. A
0081 // span provides an easy way to provide overloads for anything operating on
0082 // contiguous sequences without needing to manage pointers and array lengths
0083 // manually.
0084 
0085 // A span is conceptually a pointer (ptr) and a length (size) into an already
0086 // existing array of contiguous memory; the array it represents references the
0087 // elements "ptr[0] .. ptr[size-1]". Passing a properly-constructed `Span`
0088 // instead of raw pointers avoids many issues related to index out of bounds
0089 // errors.
0090 //
0091 // Spans may also be constructed from containers holding contiguous sequences.
0092 // Such containers must supply `data()` and `size() const` methods (e.g
0093 // `std::vector<T>`, `absl::InlinedVector<T, N>`). All implicit conversions to
0094 // `absl::Span` from such containers will create spans of type `const T`;
0095 // spans which can mutate their values (of type `T`) must use explicit
0096 // constructors.
0097 //
0098 // A `Span<T>` is somewhat analogous to an `absl::string_view`, but for an array
0099 // of elements of type `T`, and unlike an `absl::string_view`, a span can hold a
0100 // reference to mutable data. A user of `Span` must ensure that the data being
0101 // pointed to outlives the `Span` itself.
0102 //
0103 // You can construct a `Span<T>` in several ways:
0104 //
0105 //   * Explicitly from a reference to a container type
0106 //   * Explicitly from a pointer and size
0107 //   * Implicitly from a container type (but only for spans of type `const T`)
0108 //   * Using the `MakeSpan()` or `MakeConstSpan()` factory functions.
0109 //
0110 // Examples:
0111 //
0112 //   // Construct a Span explicitly from a container:
0113 //   std::vector<int> v = {1, 2, 3, 4, 5};
0114 //   auto span = absl::Span<const int>(v);
0115 //
0116 //   // Construct a Span explicitly from a C-style array:
0117 //   int a[5] =  {1, 2, 3, 4, 5};
0118 //   auto span = absl::Span<const int>(a);
0119 //
0120 //   // Construct a Span implicitly from a container
0121 //   void MyRoutine(absl::Span<const int> a) {
0122 //     ...
0123 //   }
0124 //   std::vector v = {1,2,3,4,5};
0125 //   MyRoutine(v)                     // convert to Span<const T>
0126 //
0127 // Note that `Span` objects, in addition to requiring that the memory they
0128 // point to remains alive, must also ensure that such memory does not get
0129 // reallocated. Therefore, to avoid undefined behavior, containers with
0130 // associated spans should not invoke operations that may reallocate memory
0131 // (such as resizing) or invalidate iterators into the container.
0132 //
0133 // One common use for a `Span` is when passing arguments to a routine that can
0134 // accept a variety of array types (e.g. a `std::vector`, `absl::InlinedVector`,
0135 // a C-style array, etc.). Instead of creating overloads for each case, you
0136 // can simply specify a `Span` as the argument to such a routine.
0137 //
0138 // Example:
0139 //
0140 //   void MyRoutine(absl::Span<const int> a) {
0141 //     ...
0142 //   }
0143 //
0144 //   std::vector v = {1,2,3,4,5};
0145 //   MyRoutine(v);
0146 //
0147 //   absl::InlinedVector<int, 4> my_inline_vector;
0148 //   MyRoutine(my_inline_vector);
0149 //
0150 //   // Explicit constructor from pointer,size
0151 //   int* my_array = new int[10];
0152 //   MyRoutine(absl::Span<const int>(my_array, 10));
0153 template <typename T>
0154 class ABSL_INTERNAL_ATTRIBUTE_VIEW Span {
0155  private:
0156   // Used to determine whether a Span can be constructed from a container of
0157   // type C.
0158   template <typename C>
0159   using EnableIfConvertibleFrom =
0160       typename std::enable_if<span_internal::HasData<T, C>::value &&
0161                               span_internal::HasSize<C>::value>::type;
0162 
0163   // Used to SFINAE-enable a function when the slice elements are const.
0164   template <typename U>
0165   using EnableIfValueIsConst =
0166       typename std::enable_if<std::is_const<T>::value, U>::type;
0167 
0168   // Used to SFINAE-enable a function when the slice elements are mutable.
0169   template <typename U>
0170   using EnableIfValueIsMutable =
0171       typename std::enable_if<!std::is_const<T>::value, U>::type;
0172 
0173  public:
0174   using element_type = T;
0175   using value_type = absl::remove_cv_t<T>;
0176   // TODO(b/316099902) - pointer should be Nullable<T*>, but this makes it hard
0177   // to recognize foreach loops as safe.
0178   using pointer = T*;
0179   using const_pointer = const T*;
0180   using reference = T&;
0181   using const_reference = const T&;
0182   using iterator = pointer;
0183   using const_iterator = const_pointer;
0184   using reverse_iterator = std::reverse_iterator<iterator>;
0185   using const_reverse_iterator = std::reverse_iterator<const_iterator>;
0186   using size_type = size_t;
0187   using difference_type = ptrdiff_t;
0188   using absl_internal_is_view = std::true_type;
0189 
0190   static const size_type npos = ~(size_type(0));
0191 
0192   constexpr Span() noexcept : Span(nullptr, 0) {}
0193   constexpr Span(pointer array, size_type length) noexcept
0194       : ptr_(array), len_(length) {}
0195 
0196   // Implicit conversion constructors
0197   template <size_t N>
0198   constexpr Span(T (&a)[N]) noexcept  // NOLINT(runtime/explicit)
0199       : Span(a, N) {}
0200 
0201   // Explicit reference constructor for a mutable `Span<T>` type. Can be
0202   // replaced with MakeSpan() to infer the type parameter.
0203   template <typename V, typename = EnableIfConvertibleFrom<V>,
0204             typename = EnableIfValueIsMutable<V>,
0205             typename = span_internal::EnableIfNotIsView<V>>
0206   explicit Span(
0207       V& v
0208           ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept  // NOLINT(runtime/references)
0209       : Span(span_internal::GetData(v), v.size()) {}
0210 
0211   // Implicit reference constructor for a read-only `Span<const T>` type
0212   template <typename V, typename = EnableIfConvertibleFrom<V>,
0213             typename = EnableIfValueIsConst<V>,
0214             typename = span_internal::EnableIfNotIsView<V>>
0215   constexpr Span(
0216       const V& v
0217           ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept  // NOLINT(runtime/explicit)
0218       : Span(span_internal::GetData(v), v.size()) {}
0219 
0220   // Overloads of the above two functions that are only enabled for view types.
0221   // This is so we can drop the ABSL_ATTRIBUTE_LIFETIME_BOUND annotation. These
0222   // overloads must be made unique by using a different template parameter list
0223   // (hence the = 0 for the IsView enabler).
0224   template <typename V, typename = EnableIfConvertibleFrom<V>,
0225             typename = EnableIfValueIsMutable<V>,
0226             span_internal::EnableIfIsView<V> = 0>
0227   explicit Span(V& v) noexcept  // NOLINT(runtime/references)
0228       : Span(span_internal::GetData(v), v.size()) {}
0229   template <typename V, typename = EnableIfConvertibleFrom<V>,
0230             typename = EnableIfValueIsConst<V>,
0231             span_internal::EnableIfIsView<V> = 0>
0232   constexpr Span(const V& v) noexcept  // NOLINT(runtime/explicit)
0233       : Span(span_internal::GetData(v), v.size()) {}
0234 
0235   // Implicit constructor from an initializer list, making it possible to pass a
0236   // brace-enclosed initializer list to a function expecting a `Span`. Such
0237   // spans constructed from an initializer list must be of type `Span<const T>`.
0238   //
0239   //   void Process(absl::Span<const int> x);
0240   //   Process({1, 2, 3});
0241   //
0242   // Note that as always the array referenced by the span must outlive the span.
0243   // Since an initializer list constructor acts as if it is fed a temporary
0244   // array (cf. C++ standard [dcl.init.list]/5), it's safe to use this
0245   // constructor only when the `std::initializer_list` itself outlives the span.
0246   // In order to meet this requirement it's sufficient to ensure that neither
0247   // the span nor a copy of it is used outside of the expression in which it's
0248   // created:
0249   //
0250   //   // Assume that this function uses the array directly, not retaining any
0251   //   // copy of the span or pointer to any of its elements.
0252   //   void Process(absl::Span<const int> ints);
0253   //
0254   //   // Okay: the std::initializer_list<int> will reference a temporary array
0255   //   // that isn't destroyed until after the call to Process returns.
0256   //   Process({ 17, 19 });
0257   //
0258   //   // Not okay: the storage used by the std::initializer_list<int> is not
0259   //   // allowed to be referenced after the first line.
0260   //   absl::Span<const int> ints = { 17, 19 };
0261   //   Process(ints);
0262   //
0263   //   // Not okay for the same reason as above: even when the elements of the
0264   //   // initializer list expression are not temporaries the underlying array
0265   //   // is, so the initializer list must still outlive the span.
0266   //   const int foo = 17;
0267   //   absl::Span<const int> ints = { foo };
0268   //   Process(ints);
0269   //
0270   template <typename LazyT = T,
0271             typename = EnableIfValueIsConst<LazyT>>
0272   Span(std::initializer_list<value_type> v
0273            ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept  // NOLINT(runtime/explicit)
0274       : Span(v.begin(), v.size()) {}
0275 
0276   // Accessors
0277 
0278   // Span::data()
0279   //
0280   // Returns a pointer to the span's underlying array of data (which is held
0281   // outside the span).
0282   constexpr pointer data() const noexcept { return ptr_; }
0283 
0284   // Span::size()
0285   //
0286   // Returns the size of this span.
0287   constexpr size_type size() const noexcept { return len_; }
0288 
0289   // Span::length()
0290   //
0291   // Returns the length (size) of this span.
0292   constexpr size_type length() const noexcept { return size(); }
0293 
0294   // Span::empty()
0295   //
0296   // Returns a boolean indicating whether or not this span is considered empty.
0297   constexpr bool empty() const noexcept { return size() == 0; }
0298 
0299   // Span::operator[]
0300   //
0301   // Returns a reference to the i'th element of this span.
0302   constexpr reference operator[](size_type i) const noexcept {
0303     return ABSL_HARDENING_ASSERT(i < size()), ptr_[i];
0304   }
0305 
0306   // Span::at()
0307   //
0308   // Returns a reference to the i'th element of this span.
0309   constexpr reference at(size_type i) const {
0310     return ABSL_PREDICT_TRUE(i < size())  //
0311                ? *(data() + i)
0312                : (base_internal::ThrowStdOutOfRange(
0313                       "Span::at failed bounds check"),
0314                   *(data() + i));
0315   }
0316 
0317   // Span::front()
0318   //
0319   // Returns a reference to the first element of this span. The span must not
0320   // be empty.
0321   constexpr reference front() const noexcept {
0322     return ABSL_HARDENING_ASSERT(size() > 0), *data();
0323   }
0324 
0325   // Span::back()
0326   //
0327   // Returns a reference to the last element of this span. The span must not
0328   // be empty.
0329   constexpr reference back() const noexcept {
0330     return ABSL_HARDENING_ASSERT(size() > 0), *(data() + size() - 1);
0331   }
0332 
0333   // Span::begin()
0334   //
0335   // Returns an iterator pointing to the first element of this span, or `end()`
0336   // if the span is empty.
0337   constexpr iterator begin() const noexcept { return data(); }
0338 
0339   // Span::cbegin()
0340   //
0341   // Returns a const iterator pointing to the first element of this span, or
0342   // `end()` if the span is empty.
0343   constexpr const_iterator cbegin() const noexcept { return begin(); }
0344 
0345   // Span::end()
0346   //
0347   // Returns an iterator pointing just beyond the last element at the
0348   // end of this span. This iterator acts as a placeholder; attempting to
0349   // access it results in undefined behavior.
0350   constexpr iterator end() const noexcept { return data() + size(); }
0351 
0352   // Span::cend()
0353   //
0354   // Returns a const iterator pointing just beyond the last element at the
0355   // end of this span. This iterator acts as a placeholder; attempting to
0356   // access it results in undefined behavior.
0357   constexpr const_iterator cend() const noexcept { return end(); }
0358 
0359   // Span::rbegin()
0360   //
0361   // Returns a reverse iterator pointing to the last element at the end of this
0362   // span, or `rend()` if the span is empty.
0363   constexpr reverse_iterator rbegin() const noexcept {
0364     return reverse_iterator(end());
0365   }
0366 
0367   // Span::crbegin()
0368   //
0369   // Returns a const reverse iterator pointing to the last element at the end of
0370   // this span, or `crend()` if the span is empty.
0371   constexpr const_reverse_iterator crbegin() const noexcept { return rbegin(); }
0372 
0373   // Span::rend()
0374   //
0375   // Returns a reverse iterator pointing just before the first element
0376   // at the beginning of this span. This pointer acts as a placeholder;
0377   // attempting to access its element results in undefined behavior.
0378   constexpr reverse_iterator rend() const noexcept {
0379     return reverse_iterator(begin());
0380   }
0381 
0382   // Span::crend()
0383   //
0384   // Returns a reverse const iterator pointing just before the first element
0385   // at the beginning of this span. This pointer acts as a placeholder;
0386   // attempting to access its element results in undefined behavior.
0387   constexpr const_reverse_iterator crend() const noexcept { return rend(); }
0388 
0389   // Span mutations
0390 
0391   // Span::remove_prefix()
0392   //
0393   // Removes the first `n` elements from the span.
0394   void remove_prefix(size_type n) noexcept {
0395     ABSL_HARDENING_ASSERT(size() >= n);
0396     ptr_ += n;
0397     len_ -= n;
0398   }
0399 
0400   // Span::remove_suffix()
0401   //
0402   // Removes the last `n` elements from the span.
0403   void remove_suffix(size_type n) noexcept {
0404     ABSL_HARDENING_ASSERT(size() >= n);
0405     len_ -= n;
0406   }
0407 
0408   // Span::subspan()
0409   //
0410   // Returns a `Span` starting at element `pos` and of length `len`. Both `pos`
0411   // and `len` are of type `size_type` and thus non-negative. Parameter `pos`
0412   // must be <= size(). Any `len` value that points past the end of the span
0413   // will be trimmed to at most size() - `pos`. A default `len` value of `npos`
0414   // ensures the returned subspan continues until the end of the span.
0415   //
0416   // Examples:
0417   //
0418   //   std::vector<int> vec = {10, 11, 12, 13};
0419   //   absl::MakeSpan(vec).subspan(1, 2);  // {11, 12}
0420   //   absl::MakeSpan(vec).subspan(2, 8);  // {12, 13}
0421   //   absl::MakeSpan(vec).subspan(1);     // {11, 12, 13}
0422   //   absl::MakeSpan(vec).subspan(4);     // {}
0423   //   absl::MakeSpan(vec).subspan(5);     // throws std::out_of_range
0424   constexpr Span subspan(size_type pos = 0, size_type len = npos) const {
0425     return (pos <= size())
0426                ? Span(data() + pos, (std::min)(size() - pos, len))
0427                : (base_internal::ThrowStdOutOfRange("pos > size()"), Span());
0428   }
0429 
0430   // Span::first()
0431   //
0432   // Returns a `Span` containing first `len` elements. Parameter `len` is of
0433   // type `size_type` and thus non-negative. `len` value must be <= size().
0434   //
0435   // Examples:
0436   //
0437   //   std::vector<int> vec = {10, 11, 12, 13};
0438   //   absl::MakeSpan(vec).first(1);  // {10}
0439   //   absl::MakeSpan(vec).first(3);  // {10, 11, 12}
0440   //   absl::MakeSpan(vec).first(5);  // throws std::out_of_range
0441   constexpr Span first(size_type len) const {
0442     return (len <= size())
0443                ? Span(data(), len)
0444                : (base_internal::ThrowStdOutOfRange("len > size()"), Span());
0445   }
0446 
0447   // Span::last()
0448   //
0449   // Returns a `Span` containing last `len` elements. Parameter `len` is of
0450   // type `size_type` and thus non-negative. `len` value must be <= size().
0451   //
0452   // Examples:
0453   //
0454   //   std::vector<int> vec = {10, 11, 12, 13};
0455   //   absl::MakeSpan(vec).last(1);  // {13}
0456   //   absl::MakeSpan(vec).last(3);  // {11, 12, 13}
0457   //   absl::MakeSpan(vec).last(5);  // throws std::out_of_range
0458   constexpr Span last(size_type len) const {
0459     return (len <= size())
0460                ? Span(size() - len + data(), len)
0461                : (base_internal::ThrowStdOutOfRange("len > size()"), Span());
0462   }
0463 
0464   // Support for absl::Hash.
0465   template <typename H>
0466   friend H AbslHashValue(H h, Span v) {
0467     return H::combine(H::combine_contiguous(std::move(h), v.data(), v.size()),
0468                       v.size());
0469   }
0470 
0471  private:
0472   pointer ptr_;
0473   size_type len_;
0474 };
0475 
0476 template <typename T>
0477 const typename Span<T>::size_type Span<T>::npos;
0478 
0479 // Span relationals
0480 
0481 // Equality is compared element-by-element, while ordering is lexicographical.
0482 // We provide three overloads for each operator to cover any combination on the
0483 // left or right hand side of mutable Span<T>, read-only Span<const T>, and
0484 // convertible-to-read-only Span<T>.
0485 // TODO(zhangxy): Due to MSVC overload resolution bug with partial ordering
0486 // template functions, 5 overloads per operator is needed as a workaround. We
0487 // should update them to 3 overloads per operator using non-deduced context like
0488 // string_view, i.e.
0489 // - (Span<T>, Span<T>)
0490 // - (Span<T>, non_deduced<Span<const T>>)
0491 // - (non_deduced<Span<const T>>, Span<T>)
0492 
0493 // operator==
0494 template <typename T>
0495 bool operator==(Span<T> a, Span<T> b) {
0496   return span_internal::EqualImpl<Span, const T>(a, b);
0497 }
0498 template <typename T>
0499 bool operator==(Span<const T> a, Span<T> b) {
0500   return span_internal::EqualImpl<Span, const T>(a, b);
0501 }
0502 template <typename T>
0503 bool operator==(Span<T> a, Span<const T> b) {
0504   return span_internal::EqualImpl<Span, const T>(a, b);
0505 }
0506 template <
0507     typename T, typename U,
0508     typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
0509 bool operator==(const U& a, Span<T> b) {
0510   return span_internal::EqualImpl<Span, const T>(a, b);
0511 }
0512 template <
0513     typename T, typename U,
0514     typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
0515 bool operator==(Span<T> a, const U& b) {
0516   return span_internal::EqualImpl<Span, const T>(a, b);
0517 }
0518 
0519 // operator!=
0520 template <typename T>
0521 bool operator!=(Span<T> a, Span<T> b) {
0522   return !(a == b);
0523 }
0524 template <typename T>
0525 bool operator!=(Span<const T> a, Span<T> b) {
0526   return !(a == b);
0527 }
0528 template <typename T>
0529 bool operator!=(Span<T> a, Span<const T> b) {
0530   return !(a == b);
0531 }
0532 template <
0533     typename T, typename U,
0534     typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
0535 bool operator!=(const U& a, Span<T> b) {
0536   return !(a == b);
0537 }
0538 template <
0539     typename T, typename U,
0540     typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
0541 bool operator!=(Span<T> a, const U& b) {
0542   return !(a == b);
0543 }
0544 
0545 // operator<
0546 template <typename T>
0547 bool operator<(Span<T> a, Span<T> b) {
0548   return span_internal::LessThanImpl<Span, const T>(a, b);
0549 }
0550 template <typename T>
0551 bool operator<(Span<const T> a, Span<T> b) {
0552   return span_internal::LessThanImpl<Span, const T>(a, b);
0553 }
0554 template <typename T>
0555 bool operator<(Span<T> a, Span<const T> b) {
0556   return span_internal::LessThanImpl<Span, const T>(a, b);
0557 }
0558 template <
0559     typename T, typename U,
0560     typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
0561 bool operator<(const U& a, Span<T> b) {
0562   return span_internal::LessThanImpl<Span, const T>(a, b);
0563 }
0564 template <
0565     typename T, typename U,
0566     typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
0567 bool operator<(Span<T> a, const U& b) {
0568   return span_internal::LessThanImpl<Span, const T>(a, b);
0569 }
0570 
0571 // operator>
0572 template <typename T>
0573 bool operator>(Span<T> a, Span<T> b) {
0574   return b < a;
0575 }
0576 template <typename T>
0577 bool operator>(Span<const T> a, Span<T> b) {
0578   return b < a;
0579 }
0580 template <typename T>
0581 bool operator>(Span<T> a, Span<const T> b) {
0582   return b < a;
0583 }
0584 template <
0585     typename T, typename U,
0586     typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
0587 bool operator>(const U& a, Span<T> b) {
0588   return b < a;
0589 }
0590 template <
0591     typename T, typename U,
0592     typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
0593 bool operator>(Span<T> a, const U& b) {
0594   return b < a;
0595 }
0596 
0597 // operator<=
0598 template <typename T>
0599 bool operator<=(Span<T> a, Span<T> b) {
0600   return !(b < a);
0601 }
0602 template <typename T>
0603 bool operator<=(Span<const T> a, Span<T> b) {
0604   return !(b < a);
0605 }
0606 template <typename T>
0607 bool operator<=(Span<T> a, Span<const T> b) {
0608   return !(b < a);
0609 }
0610 template <
0611     typename T, typename U,
0612     typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
0613 bool operator<=(const U& a, Span<T> b) {
0614   return !(b < a);
0615 }
0616 template <
0617     typename T, typename U,
0618     typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
0619 bool operator<=(Span<T> a, const U& b) {
0620   return !(b < a);
0621 }
0622 
0623 // operator>=
0624 template <typename T>
0625 bool operator>=(Span<T> a, Span<T> b) {
0626   return !(a < b);
0627 }
0628 template <typename T>
0629 bool operator>=(Span<const T> a, Span<T> b) {
0630   return !(a < b);
0631 }
0632 template <typename T>
0633 bool operator>=(Span<T> a, Span<const T> b) {
0634   return !(a < b);
0635 }
0636 template <
0637     typename T, typename U,
0638     typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
0639 bool operator>=(const U& a, Span<T> b) {
0640   return !(a < b);
0641 }
0642 template <
0643     typename T, typename U,
0644     typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
0645 bool operator>=(Span<T> a, const U& b) {
0646   return !(a < b);
0647 }
0648 
0649 // MakeSpan()
0650 //
0651 // Constructs a mutable `Span<T>`, deducing `T` automatically from either a
0652 // container or pointer+size.
0653 //
0654 // Because a read-only `Span<const T>` is implicitly constructed from container
0655 // types regardless of whether the container itself is a const container,
0656 // constructing mutable spans of type `Span<T>` from containers requires
0657 // explicit constructors. The container-accepting version of `MakeSpan()`
0658 // deduces the type of `T` by the constness of the pointer received from the
0659 // container's `data()` member. Similarly, the pointer-accepting version returns
0660 // a `Span<const T>` if `T` is `const`, and a `Span<T>` otherwise.
0661 //
0662 // Examples:
0663 //
0664 //   void MyRoutine(absl::Span<MyComplicatedType> a) {
0665 //     ...
0666 //   };
0667 //   // my_vector is a container of non-const types
0668 //   std::vector<MyComplicatedType> my_vector;
0669 //
0670 //   // Constructing a Span implicitly attempts to create a Span of type
0671 //   // `Span<const T>`
0672 //   MyRoutine(my_vector);                // error, type mismatch
0673 //
0674 //   // Explicitly constructing the Span is verbose
0675 //   MyRoutine(absl::Span<MyComplicatedType>(my_vector));
0676 //
0677 //   // Use MakeSpan() to make an absl::Span<T>
0678 //   MyRoutine(absl::MakeSpan(my_vector));
0679 //
0680 //   // Construct a span from an array ptr+size
0681 //   absl::Span<T> my_span() {
0682 //     return absl::MakeSpan(&array[0], num_elements_);
0683 //   }
0684 //
0685 template <int&... ExplicitArgumentBarrier, typename T>
0686 constexpr Span<T> MakeSpan(absl::Nullable<T*> ptr, size_t size) noexcept {
0687   return Span<T>(ptr, size);
0688 }
0689 
0690 template <int&... ExplicitArgumentBarrier, typename T>
0691 Span<T> MakeSpan(absl::Nullable<T*> begin, absl::Nullable<T*> end) noexcept {
0692   return ABSL_HARDENING_ASSERT(begin <= end),
0693          Span<T>(begin, static_cast<size_t>(end - begin));
0694 }
0695 
0696 template <int&... ExplicitArgumentBarrier, typename C>
0697 constexpr auto MakeSpan(C& c) noexcept  // NOLINT(runtime/references)
0698     -> decltype(absl::MakeSpan(span_internal::GetData(c), c.size())) {
0699   return MakeSpan(span_internal::GetData(c), c.size());
0700 }
0701 
0702 template <int&... ExplicitArgumentBarrier, typename T, size_t N>
0703 constexpr Span<T> MakeSpan(T (&array)[N]) noexcept {
0704   return Span<T>(array, N);
0705 }
0706 
0707 // MakeConstSpan()
0708 //
0709 // Constructs a `Span<const T>` as with `MakeSpan`, deducing `T` automatically,
0710 // but always returning a `Span<const T>`.
0711 //
0712 // Examples:
0713 //
0714 //   void ProcessInts(absl::Span<const int> some_ints);
0715 //
0716 //   // Call with a pointer and size.
0717 //   int array[3] = { 0, 0, 0 };
0718 //   ProcessInts(absl::MakeConstSpan(&array[0], 3));
0719 //
0720 //   // Call with a [begin, end) pair.
0721 //   ProcessInts(absl::MakeConstSpan(&array[0], &array[3]));
0722 //
0723 //   // Call directly with an array.
0724 //   ProcessInts(absl::MakeConstSpan(array));
0725 //
0726 //   // Call with a contiguous container.
0727 //   std::vector<int> some_ints = ...;
0728 //   ProcessInts(absl::MakeConstSpan(some_ints));
0729 //   ProcessInts(absl::MakeConstSpan(std::vector<int>{ 0, 0, 0 }));
0730 //
0731 template <int&... ExplicitArgumentBarrier, typename T>
0732 constexpr Span<const T> MakeConstSpan(absl::Nullable<T*> ptr,
0733                                       size_t size) noexcept {
0734   return Span<const T>(ptr, size);
0735 }
0736 
0737 template <int&... ExplicitArgumentBarrier, typename T>
0738 Span<const T> MakeConstSpan(absl::Nullable<T*> begin,
0739                             absl::Nullable<T*> end) noexcept {
0740   return ABSL_HARDENING_ASSERT(begin <= end), Span<const T>(begin, end - begin);
0741 }
0742 
0743 template <int&... ExplicitArgumentBarrier, typename C>
0744 constexpr auto MakeConstSpan(const C& c) noexcept -> decltype(MakeSpan(c)) {
0745   return MakeSpan(c);
0746 }
0747 
0748 template <int&... ExplicitArgumentBarrier, typename T, size_t N>
0749 constexpr Span<const T> MakeConstSpan(const T (&array)[N]) noexcept {
0750   return Span<const T>(array, N);
0751 }
0752 ABSL_NAMESPACE_END
0753 }  // namespace absl
0754 #endif  // ABSL_TYPES_SPAN_H_