-- 1c1d6e2404dfc6caa022b335df5acdac6da50fe1 by Derek Mauro <dmauro@google.com>: Fix the internal namespacing in unaligned_access.h PiperOrigin-RevId: 215434506 -- 17d4400aebf025a230690fc1c7a968ef8d85bbba by Eric Fiselier <ericwf@google.com>: gtest depends on the GCC extension allowing variadic macros to be passed a empty parameter pack for ..., but LLVM diagnoses this as a GNU extension. This patch suppresses the warning when building the absl tests. PiperOrigin-RevId: 215426161 -- f2c49dde23a9f445b9de963f1bbe840ebb568b30 by Eric Fiselier <ericwf@google.com>: Use EXPECT_DEATH_IF_SUPPORTED instead of EXPECT_DEATH. This avoids breaking the test when gtest doesn't support death tests. PiperOrigin-RevId: 215423849 -- cd687c1e121709603f4fc3726b534f6a9c52cc89 by Eric Fiselier <ericwf@google.com>: Disable LLVM's -Wmissing-variable-declarations in tests. GCC's configuration already disables this via -Wno-missing-declarations, this change makes LLVM do the same. The warning would otherwise flag most tests which use ABSL_FLAG. PiperOrigin-RevId: 215407429 -- d14098824c84e3a8c8f6fb920e0335fb48fe2010 by Eric Fiselier <ericwf@google.com>: Fix local variable shadowing in city hash implementation. PiperOrigin-RevId: 215407249 -- 4b5e140ba743f0d231790a26c49083abb4329e2c by Abseil Team <absl-team@google.com>: Make raw_hash_set::reserve 2X fast when reserve doesn't do any allocation. Make raw_hash_set::reserve ~1% faster when reserve does some (128~4k) allocation. PiperOrigin-RevId: 215348727 -- 461161e65e04b801480aa117af2534c594654ccf by Eric Fiselier <ericwf@google.com>: Internal change PiperOrigin-RevId: 215272283 -- 50413ae31ad3d3a177257416acd8ede47a17bff2 by Eric Fiselier <ericwf@google.com>: Internal Change PiperOrigin-RevId: 215233183 -- 477be54c43d61019a8fe4e190e340eb52737d383 by Abseil Team <absl-team@google.com>: Clarify misleading comment on ABSL_ATTRIBUTE_UNUSED PiperOrigin-RevId: 215185496 -- 2cafa2b5287507d3a946682aee9ab13af6d471c9 by Matt Kulukundis <kfm@google.com>: Add support for absl::Hash to various absl in types. PiperOrigin-RevId: 215039569 -- 082248901991aa3d29be0ea3689c7f213cf0fd83 by Derek Mauro <dmauro@google.com>: Remove an instance of HAS_GLOBAL_STRING from hash_function_defaults.h PiperOrigin-RevId: 214989094 -- b929f61907f0786a6133e3a9d7287e339c0a0acb by Derek Mauro <dmauro@google.com>: Internal import of Github #174 Fix code snippet in comment https://github.com/abseil/abseil-cpp/pull/174 PiperOrigin-RevId: 214958849 -- f2c5e829eca11c352e121f56eefbf87083305023 by Derek Mauro <dmauro@google.com>: Internal import of GitHub #173 Fix CMake build for absl::container. https://github.com/abseil/abseil-cpp/pull/173 PiperOrigin-RevId: 214957796 -- d704f860f9fddafb99e34e6c5032e49f73874e10 by Abseil Team <absl-team@google.com>: Internal change PiperOrigin-RevId: 214828181 GitOrigin-RevId: 1c1d6e2404dfc6caa022b335df5acdac6da50fe1 Change-Id: I551de2b1ba0cbaf6856cd5959358cf6651179dea
		
			
				
	
	
		
			762 lines
		
	
	
	
		
			26 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			762 lines
		
	
	
	
		
			26 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| //
 | |
| // Copyright 2017 The Abseil Authors.
 | |
| //
 | |
| // Licensed under the Apache License, Version 2.0 (the "License");
 | |
| // you may not use this file except in compliance with the License.
 | |
| // You may obtain a copy of the License at
 | |
| //
 | |
| //      http://www.apache.org/licenses/LICENSE-2.0
 | |
| //
 | |
| // Unless required by applicable law or agreed to in writing, software
 | |
| // distributed under the License is distributed on an "AS IS" BASIS,
 | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
| // See the License for the specific language governing permissions and
 | |
| // limitations under the License.
 | |
| //
 | |
| // -----------------------------------------------------------------------------
 | |
| // span.h
 | |
| // -----------------------------------------------------------------------------
 | |
| //
 | |
| // This header file defines a `Span<T>` type for holding a view of an existing
 | |
| // array of data. The `Span` object, much like the `absl::string_view` object,
 | |
| // does not own such data itself. A span provides a lightweight way to pass
 | |
| // around view of such data.
 | |
| //
 | |
| // Additionally, this header file defines `MakeSpan()` and `MakeConstSpan()`
 | |
