span.h
Go to the documentation of this file.
00001 //
00002 // Copyright 2017 The Abseil Authors.
00003 //
00004 // Licensed under the Apache License, Version 2.0 (the "License");
00005 // you may not use this file except in compliance with the License.
00006 // You may obtain a copy of the License at
00007 //
00008 //      https://www.apache.org/licenses/LICENSE-2.0
00009 //
00010 // Unless required by applicable law or agreed to in writing, software
00011 // distributed under the License is distributed on an "AS IS" BASIS,
00012 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013 // See the License for the specific language governing permissions and
00014 // limitations under the License.
00015 //
00016 // -----------------------------------------------------------------------------
00017 // span.h
00018 // -----------------------------------------------------------------------------
00019 //
00020 // This header file defines a `Span<T>` type for holding a view of an existing
00021 // array of data. The `Span` object, much like the `absl::string_view` object,
00022 // does not own such data itself. A span provides a lightweight way to pass
00023 // around view of such data.
00024 //
00025 // Additionally, this header file defines `MakeSpan()` and `MakeConstSpan()`
00026 // factory functions, for clearly creating spans of type `Span<T>` or read-only
00027 // `Span<const T>` when such types may be difficult to identify due to issues
00028 // with implicit conversion.
00029 //
00030 // The C++ standards committee currently has a proposal for a `std::span` type,
00031 // (http://wg21.link/p0122), which is not yet part of the standard (though may
00032 // become part of C++20). As of August 2017, the differences between
00033 // `absl::Span` and this proposal are:
00034 //    * `absl::Span` uses `size_t` for `size_type`
00035 //    * `absl::Span` has no `operator()`
00036 //    * `absl::Span` has no constructors for `std::unique_ptr` or
00037 //      `std::shared_ptr`
00038 //    * `absl::Span` has the factory functions `MakeSpan()` and
00039 //      `MakeConstSpan()`
00040 //    * `absl::Span` has `front()` and `back()` methods
00041 //    * bounds-checked access to `absl::Span` is accomplished with `at()`
00042 //    * `absl::Span` has compiler-provided move and copy constructors and
00043 //      assignment. This is due to them being specified as `constexpr`, but that
00044 //      implies const in C++11.
00045 //    * `absl::Span` has no `element_type` or `index_type` typedefs
00046 //    * A read-only `absl::Span<const T>` can be implicitly constructed from an
00047 //      initializer list.
00048 //    * `absl::Span` has no `bytes()`, `size_bytes()`, `as_bytes()`, or
00049 //      `as_mutable_bytes()` methods
00050 //    * `absl::Span` has no static extent template parameter, nor constructors
00051 //      which exist only because of the static extent parameter.
00052 //    * `absl::Span` has an explicit mutable-reference constructor
00053 //
00054 // For more information, see the class comments below.
00055 #ifndef ABSL_TYPES_SPAN_H_
00056 #define ABSL_TYPES_SPAN_H_
00057 
00058 #include <algorithm>
00059 #include <cassert>
00060 #include <cstddef>
00061 #include <initializer_list>
00062 #include <iterator>
00063 #include <type_traits>
00064 #include <utility>
00065 
00066 #include "absl/base/internal/throw_delegate.h"
00067 #include "absl/base/macros.h"
00068 #include "absl/base/optimization.h"
00069 #include "absl/base/port.h"    // TODO(strel): remove this include
00070 #include "absl/meta/type_traits.h"
00071 #include "absl/types/internal/span.h"
00072 
00073 namespace absl {
00074 
00075 //------------------------------------------------------------------------------
00076 // Span
00077 //------------------------------------------------------------------------------
00078 //
00079 // A `Span` is an "array view" type for holding a view of a contiguous data
00080 // array; the `Span` object does not and cannot own such data itself. A span
00081 // provides an easy way to provide overloads for anything operating on
00082 // contiguous sequences without needing to manage pointers and array lengths
00083 // manually.
00084 
00085 // A span is conceptually a pointer (ptr) and a length (size) into an already
00086 // existing array of contiguous memory; the array it represents references the
00087 // elements "ptr[0] .. ptr[size-1]". Passing a properly-constructed `Span`
00088 // instead of raw pointers avoids many issues related to index out of bounds
00089 // errors.
00090 //
00091 // Spans may also be constructed from containers holding contiguous sequences.
00092 // Such containers must supply `data()` and `size() const` methods (e.g
00093 // `std::vector<T>`, `absl::InlinedVector<T, N>`). All implicit conversions to
00094 // `absl::Span` from such containers will create spans of type `const T`;
00095 // spans which can mutate their values (of type `T`) must use explicit
00096 // constructors.
00097 //
00098 // A `Span<T>` is somewhat analogous to an `absl::string_view`, but for an array
00099 // of elements of type `T`. A user of `Span` must ensure that the data being
00100 // pointed to outlives the `Span` itself.
00101 //
00102 // You can construct a `Span<T>` in several ways:
00103 //
00104 //   * Explicitly from a reference to a container type
00105 //   * Explicitly from a pointer and size
00106 //   * Implicitly from a container type (but only for spans of type `const T`)
00107 //   * Using the `MakeSpan()` or `MakeConstSpan()` factory functions.
00108 //
00109 // Examples:
00110 //
00111 //   // Construct a Span explicitly from a container:
00112 //   std::vector<int> v = {1, 2, 3, 4, 5};
00113 //   auto span = absl::Span<const int>(v);
00114 //
00115 //   // Construct a Span explicitly from a C-style array:
00116 //   int a[5] =  {1, 2, 3, 4, 5};
00117 //   auto span = absl::Span<const int>(a);
00118 //
00119 //   // Construct a Span implicitly from a container
00120 //   void MyRoutine(absl::Span<const int> a) {
00121 //     ...
00122 //   }
00123 //   std::vector v = {1,2,3,4,5};
00124 //   MyRoutine(v)                     // convert to Span<const T>
00125 //
00126 // Note that `Span` objects, in addition to requiring that the memory they
00127 // point to remains alive, must also ensure that such memory does not get
00128 // reallocated. Therefore, to avoid undefined behavior, containers with
00129 // associated span views should not invoke operations that may reallocate memory
00130 // (such as resizing) or invalidate iterators into the container.
00131 //
00132 // One common use for a `Span` is when passing arguments to a routine that can
00133 // accept a variety of array types (e.g. a `std::vector`, `absl::InlinedVector`,
00134 // a C-style array, etc.). Instead of creating overloads for each case, you
00135 // can simply specify a `Span` as the argument to such a routine.
00136 //
00137 // Example:
00138 //
00139 //   void MyRoutine(absl::Span<const int> a) {
00140 //     ...
00141 //   }
00142 //
00143 //   std::vector v = {1,2,3,4,5};
00144 //   MyRoutine(v);
00145 //
00146 //   absl::InlinedVector<int, 4> my_inline_vector;
00147 //   MyRoutine(my_inline_vector);
00148 //
00149 //   // Explicit constructor from pointer,size
00150 //   int* my_array = new int[10];
00151 //   MyRoutine(absl::Span<const int>(my_array, 10));
00152 template <typename T>
00153 class Span {
00154  private:
00155   // Used to determine whether a Span can be constructed from a container of
00156   // type C.
00157   template <typename C>
00158   using EnableIfConvertibleFrom =
00159       typename std::enable_if<span_internal::HasData<T, C>::value &&
00160                               span_internal::HasSize<C>::value>::type;
00161 
00162   // Used to SFINAE-enable a function when the slice elements are const.
00163   template <typename U>
00164   using EnableIfConstView =
00165       typename std::enable_if<std::is_const<T>::value, U>::type;
00166 
00167   // Used to SFINAE-enable a function when the slice elements are mutable.
00168   template <typename U>
00169   using EnableIfMutableView =
00170       typename std::enable_if<!std::is_const<T>::value, U>::type;
00171 
00172  public:
00173   using value_type = absl::remove_cv_t<T>;
00174   using pointer = T*;
00175   using const_pointer = const T*;
00176   using reference = T&;
00177   using const_reference = const T&;
00178   using iterator = pointer;
00179   using const_iterator = const_pointer;
00180   using reverse_iterator = std::reverse_iterator<iterator>;
00181   using const_reverse_iterator = std::reverse_iterator<const_iterator>;
00182   using size_type = size_t;
00183   using difference_type = ptrdiff_t;
00184 
00185   static const size_type npos = ~(size_type(0));
00186 
00187   constexpr Span() noexcept : Span(nullptr, 0) {}
00188   constexpr Span(pointer array, size_type length) noexcept
00189       : ptr_(array), len_(length) {}
00190 
00191   // Implicit conversion constructors
00192   template <size_t N>
00193   constexpr Span(T (&a)[N]) noexcept  // NOLINT(runtime/explicit)
00194       : Span(a, N) {}
00195 
00196   // Explicit reference constructor for a mutable `Span<T>` type. Can be
00197   // replaced with MakeSpan() to infer the type parameter.
00198   template <typename V, typename = EnableIfConvertibleFrom<V>,
00199             typename = EnableIfMutableView<V>>
00200   explicit Span(V& v) noexcept  // NOLINT(runtime/references)
00201       : Span(span_internal::GetData(v), v.size()) {}
00202 
00203   // Implicit reference constructor for a read-only `Span<const T>` type
00204   template <typename V, typename = EnableIfConvertibleFrom<V>,
00205             typename = EnableIfConstView<V>>
00206   constexpr Span(const V& v) noexcept  // NOLINT(runtime/explicit)
00207       : Span(span_internal::GetData(v), v.size()) {}
00208 
00209   // Implicit constructor from an initializer list, making it possible to pass a
00210   // brace-enclosed initializer list to a function expecting a `Span`. Such
00211   // spans constructed from an initializer list must be of type `Span<const T>`.
00212   //
00213   //   void Process(absl::Span<const int> x);
00214   //   Process({1, 2, 3});
00215   //
00216   // Note that as always the array referenced by the span must outlive the span.
00217   // Since an initializer list constructor acts as if it is fed a temporary
00218   // array (cf. C++ standard [dcl.init.list]/5), it's safe to use this
00219   // constructor only when the `std::initializer_list` itself outlives the span.
00220   // In order to meet this requirement it's sufficient to ensure that neither
00221   // the span nor a copy of it is used outside of the expression in which it's
00222   // created:
00223   //
00224   //   // Assume that this function uses the array directly, not retaining any
00225   //   // copy of the span or pointer to any of its elements.
00226   //   void Process(absl::Span<const int> ints);
00227   //
00228   //   // Okay: the std::initializer_list<int> will reference a temporary array
00229   //   // that isn't destroyed until after the call to Process returns.
00230   //   Process({ 17, 19 });
00231   //
00232   //   // Not okay: the storage used by the std::initializer_list<int> is not
00233   //   // allowed to be referenced after the first line.
00234   //   absl::Span<const int> ints = { 17, 19 };
00235   //   Process(ints);
00236   //
00237   //   // Not okay for the same reason as above: even when the elements of the
00238   //   // initializer list expression are not temporaries the underlying array
00239   //   // is, so the initializer list must still outlive the span.
00240   //   const int foo = 17;
00241   //   absl::Span<const int> ints = { foo };
00242   //   Process(ints);
00243   //
00244   template <typename LazyT = T,
00245             typename = EnableIfConstView<LazyT>>
00246   Span(
00247       std::initializer_list<value_type> v) noexcept  // NOLINT(runtime/explicit)
00248       : Span(v.begin(), v.size()) {}
00249 
00250   // Accessors
00251 
00252   // Span::data()
00253   //
00254   // Returns a pointer to the span's underlying array of data (which is held
00255   // outside the span).
00256   constexpr pointer data() const noexcept { return ptr_; }
00257 
00258   // Span::size()
00259   //
00260   // Returns the size of this span.
00261   constexpr size_type size() const noexcept { return len_; }
00262 
00263   // Span::length()
00264   //
00265   // Returns the length (size) of this span.
00266   constexpr size_type length() const noexcept { return size(); }
00267 
00268   // Span::empty()
00269   //
00270   // Returns a boolean indicating whether or not this span is considered empty.
00271   constexpr bool empty() const noexcept { return size() == 0; }
00272 
00273   // Span::operator[]
00274   //
00275   // Returns a reference to the i'th element of this span.
00276   constexpr reference operator[](size_type i) const noexcept {
00277     // MSVC 2015 accepts this as constexpr, but not ptr_[i]
00278     return *(data() + i);
00279   }
00280 
00281   // Span::at()
00282   //
00283   // Returns a reference to the i'th element of this span.
00284   constexpr reference at(size_type i) const {
00285     return ABSL_PREDICT_TRUE(i < size())  //
00286                ? *(data() + i)
00287                : (base_internal::ThrowStdOutOfRange(
00288                       "Span::at failed bounds check"),
00289                   *(data() + i));
00290   }
00291 
00292   // Span::front()
00293   //
00294   // Returns a reference to the first element of this span.
00295   constexpr reference front() const noexcept {
00296     return ABSL_ASSERT(size() > 0), *data();
00297   }
00298 
00299   // Span::back()
00300   //
00301   // Returns a reference to the last element of this span.
00302   constexpr reference back() const noexcept {
00303     return ABSL_ASSERT(size() > 0), *(data() + size() - 1);
00304   }
00305 
00306   // Span::begin()
00307   //
00308   // Returns an iterator to the first element of this span.
00309   constexpr iterator begin() const noexcept { return data(); }
00310 
00311   // Span::cbegin()
00312   //
00313   // Returns a const iterator to the first element of this span.
00314   constexpr const_iterator cbegin() const noexcept { return begin(); }
00315 
00316   // Span::end()
00317   //
00318   // Returns an iterator to the last element of this span.
00319   constexpr iterator end() const noexcept { return data() + size(); }
00320 
00321   // Span::cend()
00322   //
00323   // Returns a const iterator to the last element of this span.
00324   constexpr const_iterator cend() const noexcept { return end(); }
00325 
00326   // Span::rbegin()
00327   //
00328   // Returns a reverse iterator starting at the last element of this span.
00329   constexpr reverse_iterator rbegin() const noexcept {
00330     return reverse_iterator(end());
00331   }
00332 
00333   // Span::crbegin()
00334   //
00335   // Returns a reverse const iterator starting at the last element of this span.
00336   constexpr const_reverse_iterator crbegin() const noexcept { return rbegin(); }
00337 
00338   // Span::rend()
00339   //
00340   // Returns a reverse iterator starting at the first element of this span.
00341   constexpr reverse_iterator rend() const noexcept {
00342     return reverse_iterator(begin());
00343   }
00344 
00345   // Span::crend()
00346   //
00347   // Returns a reverse iterator starting at the first element of this span.
00348   constexpr const_reverse_iterator crend() const noexcept { return rend(); }
00349 
00350   // Span mutations
00351 
00352   // Span::remove_prefix()
00353   //
00354   // Removes the first `n` elements from the span.
00355   void remove_prefix(size_type n) noexcept {
00356     assert(size() >= n);
00357     ptr_ += n;
00358     len_ -= n;
00359   }
00360 
00361   // Span::remove_suffix()
00362   //
00363   // Removes the last `n` elements from the span.
00364   void remove_suffix(size_type n) noexcept {
00365     assert(size() >= n);
00366     len_ -= n;
00367   }
00368 
00369   // Span::subspan()
00370   //
00371   // Returns a `Span` starting at element `pos` and of length `len`. Both `pos`
00372   // and `len` are of type `size_type` and thus non-negative. Parameter `pos`
00373   // must be <= size(). Any `len` value that points past the end of the span
00374   // will be trimmed to at most size() - `pos`. A default `len` value of `npos`
00375   // ensures the returned subspan continues until the end of the span.
00376   //
00377   // Examples:
00378   //
00379   //   std::vector<int> vec = {10, 11, 12, 13};
00380   //   absl::MakeSpan(vec).subspan(1, 2);  // {11, 12}
00381   //   absl::MakeSpan(vec).subspan(2, 8);  // {12, 13}
00382   //   absl::MakeSpan(vec).subspan(1);     // {11, 12, 13}
00383   //   absl::MakeSpan(vec).subspan(4);     // {}
00384   //   absl::MakeSpan(vec).subspan(5);     // throws std::out_of_range
00385   constexpr Span subspan(size_type pos = 0, size_type len = npos) const {
00386     return (pos <= size())
00387                ? Span(data() + pos, span_internal::Min(size() - pos, len))
00388                : (base_internal::ThrowStdOutOfRange("pos > size()"), Span());
00389   }
00390 
00391   // Span::first()
00392   //
00393   // Returns a `Span` containing first `len` elements. Parameter `len` is of
00394   // type `size_type` and thus non-negative. `len` value must be <= size().
00395   //
00396   // Examples:
00397   //
00398   //   std::vector<int> vec = {10, 11, 12, 13};
00399   //   absl::MakeSpan(vec).first(1);  // {10}
00400   //   absl::MakeSpan(vec).first(3);  // {10, 11, 12}
00401   //   absl::MakeSpan(vec).first(5);  // throws std::out_of_range
00402   constexpr Span first(size_type len) const {
00403     return (len <= size())
00404                ? Span(data(), len)
00405                : (base_internal::ThrowStdOutOfRange("len > size()"), Span());
00406   }
00407 
00408   // Span::last()
00409   //
00410   // Returns a `Span` containing last `len` elements. Parameter `len` is of
00411   // type `size_type` and thus non-negative. `len` value must be <= size().
00412   //
00413   // Examples:
00414   //
00415   //   std::vector<int> vec = {10, 11, 12, 13};
00416   //   absl::MakeSpan(vec).last(1);  // {13}
00417   //   absl::MakeSpan(vec).last(3);  // {11, 12, 13}
00418   //   absl::MakeSpan(vec).last(5);  // throws std::out_of_range
00419   constexpr Span last(size_type len) const {
00420     return (len <= size())
00421                ? Span(size() - len + data(), len)
00422                : (base_internal::ThrowStdOutOfRange("len > size()"), Span());
00423   }
00424 
00425   // Support for absl::Hash.
00426   template <typename H>
00427   friend H AbslHashValue(H h, Span v) {
00428     return H::combine(H::combine_contiguous(std::move(h), v.data(), v.size()),
00429                       v.size());
00430   }
00431 
00432  private:
00433   pointer ptr_;
00434   size_type len_;
00435 };
00436 
00437 template <typename T>
00438 const typename Span<T>::size_type Span<T>::npos;
00439 
00440 // Span relationals
00441 
00442 // Equality is compared element-by-element, while ordering is lexicographical.
00443 // We provide three overloads for each operator to cover any combination on the
00444 // left or right hand side of mutable Span<T>, read-only Span<const T>, and
00445 // convertible-to-read-only Span<T>.
00446 // TODO(zhangxy): Due to MSVC overload resolution bug with partial ordering
00447 // template functions, 5 overloads per operator is needed as a workaround. We
00448 // should update them to 3 overloads per operator using non-deduced context like
00449 // string_view, i.e.
00450 // - (Span<T>, Span<T>)
00451 // - (Span<T>, non_deduced<Span<const T>>)
00452 // - (non_deduced<Span<const T>>, Span<T>)
00453 
00454 // operator==
00455 template <typename T>
00456 bool operator==(Span<T> a, Span<T> b) {
00457   return span_internal::EqualImpl<Span, const T>(a, b);
00458 }
00459 template <typename T>
00460 bool operator==(Span<const T> a, Span<T> b) {
00461   return span_internal::EqualImpl<Span, const T>(a, b);
00462 }
00463 template <typename T>
00464 bool operator==(Span<T> a, Span<const T> b) {
00465   return span_internal::EqualImpl<Span, const T>(a, b);
00466 }
00467 template <
00468     typename T, typename U,
00469     typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
00470 bool operator==(const U& a, Span<T> b) {
00471   return span_internal::EqualImpl<Span, const T>(a, b);
00472 }
00473 template <
00474     typename T, typename U,
00475     typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
00476 bool operator==(Span<T> a, const U& b) {
00477   return span_internal::EqualImpl<Span, const T>(a, b);
00478 }
00479 
00480 // operator!=
00481 template <typename T>
00482 bool operator!=(Span<T> a, Span<T> b) {
00483   return !(a == b);
00484 }
00485 template <typename T>
00486 bool operator!=(Span<const T> a, Span<T> b) {
00487   return !(a == b);
00488 }
00489 template <typename T>
00490 bool operator!=(Span<T> a, Span<const T> b) {
00491   return !(a == b);
00492 }
00493 template <
00494     typename T, typename U,
00495     typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
00496 bool operator!=(const U& a, Span<T> b) {
00497   return !(a == b);
00498 }
00499 template <
00500     typename T, typename U,
00501     typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
00502 bool operator!=(Span<T> a, const U& b) {
00503   return !(a == b);
00504 }
00505 
00506 // operator<
00507 template <typename T>
00508 bool operator<(Span<T> a, Span<T> b) {
00509   return span_internal::LessThanImpl<Span, const T>(a, b);
00510 }
00511 template <typename T>
00512 bool operator<(Span<const T> a, Span<T> b) {
00513   return span_internal::LessThanImpl<Span, const T>(a, b);
00514 }
00515 template <typename T>
00516 bool operator<(Span<T> a, Span<const T> b) {
00517   return span_internal::LessThanImpl<Span, const T>(a, b);
00518 }
00519 template <
00520     typename T, typename U,
00521     typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
00522 bool operator<(const U& a, Span<T> b) {
00523   return span_internal::LessThanImpl<Span, const T>(a, b);
00524 }
00525 template <
00526     typename T, typename U,
00527     typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
00528 bool operator<(Span<T> a, const U& b) {
00529   return span_internal::LessThanImpl<Span, const T>(a, b);
00530 }
00531 
00532 // operator>
00533 template <typename T>
00534 bool operator>(Span<T> a, Span<T> b) {
00535   return b < a;
00536 }
00537 template <typename T>
00538 bool operator>(Span<const T> a, Span<T> b) {
00539   return b < a;
00540 }
00541 template <typename T>
00542 bool operator>(Span<T> a, Span<const T> b) {
00543   return b < a;
00544 }
00545 template <
00546     typename T, typename U,
00547     typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
00548 bool operator>(const U& a, Span<T> b) {
00549   return b < a;
00550 }
00551 template <
00552     typename T, typename U,
00553     typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
00554 bool operator>(Span<T> a, const U& b) {
00555   return b < a;
00556 }
00557 
00558 // operator<=
00559 template <typename T>
00560 bool operator<=(Span<T> a, Span<T> b) {
00561   return !(b < a);
00562 }
00563 template <typename T>
00564 bool operator<=(Span<const T> a, Span<T> b) {
00565   return !(b < a);
00566 }
00567 template <typename T>
00568 bool operator<=(Span<T> a, Span<const T> b) {
00569   return !(b < a);
00570 }
00571 template <
00572     typename T, typename U,
00573     typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
00574 bool operator<=(const U& a, Span<T> b) {
00575   return !(b < a);
00576 }
00577 template <
00578     typename T, typename U,
00579     typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
00580 bool operator<=(Span<T> a, const U& b) {
00581   return !(b < a);
00582 }
00583 
00584 // operator>=
00585 template <typename T>
00586 bool operator>=(Span<T> a, Span<T> b) {
00587   return !(a < b);
00588 }
00589 template <typename T>
00590 bool operator>=(Span<const T> a, Span<T> b) {
00591   return !(a < b);
00592 }
00593 template <typename T>
00594 bool operator>=(Span<T> a, Span<const T> b) {
00595   return !(a < b);
00596 }
00597 template <
00598     typename T, typename U,
00599     typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
00600 bool operator>=(const U& a, Span<T> b) {
00601   return !(a < b);
00602 }
00603 template <
00604     typename T, typename U,
00605     typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
00606 bool operator>=(Span<T> a, const U& b) {
00607   return !(a < b);
00608 }
00609 
00610 // MakeSpan()
00611 //
00612 // Constructs a mutable `Span<T>`, deducing `T` automatically from either a
00613 // container or pointer+size.
00614 //
00615 // Because a read-only `Span<const T>` is implicitly constructed from container
00616 // types regardless of whether the container itself is a const container,
00617 // constructing mutable spans of type `Span<T>` from containers requires
00618 // explicit constructors. The container-accepting version of `MakeSpan()`
00619 // deduces the type of `T` by the constness of the pointer received from the
00620 // container's `data()` member. Similarly, the pointer-accepting version returns
00621 // a `Span<const T>` if `T` is `const`, and a `Span<T>` otherwise.
00622 //
00623 // Examples:
00624 //
00625 //   void MyRoutine(absl::Span<MyComplicatedType> a) {
00626 //     ...
00627 //   };
00628 //   // my_vector is a container of non-const types
00629 //   std::vector<MyComplicatedType> my_vector;
00630 //
00631 //   // Constructing a Span implicitly attempts to create a Span of type
00632 //   // `Span<const T>`
00633 //   MyRoutine(my_vector);                // error, type mismatch
00634 //
00635 //   // Explicitly constructing the Span is verbose
00636 //   MyRoutine(absl::Span<MyComplicatedType>(my_vector));
00637 //
00638 //   // Use MakeSpan() to make an absl::Span<T>
00639 //   MyRoutine(absl::MakeSpan(my_vector));
00640 //
00641 //   // Construct a span from an array ptr+size
00642 //   absl::Span<T> my_span() {
00643 //     return absl::MakeSpan(&array[0], num_elements_);
00644 //   }
00645 //
00646 template <int&... ExplicitArgumentBarrier, typename T>
00647 constexpr Span<T> MakeSpan(T* ptr, size_t size) noexcept {
00648   return Span<T>(ptr, size);
00649 }
00650 
00651 template <int&... ExplicitArgumentBarrier, typename T>
00652 Span<T> MakeSpan(T* begin, T* end) noexcept {
00653   return ABSL_ASSERT(begin <= end), Span<T>(begin, end - begin);
00654 }
00655 
00656 template <int&... ExplicitArgumentBarrier, typename C>
00657 constexpr auto MakeSpan(C& c) noexcept  // NOLINT(runtime/references)
00658     -> decltype(absl::MakeSpan(span_internal::GetData(c), c.size())) {
00659   return MakeSpan(span_internal::GetData(c), c.size());
00660 }
00661 
00662 template <int&... ExplicitArgumentBarrier, typename T, size_t N>
00663 constexpr Span<T> MakeSpan(T (&array)[N]) noexcept {
00664   return Span<T>(array, N);
00665 }
00666 
00667 // MakeConstSpan()
00668 //
00669 // Constructs a `Span<const T>` as with `MakeSpan`, deducing `T` automatically,
00670 // but always returning a `Span<const T>`.
00671 //
00672 // Examples:
00673 //
00674 //   void ProcessInts(absl::Span<const int> some_ints);
00675 //
00676 //   // Call with a pointer and size.
00677 //   int array[3] = { 0, 0, 0 };
00678 //   ProcessInts(absl::MakeConstSpan(&array[0], 3));
00679 //
00680 //   // Call with a [begin, end) pair.
00681 //   ProcessInts(absl::MakeConstSpan(&array[0], &array[3]));
00682 //
00683 //   // Call directly with an array.
00684 //   ProcessInts(absl::MakeConstSpan(array));
00685 //
00686 //   // Call with a contiguous container.
00687 //   std::vector<int> some_ints = ...;
00688 //   ProcessInts(absl::MakeConstSpan(some_ints));
00689 //   ProcessInts(absl::MakeConstSpan(std::vector<int>{ 0, 0, 0 }));
00690 //
00691 template <int&... ExplicitArgumentBarrier, typename T>
00692 constexpr Span<const T> MakeConstSpan(T* ptr, size_t size) noexcept {
00693   return Span<const T>(ptr, size);
00694 }
00695 
00696 template <int&... ExplicitArgumentBarrier, typename T>
00697 Span<const T> MakeConstSpan(T* begin, T* end) noexcept {
00698   return ABSL_ASSERT(begin <= end), Span<const T>(begin, end - begin);
00699 }
00700 
00701 template <int&... ExplicitArgumentBarrier, typename C>
00702 constexpr auto MakeConstSpan(const C& c) noexcept -> decltype(MakeSpan(c)) {
00703   return MakeSpan(c);
00704 }
00705 
00706 template <int&... ExplicitArgumentBarrier, typename T, size_t N>
00707 constexpr Span<const T> MakeConstSpan(const T (&array)[N]) noexcept {
00708   return Span<const T>(array, N);
00709 }
00710 }  // namespace absl
00711 #endif  // ABSL_TYPES_SPAN_H_


abseil_cpp
Author(s):
autogenerated on Wed Jun 19 2019 19:42:15