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_