| // factory functions, for clearly creating spans of type `Span<T>` or read-only
 | |
| // `Span<const T>` when such types may be difficult to identify due to issues
 | |
| // with implicit conversion.
 | |
| //
 | |
| // The C++ standards committee currently has a proposal for a `std::span` type,
 | |
| // (http://wg21.link/p0122), which is not yet part of the standard (though may
 | |
| // become part of C++20). As of August 2017, the differences between
 | |
| // `absl::Span` and this proposal are:
 | |
| //    * `absl::Span` uses `size_t` for `size_type`
 | |
| //    * `absl::Span` has no `operator()`
 | |
| //    * `absl::Span` has no constructors for `std::unique_ptr` or
 | |
| //      `std::shared_ptr`
 | |
| //    * `absl::Span` has the factory functions `MakeSpan()` and
 | |
| //      `MakeConstSpan()`
 | |
| //    * `absl::Span` has `front()` and `back()` methods
 | |
| //    * bounds-checked access to `absl::Span` is accomplished with `at()`
 | |
| //    * `absl::Span` has compiler-provided move and copy constructors and
 | |
| //      assignment. This is due to them being specified as `constexpr`, but that
 | |
| //      implies const in C++11.
 | |
| //    * `absl::Span` has no `element_type` or `index_type` typedefs
 | |
| //    * A read-only `absl::Span<const T>` can be implicitly constructed from an
 | |
| //      initializer list.
 | |
| //    * `absl::Span` has no `bytes()`, `size_bytes()`, `as_bytes()`, or
 | |
| //      `as_mutable_bytes()` methods
 | |
| //    * `absl::Span` has no static extent template parameter, nor constructors
 | |
| //      which exist only because of the static extent parameter.
 | |
| //    * `absl::Span` has an explicit mutable-reference constructor
 | |
| //
 | |
| // For more information, see the class comments below.
 | |
| #ifndef ABSL_TYPES_SPAN_H_
 | |
| #define ABSL_TYPES_SPAN_H_
 | |
| 
 | |
| #include <algorithm>
 | |
| #include <cassert>
 | |
| #include <cstddef>
 | |
| #include <initializer_list>
 | |
| #include <iterator>
 | |
| #include <string>
 | |
| #include <type_traits>
 | |
| #include <utility>
 | |
| 
 | |
| #include "absl/algorithm/algorithm.h"
 | |
| #include "absl/base/internal/throw_delegate.h"
 | |
| #include "absl/base/macros.h"
 | |
| #include "absl/base/optimization.h"
 | |
| #include "absl/base/port.h"
 | |
| #include "absl/meta/type_traits.h"
 | |
| 
 | |
| namespace absl {
 | |
| 
 | |
| template <typename T>
 | |
| class Span;
 | |
| 
 | |
| namespace span_internal {
 | |
| // A constexpr min function
 | |
| constexpr size_t Min(size_t a, size_t b) noexcept { return a < b ? a : b; }
 | |
| 
 | |
| // Wrappers for access to container data pointers.
 | |
| template <typename C>
 | |
| constexpr auto GetDataImpl(C& c, char) noexcept  // NOLINT(runtime/references)
 | |
|     -> decltype(c.data()) {
 | |
|   return c.data();
 | |
| }
 | |
| 
 | |
| // Before C++17, string::data returns a const char* in all cases.
 | |
| inline char* GetDataImpl(std::string& s,  // NOLINT(runtime/references)
 | |
|                          int) noexcept {
 | |
|   return &s[0];
 | |
| }
 | |
| 
 | |
| template <typename C>
 | |
| constexpr auto GetData(C& c) noexcept  // NOLINT(runtime/references)
 | |
|     -> decltype(GetDataImpl(c, 0)) {
 | |
|   return GetDataImpl(c, 0);
 | |
| }
 | |
| 
 | |
| // Detection idioms for size() and data().
 | |
| template <typename C>
 | |
| using HasSize =
 | |
|     std::is_integral<absl::decay_t<decltype(std::declval<C&>().size())>>;
 | |
| 
 | |
| // We want to enable conversion from vector<T*> to Span<const T* const> but
 | |
| // disable conversion from vector<Derived> to Span<Base>. Here we use
 | |
| // the fact that U** is convertible to Q* const* if and only if Q is the same
 | |
| // type or a more cv-qualified version of U.  We also decay the result type of
 | |
| // data() to avoid problems with classes which have a member function data()
 | |
| // which returns a reference.
 | |
| template <typename T, typename C>
 | |
| using HasData =
 | |
|     std::is_convertible<absl::decay_t<decltype(GetData(std::declval<C&>()))>*,
 | |
|                         T* const*>;
 | |
| 
 | |
| // Extracts value type from a Container
 | |
| template <typename C>
 | |
| struct ElementType {
 | |
|   using type = typename absl::remove_reference_t<C>::value_type;
 | |
| };
 | |
| 
 | |
| template <typename T, size_t N>
 | |
| struct ElementType<T (&)[N]> {
 | |
|   using type = T;
 | |
| };
 | |
| 
 | |
| template <typename C>
 | |
| using ElementT = typename ElementType<C>::type;
 | |
| 
 | |
| template <typename T>
 | |
| using EnableIfMutable =
 | |
|     typename std::enable_if<!std::is_const<T>::value, int>::type;
 | |
| 
 | |
| template <typename T>
 | |
| bool EqualImpl(Span<T> a, Span<T> b) {
 | |
|   static_assert(std::is_const<T>::value, "");
 | |
|   return absl::equal(a.begin(), a.end(), b.begin(), b.end());
 | |
| }
 | |
| 
 | |
| template <typename T>
 | |
| bool LessThanImpl(Span<T> a, Span<T> b) {
 | |
|   static_assert(std::is_const<T>::value, "");
 | |
|   return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end());
 | |
| }
 | |
| 
 | |
| // The `IsConvertible` classes here are needed because of the
 | |
| // `std::is_convertible` bug in libcxx when compiled with GCC. This build
 | |
| // configuration is used by Android NDK toolchain. Reference link:
 | |
| // https://bugs.llvm.org/show_bug.cgi?id=27538.
 | |
| template <typename From, typename To>
 | |
| struct IsConvertibleHelper {
 | |
|  private:
 | |
|   static std::true_type testval(To);
 | |
|   static std::false_type testval(...);
 | |
| 
 | |
|  public:
 | |
|   using type = decltype(testval(std::declval<From>()));
 | |
| };
 | |
| 
 | |
| template <typename From, typename To>
 | |
| struct IsConvertible : IsConvertibleHelper<From, To>::type {};
 | |
| 
 | |
| // TODO(zhangxy): replace `IsConvertible` with `std::is_convertible` once the
 | |
| // older version of libcxx is not supported.
 | |
| template <typename From, typename To>
 | |
| using EnableIfConvertibleToSpanConst =
 | |
|     typename std::enable_if<IsConvertible<From, Span<const To>>::value>::type;
 | |
| }  // namespace span_internal
 | |
| 
 | |
| //------------------------------------------------------------------------------
 | |
| // Span
 | |
| //------------------------------------------------------------------------------
 | |
| //
 | |
| // A `Span` is an "array view" type for holding a view of a contiguous data
 | |
| // array; the `Span` object does not and cannot own such data itself. A span
 | |
| // provides an easy way to provide overloads for anything operating on
 | |
| // contiguous sequences without needing to manage pointers and array lengths
 | |
| // manually.
 | |
| 
 | |
| // A span is conceptually a pointer (ptr) and a length (size) into an already
 | |
| // existing array of contiguous memory; the array it represents references the
 | |
| // elements "ptr[0] .. ptr[size-1]". Passing a properly-constructed `Span`
 | |
| // instead of raw pointers avoids many issues related to index out of bounds
 | |
| // errors.
 | |
| //
 | |
| // Spans may also be constructed from containers holding contiguous sequences.
 | |
| // Such containers must supply `data()` and `size() const` methods (e.g
 | |
| // `std::vector<T>`, `absl::InlinedVector<T, N>`). All implicit conversions to
 | |
| // `absl::Span` from such containers will create spans of type `const T`;
 | |
| // spans which can mutate their values (of type `T`) must use explicit
 | |
| // constructors.
 | |
| //
 | |
| // A `Span<T>` is somewhat analogous to an `absl::string_view`, but for an array
 | |
| // of elements of type `T`. A user of `Span` must ensure that the data being
 | |
| // pointed to outlives the `Span` itself.
 | |
| //
 | |
| // You can construct a `Span<T>` in several ways:
 | |
| //
 | |
| //   * Explicitly from a reference to a container type
 | |
| //   * Explicitly from a pointer and size
 | |
| //   * Implicitly from a container type (but only for spans of type `const T`)
 | |
| //   * Using the `MakeSpan()` or `MakeConstSpan()` factory functions.
 | |
| //
 | |
| // Examples:
 | |
| //
 | |
| //   // Construct a Span explicitly from a container:
 | |
| //   std::vector<int> v = {1, 2, 3, 4, 5};
 | |
| //   auto span = absl::Span<const int>(v);
 | |
| //
 | |
| //   // Construct a Span explicitly from a C-style array:
 | |
| //   int a[5] =  {1, 2, 3, 4, 5};
 | |
| //   auto span = absl::Span<const int>(a);
 | |
| //
 | |
| //   // Construct a Span implicitly from a container
 | |
| //   void MyRoutine(absl::Span<const int> a) {
 | |
| //     ...
 | |
| //   }
 | |
| //   std::vector v = {1,2,3,4,5};
 | |
| //   MyRoutine(v)                     // convert to Span<const T>
 | |
| //
 | |
| // Note that `Span` objects, in addition to requiring that the memory they
 | |
| // point to remains alive, must also ensure that such memory does not get
 | |
| // reallocated. Therefore, to avoid undefined behavior, containers with
 | |
| // associated span views should not invoke operations that may reallocate memory
 | |
| // (such as resizing) or invalidate iterators into the container.
 | |
| //
 | |
| // One common use for a `Span` is when passing arguments to a routine that can
 | |
| // accept a variety of array types (e.g. a `std::vector`, `absl::InlinedVector`,
 | |
| // a C-style array, etc.). Instead of creating overloads for each case, you
 | |
| // can simply specify a `Span` as the argument to such a routine.
 | |
| //
 | |
| // Example:
 | |
| //
 | |
| //   void MyRoutine(absl::Span<const int> a) {
 | |
| //     ...
 | |
| //   }
 | |
| //
 | |
| //   std::vector v = {1,2,3,4,5};
 | |
| //   MyRoutine(v);
 | |
| //
 | |
| //   absl::InlinedVector<int, 4> my_inline_vector;
 | |
| //   MyRoutine(my_inline_vector);
 | |
| //
 | |
| //   // Explicit constructor from pointer,size
 | |
| //   int* my_array = new int[10];
 | |
| //   MyRoutine(absl::Span<const int>(my_array, 10));
 | |
| template <typename T>
 | |
| class Span {
 | |
|  private:
 | |
|   // Used to determine whether a Span can be constructed from a container of
 | |
|   // type C.
 | |
|   template <typename C>
 | |
|   using EnableIfConvertibleFrom =
 | |
|       typename std::enable_if<span_internal::HasData<T, C>::value &&
 | |
|                               span_internal::HasSize<C>::value>::type;
 | |
| 
 | |
|   // Used to SFINAE-enable a function when the slice elements are const.
 | |
|   template <typename U>
 | |
|   using EnableIfConstView =
 | |
|       typename std::enable_if<std::is_const<T>::value, U>::type;
 | |
| 
 | |
|   // Used to SFINAE-enable a function when the slice elements are mutable.
 | |
|   template <typename U>
 | |
|   using EnableIfMutableView =
 | |
|       typename std::enable_if<!std::is_const<T>::value, U>::type;
 | |
| 
 | |
|  public:
 | |
|   using value_type = absl::remove_cv_t<T>;
 | |
|   using pointer = T*;
 | |
|   using const_pointer = const T*;
 | |
|   using reference = T&;
 | |
|   using const_reference = const T&;
 | |
|   using iterator = pointer;
 | |
|   using const_iterator = const_pointer;
 | |
|   using reverse_iterator = std::reverse_iterator<iterator>;
 | |
|   using const_reverse_iterator = std::reverse_iterator<const_iterator>;
 | |
|   using size_type = size_t;
 | |
|   using difference_type = ptrdiff_t;
 | |
| 
 | |
|   static const size_type npos = ~(size_type(0));
 | |
| 
 | |
|   constexpr Span() noexcept : Span(nullptr, 0) {}
 | |
|   constexpr Span(pointer array, size_type length) noexcept
 | |
|       : ptr_(array), len_(length) {}
 | |
| 
 | |
|   // Implicit conversion constructors
 | |
|   template <size_t N>
 | |
|   constexpr Span(T (&a)[N]) noexcept  // NOLINT(runtime/explicit)
 | |
|       : Span(a, N) {}
 | |
| 
 | |
|   // Explicit reference constructor for a mutable `Span<T>` type. Can be
 | |
|   // replaced with MakeSpan() to infer the type parameter.
 | |
|   template <typename V, typename = EnableIfConvertibleFrom<V>,
 | |
|             typename = EnableIfMutableView<V>>
 | |
|   explicit Span(V& v) noexcept  // NOLINT(runtime/references)
 | |
|       : Span(span_internal::GetData(v), v.size()) {}
 | |
| 
 | |
|   // Implicit reference constructor for a read-only `Span<const T>` type
 | |
|   template <typename V, typename = EnableIfConvertibleFrom<V>,
 | |
|             typename = EnableIfConstView<V>>
 | |
|   constexpr Span(const V& v) noexcept  // NOLINT(runtime/explicit)
 | |
|       : Span(span_internal::GetData(v), v.size()) {}
 | |
| 
 | |
|   // Implicit constructor from an initializer list, making it possible to pass a
 | |
|   // brace-enclosed initializer list to a function expecting a `Span`. Such
 | |
|   // spans constructed from an initializer list must be of type `Span<const T>`.
 | |
|   //
 | |
|   //   void Process(absl::Span<const int> x);
 | |
|   //   Process({1, 2, 3});
 | |
|   //
 | |
|   // Note that as always the array referenced by the span must outlive the span.
 | |
|   // Since an initializer list constructor acts as if it is fed a temporary
 | |
|   // array (cf. C++ standard [dcl.init.list]/5), it's safe to use this
 | |
|   // constructor only when the `std::initializer_list` itself outlives the span.
 | |
|   // In order to meet this requirement it's sufficient to ensure that neither
 | |
|   // the span nor a copy of it is used outside of the expression in which it's
 | |
|   // created:
 | |
|   //
 | |
|   //   // Assume that this function uses the array directly, not retaining any
 | |
|   //   // copy of the span or pointer to any of its elements.
 | |
|   //   void Process(absl::Span<const int> ints);
 | |
|   //
 | |
|   //   // Okay: the std::initializer_list<int> will reference a temporary array
 | |
|   //   // that isn't destroyed until after the call to Process returns.
 | |
|   //   Process({ 17, 19 });
 | |
|   //
 | |
|   //   // Not okay: the storage used by the std::initializer_list<int> is not
 | |
|   //   // allowed to be referenced after the first line.
 | |
|   //   absl::Span<const int> ints = { 17, 19 };
 | |
|   //   Process(ints);
 | |
|   //
 | |
|   //   // Not okay for the same reason as above: even when the elements of the
 | |
|   //   // initializer list expression are not temporaries the underlying array
 | |
|   //   // is, so the initializer list must still outlive the span.
 | |
|   //   const int foo = 17;
 | |
|   //   absl::Span<const int> ints = { foo };
 | |
|   //   Process(ints);
 | |
|   //
 | |
|   template <typename LazyT = T,
 | |
|             typename = EnableIfConstView<LazyT>>
 | |
|   Span(
 | |
|       std::initializer_list<value_type> v) noexcept  // NOLINT(runtime/explicit)
 | |
|       : Span(v.begin(), v.size()) {}
 | |
| 
 | |
|   // Accessors
 | |
| 
 | |
|   // Span::data()
 | |
|   //
 | |
|   // Returns a pointer to the span's underlying array of data (which is held
 | |
|   // outside the span).
 | |
|   constexpr pointer data() const noexcept { return ptr_; }
 | |
| 
 | |
|   // Span::size()
 | |
|   //
 | |
|   // Returns the size of this span.
 | |
|   constexpr size_type size() const noexcept { return len_; }
 | |
| 
 | |
|   // Span::length()
 | |
|   //
 | |
|   // Returns the length (size) of this span.
 | |
|   constexpr size_type length() const noexcept { return size(); }
 | |
| 
 | |
|   // Span::empty()
 | |
|   //
 | |
|   // Returns a boolean indicating whether or not this span is considered empty.
 | |
|   constexpr bool empty() const noexcept { return size() == 0; }
 | |
| 
 | |
|   // Span::operator[]
 | |
|   //
 | |
|   // Returns a reference to the i'th element of this span.
 | |
|   constexpr reference operator[](size_type i) const noexcept {
 | |
|     // MSVC 2015 accepts this as constexpr, but not ptr_[i]
 | |
|     return *(data() + i);
 | |
|   }
 | |
| 
 | |
|   // Span::at()
 | |
|   //
 | |
|   // Returns a reference to the i'th element of this span.
 | |
|   constexpr reference at(size_type i) const {
 | |
|     return ABSL_PREDICT_TRUE(i < size())  //
 | |
|                ? *(data() + i)
 | |
|                : (base_internal::ThrowStdOutOfRange(
 | |
|                       "Span::at failed bounds check"),
 | |
|                   *(data() + i));
 | |
|   }
 | |
| 
 | |
|   // Span::front()
 | |
|   //
 | |
|   // Returns a reference to the first element of this span.
 | |
|   constexpr reference front() const noexcept {
 | |
|     return ABSL_ASSERT(size() > 0), *data();
 | |
|   }
 | |
| 
 | |
|   // Span::back()
 | |
|   //
 | |
|   // Returns a reference to the last element of this span.
 | |
|   constexpr reference back() const noexcept {
 | |
|     return ABSL_ASSERT(size() > 0), *(data() + size() - 1);
 | |
|   }
 | |
| 
 | |
|   // Span::begin()
 | |
|   //
 | |
|   // Returns an iterator to the first element of this span.
 | |
|   constexpr iterator begin() const noexcept { return data(); }
 | |
| 
 | |
|   // Span::cbegin()
 | |
|   //
 | |
|   // Returns a const iterator to the first element of this span.
 | |
|   constexpr const_iterator cbegin() const noexcept { return begin(); }
 | |
| 
 | |
|   // Span::end()
 | |
|   //
 | |
|   // Returns an iterator to the last element of this span.
 | |
|   constexpr iterator end() const noexcept { return data() + size(); }
 | |
| 
 | |
|   // Span::cend()
 | |
|   //
 | |
|   // Returns a const iterator to the last element of this span.
 | |
|   constexpr const_iterator cend() const noexcept { return end(); }
 | |
| 
 | |
|   // Span::rbegin()
 | |
|   //
 | |
|   // Returns a reverse iterator starting at the last element of this span.
 | |
|   constexpr reverse_iterator rbegin() const noexcept {
 | |
|     return reverse_iterator(end());
 | |
|   }
 | |
| 
 | |
|   // Span::crbegin()
 | |
|   //
 | |
|   // Returns a reverse const iterator starting at the last element of this span.
 | |
|   constexpr const_reverse_iterator crbegin() const noexcept { return rbegin(); }
 | |
| 
 | |
|   // Span::rend()
 | |
|   //
 | |
|   // Returns a reverse iterator starting at the first element of this span.
 | |
|   constexpr reverse_iterator rend() const noexcept {
 | |
|     return reverse_iterator(begin());
 | |
|   }
 | |
| 
 | |
|   // Span::crend()
 | |
|   //
 | |
|   // Returns a reverse iterator starting at the first element of this span.
 | |
|   constexpr const_reverse_iterator crend() const noexcept { return rend(); }
 | |
| 
 | |
|   // Span mutations
 | |
| 
 | |
|   // Span::remove_prefix()
 | |
|   //
 | |
|   // Removes the first `n` elements from the span.
 | |
|   void remove_prefix(size_type n) noexcept {
 | |
|     assert(size() >= n);
 | |
|     ptr_ += n;
 | |
|     len_ -= n;
 | |
|   }
 | |
| 
 | |
|   // Span::remove_suffix()
 | |
|   //
 | |
|   // Removes the last `n` elements from the span.
 | |
|   void remove_suffix(size_type n) noexcept {
 | |
|     assert(size() >= n);
 | |
|     len_ -= n;
 | |
|   }
 | |
| 
 | |
|   // Span::subspan()
 | |
|   //
 | |
|   // Returns a `Span` starting at element `pos` and of length `len`. Both `pos`
 | |
|   // and `len` are of type `size_type` and thus non-negative. Parameter `pos`
 | |
|   // must be <= size(). Any `len` value that points past the end of the span
 | |
|   // will be trimmed to at most size() - `pos`. A default `len` value of `npos`
 | |
|   // ensures the returned subspan continues until the end of the span.
 | |
|   //
 | |
|   // Examples:
 | |
|   //
 | |
|   //   std::vector<int> vec = {10, 11, 12, 13};
 | |
|   //   absl::MakeSpan(vec).subspan(1, 2);  // {11, 12}
 | |
|   //   absl::MakeSpan(vec).subspan(2, 8);  // {12, 13}
 | |
|   //   absl::MakeSpan(vec).subspan(1);     // {11, 12, 13}
 | |
|   //   absl::MakeSpan(vec).subspan(4);     // {}
 | |
|   //   absl::MakeSpan(vec).subspan(5);     // throws std::out_of_range
 | |
|   constexpr Span subspan(size_type pos = 0, size_type len = npos) const {
 | |
|     return (pos <= size())
 | |
|                ? Span(data() + pos, span_internal::Min(size() - pos, len))
 | |
|                : (base_internal::ThrowStdOutOfRange("pos > size()"), Span());
 | |
|   }
 | |
| 
 | |
|   // Support for absl::Hash.
 | |
|   template <typename H>
 | |
|   friend H AbslHashValue(H h, Span v) {
 | |
|     return H::combine(H::combine_contiguous(std::move(h), v.data(), v.size()),
 | |
|                       v.size());
 | |
|   }
 | |
| 
 | |
|  private:
 | |
|   pointer ptr_;
 | |
|   size_type len_;
 | |
| };
 | |
| 
 | |
| template <typename T>
 | |
| const typename Span<T>::size_type Span<T>::npos;
 | |
| 
 | |
| // Span relationals
 | |
| 
 | |
| // Equality is compared element-by-element, while ordering is lexicographical.
 | |
| // We provide three overloads for each operator to cover any combination on the
 | |
| // left or right hand side of mutable Span<T>, read-only Span<const T>, and
 | |
| // convertible-to-read-only Span<T>.
 | |
| // TODO(zhangxy): Due to MSVC overload resolution bug with partial ordering
 | |
| // template functions, 5 overloads per operator is needed as a workaround. We
 | |
| // should update them to 3 overloads per operator using non-deduced context like
 | |
| // string_view, i.e.
 | |
| // - (Span<T>, Span<T>)
 | |
| // - (Span<T>, non_deduced<Span<const T>>)
 | |
| // - (non_deduced<Span<const T>>, Span<T>)
 | |
| 
 | |
| // operator==
 | |
| template <typename T>
 | |
| bool operator==(Span<T> a, Span<T> b) {
 | |
|   return span_internal::EqualImpl<const T>(a, b);
 | |
| }
 | |
| template <typename T>
 | |
| bool operator==(Span<const T> a, Span<T> b) {
 | |
|   return span_internal::EqualImpl<const T>(a, b);
 | |
| }
 | |
| template <typename T>
 | |
| bool operator==(Span<T> a, Span<const T> b) {
 | |
|   return span_internal::EqualImpl<const T>(a, b);
 | |
| }
 | |
| template <typename T, typename U,
 | |
|           typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
 | |
| bool operator==(const U& a, Span<T> b) {
 | |
|   return span_internal::EqualImpl<const T>(a, b);
 | |
| }
 | |
| template <typename T, typename U,
 | |
|           typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
 | |
| bool operator==(Span<T> a, const U& b) {
 | |
|   return span_internal::EqualImpl<const T>(a, b);
 | |
| }
 | |
| 
 | |
| // operator!=
 | |
| template <typename T>
 | |
| bool operator!=(Span<T> a, Span<T> b) {
 | |
|   return !(a == b);
 | |
| }
 | |
| template <typename T>
 | |
| bool operator!=(Span<const T> a, Span<T> b) {
 | |
|   return !(a == b);
 | |
| }
 | |
| template <typename T>
 | |
| bool operator!=(Span<T> a, Span<const T> b) {
 | |
|   return !(a == b);
 | |
| }
 | |
| template <typename T, typename U,
 | |
|           typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
 | |
| bool operator!=(const U& a, Span<T> b) {
 | |
|   return !(a == b);
 | |
| }
 | |
| template <typename T, typename U,
 | |
|           typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
 | |
| bool operator!=(Span<T> a, const U& b) {
 | |
|   return !(a == b);
 | |
| }
 | |
| 
 | |
| // operator<
 | |
| template <typename T>
 | |
| bool operator<(Span<T> a, Span<T> b) {
 | |
|   return span_internal::LessThanImpl<const T>(a, b);
 | |
| }
 | |
| template <typename T>
 | |
| bool operator<(Span<const T> a, Span<T> b) {
 | |
|   return span_internal::LessThanImpl<const T>(a, b);
 | |
| }
 | |
| template <typename T>
 | |
| bool operator<(Span<T> a, Span<const T> b) {
 | |
|   return span_internal::LessThanImpl<const T>(a, b);
 | |
| }
 | |
| template <typename T, typename U,
 | |
|           typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
 | |
| bool operator<(const U& a, Span<T> b) {
 | |
|   return span_internal::LessThanImpl<const T>(a, b);
 | |
| }
 | |
| template <typename T, typename U,
 | |
|           typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
 | |
| bool operator<(Span<T> a, const U& b) {
 | |
|   return span_internal::LessThanImpl<const T>(a, b);
 | |
| }
 | |
| 
 | |
| // operator>
 | |
| template <typename T>
 | |
| bool operator>(Span<T> a, Span<T> b) {
 | |
|   return b < a;
 | |
| }
 | |
| template <typename T>
 | |
| bool operator>(Span<const T> a, Span<T> b) {
 | |
|   return b < a;
 | |
| }
 | |
| template <typename T>
 | |
| bool operator>(Span<T> a, Span<const T> b) {
 | |
|   return b < a;
 | |
| }
 | |
| template <typename T, typename U,
 | |
|           typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
 | |
| bool operator>(const U& a, Span<T> b) {
 | |
|   return b < a;
 | |
| }
 | |
| template <typename T, typename U,
 | |
|           typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
 | |
| bool operator>(Span<T> a, const U& b) {
 | |
|   return b < a;
 | |
| }
 | |
| 
 | |
| // operator<=
 | |
| template <typename T>
 | |
| bool operator<=(Span<T> a, Span<T> b) {
 | |
|   return !(b < a);
 | |
| }
 | |
| template <typename T>
 | |
| bool operator<=(Span<const T> a, Span<T> b) {
 | |
|   return !(b < a);
 | |
| }
 | |
| template <typename T>
 | |
| bool operator<=(Span<T> a, Span<const T> b) {
 | |
|   return !(b < a);
 | |
| }
 | |
| template <typename T, typename U,
 | |
|           typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
 | |
| bool operator<=(const U& a, Span<T> b) {
 | |
|   return !(b < a);
 | |
| }
 | |
| template <typename T, typename U,
 | |
|           typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
 | |
| bool operator<=(Span<T> a, const U& b) {
 | |
|   return !(b < a);
 | |
| }
 | |
| 
 | |
| // operator>=
 | |
| template <typename T>
 | |
| bool operator>=(Span<T> a, Span<T> b) {
 | |
|   return !(a < b);
 | |
| }
 | |
| template <typename T>
 | |
| bool operator>=(Span<const T> a, Span<T> b) {
 | |
|   return !(a < b);
 | |
| }
 | |
| template <typename T>
 | |
| bool operator>=(Span<T> a, Span<const T> b) {
 | |
|   return !(a < b);
 | |
| }
 | |
| template <typename T, typename U,
 | |
|           typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
 | |
| bool operator>=(const U& a, Span<T> b) {
 | |
|   return !(a < b);
 | |
| }
 | |
| template <typename T, typename U,
 | |
|           typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
 | |
| bool operator>=(Span<T> a, const U& b) {
 | |
|   return !(a < b);
 | |
| }
 | |
| 
 | |
| // MakeSpan()
 | |
| //
 | |
| // Constructs a mutable `Span<T>`, deducing `T` automatically from either a
 | |
| // container or pointer+size.
 | |
| //
 | |
| // Because a read-only `Span<const T>` is implicitly constructed from container
 | |
| // types regardless of whether the container itself is a const container,
 | |
| // constructing mutable spans of type `Span<T>` from containers requires
 | |
| // explicit constructors. The container-accepting version of `MakeSpan()`
 | |
| // deduces the type of `T` by the constness of the pointer received from the
 | |
| // container's `data()` member. Similarly, the pointer-accepting version returns
 | |
| // a `Span<const T>` if `T` is `const`, and a `Span<T>` otherwise.
 | |
| //
 | |
| // Examples:
 | |
| //
 | |
| //   void MyRoutine(absl::Span<MyComplicatedType> a) {
 | |
| //     ...
 | |
| //   };
 | |
| //   // my_vector is a container of non-const types
 | |
| //   std::vector<MyComplicatedType> my_vector;
 | |
| //
 | |
| //   // Constructing a Span implicitly attempts to create a Span of type
 | |
| //   // `Span<const T>`
 | |
| //   MyRoutine(my_vector);                // error, type mismatch
 | |
| //
 | |
| //   // Explicitly constructing the Span is verbose
 | |
| //   MyRoutine(absl::Span<MyComplicatedType>(my_vector));
 | |
| //
 | |
| //   // Use MakeSpan() to make an absl::Span<T>
 | |
| //   MyRoutine(absl::MakeSpan(my_vector));
 | |
| //
 | |
| //   // Construct a span from an array ptr+size
 | |
| //   absl::Span<T> my_span() {
 | |
| //     return absl::MakeSpan(&array[0], num_elements_);
 | |
| //   }
 | |
| //
 | |
| template <int&... ExplicitArgumentBarrier, typename T>
 | |
| constexpr Span<T> MakeSpan(T* ptr, size_t size) noexcept {
 | |
|   return Span<T>(ptr, size);
 | |
| }
 | |
| 
 | |
| template <int&... ExplicitArgumentBarrier, typename T>
 | |
| Span<T> MakeSpan(T* begin, T* end) noexcept {
 | |
|   return ABSL_ASSERT(begin <= end), Span<T>(begin, end - begin);
 | |
| }
 | |
| 
 | |
| template <int&... ExplicitArgumentBarrier, typename C>
 | |
| constexpr auto MakeSpan(C& c) noexcept  // NOLINT(runtime/references)
 | |
|     -> decltype(absl::MakeSpan(span_internal::GetData(c), c.size())) {
 | |
|   return MakeSpan(span_internal::GetData(c), c.size());
 | |
| }
 | |
| 
 | |
| template <int&... ExplicitArgumentBarrier, typename T, size_t N>
 | |
| constexpr Span<T> MakeSpan(T (&array)[N]) noexcept {
 | |
|   return Span<T>(array, N);
 | |
| }
 | |
| 
 | |
| // MakeConstSpan()
 | |
| //
 | |
| // Constructs a `Span<const T>` as with `MakeSpan`, deducing `T` automatically,
 | |
| // but always returning a `Span<const T>`.
 | |
| //
 | |
| // Examples:
 | |
| //
 | |
| //   void ProcessInts(absl::Span<const int> some_ints);
 | |
| //
 | |
| //   // Call with a pointer and size.
 | |
| //   int array[3] = { 0, 0, 0 };
 | |
| //   ProcessInts(absl::MakeConstSpan(&array[0], 3));
 | |
| //
 | |
| //   // Call with a [begin, end) pair.
 | |
| //   ProcessInts(absl::MakeConstSpan(&array[0], &array[3]));
 | |
| //
 | |
| //   // Call directly with an array.
 | |
| //   ProcessInts(absl::MakeConstSpan(array));
 | |
| //
 | |
| //   // Call with a contiguous container.
 | |
| //   std::vector<int> some_ints = ...;
 | |
| //   ProcessInts(absl::MakeConstSpan(some_ints));
 | |
| //   ProcessInts(absl::MakeConstSpan(std::vector<int>{ 0, 0, 0 }));
 | |
| //
 | |
| template <int&... ExplicitArgumentBarrier, typename T>
 | |
| constexpr Span<const T> MakeConstSpan(T* ptr, size_t size) noexcept {
 | |
|   return Span<const T>(ptr, size);
 | |
| }
 | |
| 
 | |
| template <int&... ExplicitArgumentBarrier, typename T>
 | |
| Span<const T> MakeConstSpan(T* begin, T* end) noexcept {
 | |
|   return ABSL_ASSERT(begin <= end), Span<const T>(begin, end - begin);
 | |
| }
 | |
| 
 | |
| template <int&... ExplicitArgumentBarrier, typename C>
 | |
| constexpr auto MakeConstSpan(const C& c) noexcept -> decltype(MakeSpan(c)) {
 | |
|   return MakeSpan(c);
 | |
| }
 | |
| 
 | |
| template <int&... ExplicitArgumentBarrier, typename T, size_t N>
 | |
| constexpr Span<const T> MakeConstSpan(const T (&array)[N]) noexcept {
 | |
|   return Span<const T>(array, N);
 | |
| }
 | |
| }  // namespace absl
 | |
| #endif  // ABSL_TYPES_SPAN_H_
 |