span.h
Go to the documentation of this file.
1 //
2 // Copyright 2017 The Abseil Authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // https://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 // -----------------------------------------------------------------------------
17 // span.h
18 // -----------------------------------------------------------------------------
19 //
20 // This header file defines a `Span<T>` type for holding a view of an existing
21 // array of data. The `Span` object, much like the `absl::string_view` object,
22 // does not own such data itself. A span provides a lightweight way to pass
23 // around view of such data.
24 //
25 // Additionally, this header file defines `MakeSpan()` and `MakeConstSpan()`
26 // factory functions, for clearly creating spans of type `Span<T>` or read-only
27 // `Span<const T>` when such types may be difficult to identify due to issues
28 // with implicit conversion.
29 //
30 // The C++ standards committee currently has a proposal for a `std::span` type,
31 // (http://wg21.link/p0122), which is not yet part of the standard (though may
32 // become part of C++20). As of August 2017, the differences between
33 // `absl::Span` and this proposal are:
34 // * `absl::Span` uses `size_t` for `size_type`
35 // * `absl::Span` has no `operator()`
36 // * `absl::Span` has no constructors for `std::unique_ptr` or
37 // `std::shared_ptr`
38 // * `absl::Span` has the factory functions `MakeSpan()` and
39 // `MakeConstSpan()`
40 // * `absl::Span` has `front()` and `back()` methods
41 // * bounds-checked access to `absl::Span` is accomplished with `at()`
42 // * `absl::Span` has compiler-provided move and copy constructors and
43 // assignment. This is due to them being specified as `constexpr`, but that
44 // implies const in C++11.
45 // * `absl::Span` has no `element_type` or `index_type` typedefs
46 // * A read-only `absl::Span<const T>` can be implicitly constructed from an
47 // initializer list.
48 // * `absl::Span` has no `bytes()`, `size_bytes()`, `as_bytes()`, or
49 // `as_mutable_bytes()` methods
50 // * `absl::Span` has no static extent template parameter, nor constructors
51 // which exist only because of the static extent parameter.
52 // * `absl::Span` has an explicit mutable-reference constructor
53 //
54 // For more information, see the class comments below.
55 #ifndef ABSL_TYPES_SPAN_H_
56 #define ABSL_TYPES_SPAN_H_
57 
58 #include <algorithm>
59 #include <cassert>
60 #include <cstddef>
61 #include <initializer_list>
62 #include <iterator>
63 #include <type_traits>
64 #include <utility>
65 
67 #include "absl/base/macros.h"
68 #include "absl/base/optimization.h"
69 #include "absl/base/port.h" // TODO(strel): remove this include
70 #include "absl/meta/type_traits.h"
72 
73 namespace absl {
74 
75 //------------------------------------------------------------------------------
76 // Span
77 //------------------------------------------------------------------------------
78 //
79 // A `Span` is an "array view" type for holding a view of a contiguous data
80 // array; the `Span` object does not and cannot own such data itself. A span
81 // provides an easy way to provide overloads for anything operating on
82 // contiguous sequences without needing to manage pointers and array lengths
83 // manually.
84 
85 // A span is conceptually a pointer (ptr) and a length (size) into an already
86 // existing array of contiguous memory; the array it represents references the
87 // elements "ptr[0] .. ptr[size-1]". Passing a properly-constructed `Span`
88 // instead of raw pointers avoids many issues related to index out of bounds
89 // errors.
90 //
91 // Spans may also be constructed from containers holding contiguous sequences.
92 // Such containers must supply `data()` and `size() const` methods (e.g
93 // `std::vector<T>`, `absl::InlinedVector<T, N>`). All implicit conversions to
94 // `absl::Span` from such containers will create spans of type `const T`;
95 // spans which can mutate their values (of type `T`) must use explicit
96 // constructors.
97 //
98 // A `Span<T>` is somewhat analogous to an `absl::string_view`, but for an array
99 // of elements of type `T`. A user of `Span` must ensure that the data being
100 // pointed to outlives the `Span` itself.
101 //
102 // You can construct a `Span<T>` in several ways:
103 //
104 // * Explicitly from a reference to a container type
105 // * Explicitly from a pointer and size
106 // * Implicitly from a container type (but only for spans of type `const T`)
107 // * Using the `MakeSpan()` or `MakeConstSpan()` factory functions.
108 //
109 // Examples:
110 //
111 // // Construct a Span explicitly from a container:
112 // std::vector<int> v = {1, 2, 3, 4, 5};
113 // auto span = absl::Span<const int>(v);
114 //
115 // // Construct a Span explicitly from a C-style array:
116 // int a[5] = {1, 2, 3, 4, 5};
117 // auto span = absl::Span<const int>(a);
118 //
119 // // Construct a Span implicitly from a container
120 // void MyRoutine(absl::Span<const int> a) {
121 // ...
122 // }
123 // std::vector v = {1,2,3,4,5};
124 // MyRoutine(v) // convert to Span<const T>
125 //
126 // Note that `Span` objects, in addition to requiring that the memory they
127 // point to remains alive, must also ensure that such memory does not get
128 // reallocated. Therefore, to avoid undefined behavior, containers with
129 // associated span views should not invoke operations that may reallocate memory
130 // (such as resizing) or invalidate iterators into the container.
131 //
132 // One common use for a `Span` is when passing arguments to a routine that can
133 // accept a variety of array types (e.g. a `std::vector`, `absl::InlinedVector`,
134 // a C-style array, etc.). Instead of creating overloads for each case, you
135 // can simply specify a `Span` as the argument to such a routine.
136 //
137 // Example:
138 //
139 // void MyRoutine(absl::Span<const int> a) {
140 // ...
141 // }
142 //
143 // std::vector v = {1,2,3,4,5};
144 // MyRoutine(v);
145 //
146 // absl::InlinedVector<int, 4> my_inline_vector;
147 // MyRoutine(my_inline_vector);
148 //
149 // // Explicit constructor from pointer,size
150 // int* my_array = new int[10];
151 // MyRoutine(absl::Span<const int>(my_array, 10));
152 template <typename T>
153 class Span {
154  private:
155  // Used to determine whether a Span can be constructed from a container of
156  // type C.
157  template <typename C>
161 
162  // Used to SFINAE-enable a function when the slice elements are const.
163  template <typename U>
164  using EnableIfConstView =
166 
167  // Used to SFINAE-enable a function when the slice elements are mutable.
168  template <typename U>
169  using EnableIfMutableView =
171 
172  public:
174  using pointer = T*;
175  using const_pointer = const T*;
176  using reference = T&;
177  using const_reference = const T&;
178  using iterator = pointer;
180  using reverse_iterator = std::reverse_iterator<iterator>;
181  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
182  using size_type = size_t;
183  using difference_type = ptrdiff_t;
184 
185  static const size_type npos = ~(size_type(0));
186 
187  constexpr Span() noexcept : Span(nullptr, 0) {}
188  constexpr Span(pointer array, size_type length) noexcept
189  : ptr_(array), len_(length) {}
190 
191  // Implicit conversion constructors
192  template <size_t N>
193  constexpr Span(T (&a)[N]) noexcept // NOLINT(runtime/explicit)
194  : Span(a, N) {}
195 
196  // Explicit reference constructor for a mutable `Span<T>` type. Can be
197  // replaced with MakeSpan() to infer the type parameter.
198  template <typename V, typename = EnableIfConvertibleFrom<V>,
199  typename = EnableIfMutableView<V>>
200  explicit Span(V& v) noexcept // NOLINT(runtime/references)
201  : Span(span_internal::GetData(v), v.size()) {}
202 
203  // Implicit reference constructor for a read-only `Span<const T>` type
204  template <typename V, typename = EnableIfConvertibleFrom<V>,
205  typename = EnableIfConstView<V>>
206  constexpr Span(const V& v) noexcept // NOLINT(runtime/explicit)
207  : Span(span_internal::GetData(v), v.size()) {}
208 
209  // Implicit constructor from an initializer list, making it possible to pass a
210  // brace-enclosed initializer list to a function expecting a `Span`. Such
211  // spans constructed from an initializer list must be of type `Span<const T>`.
212  //
213  // void Process(absl::Span<const int> x);
214  // Process({1, 2, 3});
215  //
216  // Note that as always the array referenced by the span must outlive the span.
217  // Since an initializer list constructor acts as if it is fed a temporary
218  // array (cf. C++ standard [dcl.init.list]/5), it's safe to use this
219  // constructor only when the `std::initializer_list` itself outlives the span.
220  // In order to meet this requirement it's sufficient to ensure that neither
221  // the span nor a copy of it is used outside of the expression in which it's
222  // created:
223  //
224  // // Assume that this function uses the array directly, not retaining any
225  // // copy of the span or pointer to any of its elements.
226  // void Process(absl::Span<const int> ints);
227  //
228  // // Okay: the std::initializer_list<int> will reference a temporary array
229  // // that isn't destroyed until after the call to Process returns.
230  // Process({ 17, 19 });
231  //
232  // // Not okay: the storage used by the std::initializer_list<int> is not
233  // // allowed to be referenced after the first line.
234  // absl::Span<const int> ints = { 17, 19 };
235  // Process(ints);
236  //
237  // // Not okay for the same reason as above: even when the elements of the
238  // // initializer list expression are not temporaries the underlying array
239  // // is, so the initializer list must still outlive the span.
240  // const int foo = 17;
241  // absl::Span<const int> ints = { foo };
242  // Process(ints);
243  //
244  template <typename LazyT = T,
245  typename = EnableIfConstView<LazyT>>
247  std::initializer_list<value_type> v) noexcept // NOLINT(runtime/explicit)
248  : Span(v.begin(), v.size()) {}
249 
250  // Accessors
251 
252  // Span::data()
253  //
254  // Returns a pointer to the span's underlying array of data (which is held
255  // outside the span).
256  constexpr pointer data() const noexcept { return ptr_; }
257 
258  // Span::size()
259  //
260  // Returns the size of this span.
261  constexpr size_type size() const noexcept { return len_; }
262 
263  // Span::length()
264  //
265  // Returns the length (size) of this span.
266  constexpr size_type length() const noexcept { return size(); }
267 
268  // Span::empty()
269  //
270  // Returns a boolean indicating whether or not this span is considered empty.
271  constexpr bool empty() const noexcept { return size() == 0; }
272 
273  // Span::operator[]
274  //
275  // Returns a reference to the i'th element of this span.
276  constexpr reference operator[](size_type i) const noexcept {
277  // MSVC 2015 accepts this as constexpr, but not ptr_[i]
278  return *(data() + i);
279  }
280 
281  // Span::at()
282  //
283  // Returns a reference to the i'th element of this span.
284  constexpr reference at(size_type i) const {
285  return ABSL_PREDICT_TRUE(i < size()) //
286  ? *(data() + i)
288  "Span::at failed bounds check"),
289  *(data() + i));
290  }
291 
292  // Span::front()
293  //
294  // Returns a reference to the first element of this span.
295  constexpr reference front() const noexcept {
296  return ABSL_ASSERT(size() > 0), *data();
297  }
298 
299  // Span::back()
300  //
301  // Returns a reference to the last element of this span.
302  constexpr reference back() const noexcept {
303  return ABSL_ASSERT(size() > 0), *(data() + size() - 1);
304  }
305 
306  // Span::begin()
307  //
308  // Returns an iterator to the first element of this span.
309  constexpr iterator begin() const noexcept { return data(); }
310 
311  // Span::cbegin()
312  //
313  // Returns a const iterator to the first element of this span.
314  constexpr const_iterator cbegin() const noexcept { return begin(); }
315 
316  // Span::end()
317  //
318  // Returns an iterator to the last element of this span.
319  constexpr iterator end() const noexcept { return data() + size(); }
320 
321  // Span::cend()
322  //
323  // Returns a const iterator to the last element of this span.
324  constexpr const_iterator cend() const noexcept { return end(); }
325 
326  // Span::rbegin()
327  //
328  // Returns a reverse iterator starting at the last element of this span.
329  constexpr reverse_iterator rbegin() const noexcept {
330  return reverse_iterator(end());
331  }
332 
333  // Span::crbegin()
334  //
335  // Returns a reverse const iterator starting at the last element of this span.
336  constexpr const_reverse_iterator crbegin() const noexcept { return rbegin(); }
337 
338  // Span::rend()
339  //
340  // Returns a reverse iterator starting at the first element of this span.
341  constexpr reverse_iterator rend() const noexcept {
342  return reverse_iterator(begin());
343  }
344 
345  // Span::crend()
346  //
347  // Returns a reverse iterator starting at the first element of this span.
348  constexpr const_reverse_iterator crend() const noexcept { return rend(); }
349 
350  // Span mutations
351 
352  // Span::remove_prefix()
353  //
354  // Removes the first `n` elements from the span.
355  void remove_prefix(size_type n) noexcept {
356  assert(size() >= n);
357  ptr_ += n;
358  len_ -= n;
359  }
360 
361  // Span::remove_suffix()
362  //
363  // Removes the last `n` elements from the span.
364  void remove_suffix(size_type n) noexcept {
365  assert(size() >= n);
366  len_ -= n;
367  }
368 
369  // Span::subspan()
370  //
371  // Returns a `Span` starting at element `pos` and of length `len`. Both `pos`
372  // and `len` are of type `size_type` and thus non-negative. Parameter `pos`
373  // must be <= size(). Any `len` value that points past the end of the span
374  // will be trimmed to at most size() - `pos`. A default `len` value of `npos`
375  // ensures the returned subspan continues until the end of the span.
376  //
377  // Examples:
378  //
379  // std::vector<int> vec = {10, 11, 12, 13};
380  // absl::MakeSpan(vec).subspan(1, 2); // {11, 12}
381  // absl::MakeSpan(vec).subspan(2, 8); // {12, 13}
382  // absl::MakeSpan(vec).subspan(1); // {11, 12, 13}
383  // absl::MakeSpan(vec).subspan(4); // {}
384  // absl::MakeSpan(vec).subspan(5); // throws std::out_of_range
385  constexpr Span subspan(size_type pos = 0, size_type len = npos) const {
386  return (pos <= size())
387  ? Span(data() + pos, span_internal::Min(size() - pos, len))
388  : (base_internal::ThrowStdOutOfRange("pos > size()"), Span());
389  }
390 
391  // Span::first()
392  //
393  // Returns a `Span` containing first `len` elements. Parameter `len` is of
394  // type `size_type` and thus non-negative. `len` value must be <= size().
395  //
396  // Examples:
397  //
398  // std::vector<int> vec = {10, 11, 12, 13};
399  // absl::MakeSpan(vec).first(1); // {10}
400  // absl::MakeSpan(vec).first(3); // {10, 11, 12}
401  // absl::MakeSpan(vec).first(5); // throws std::out_of_range
402  constexpr Span first(size_type len) const {
403  return (len <= size())
404  ? Span(data(), len)
405  : (base_internal::ThrowStdOutOfRange("len > size()"), Span());
406  }
407 
408  // Span::last()
409  //
410  // Returns a `Span` containing last `len` elements. Parameter `len` is of
411  // type `size_type` and thus non-negative. `len` value must be <= size().
412  //
413  // Examples:
414  //
415  // std::vector<int> vec = {10, 11, 12, 13};
416  // absl::MakeSpan(vec).last(1); // {13}
417  // absl::MakeSpan(vec).last(3); // {11, 12, 13}
418  // absl::MakeSpan(vec).last(5); // throws std::out_of_range
419  constexpr Span last(size_type len) const {
420  return (len <= size())
421  ? Span(size() - len + data(), len)
422  : (base_internal::ThrowStdOutOfRange("len > size()"), Span());
423  }
424 
425  // Support for absl::Hash.
426  template <typename H>
427  friend H AbslHashValue(H h, Span v) {
428  return H::combine(H::combine_contiguous(std::move(h), v.data(), v.size()),
429  v.size());
430  }
431 
432  private:
435 };
436 
437 template <typename T>
438 const typename Span<T>::size_type Span<T>::npos;
439 
440 // Span relationals
441 
442 // Equality is compared element-by-element, while ordering is lexicographical.
443 // We provide three overloads for each operator to cover any combination on the
444 // left or right hand side of mutable Span<T>, read-only Span<const T>, and
445 // convertible-to-read-only Span<T>.
446 // TODO(zhangxy): Due to MSVC overload resolution bug with partial ordering
447 // template functions, 5 overloads per operator is needed as a workaround. We
448 // should update them to 3 overloads per operator using non-deduced context like
449 // string_view, i.e.
450 // - (Span<T>, Span<T>)
451 // - (Span<T>, non_deduced<Span<const T>>)
452 // - (non_deduced<Span<const T>>, Span<T>)
453 
454 // operator==
455 template <typename T>
457  return span_internal::EqualImpl<Span, const T>(a, b);
458 }
459 template <typename T>
461  return span_internal::EqualImpl<Span, const T>(a, b);
462 }
463 template <typename T>
464 bool operator==(Span<T> a, Span<const T> b) {
465  return span_internal::EqualImpl<Span, const T>(a, b);
466 }
467 template <
468  typename T, typename U,
470 bool operator==(const U& a, Span<T> b) {
471  return span_internal::EqualImpl<Span, const T>(a, b);
472 }
473 template <
474  typename T, typename U,
476 bool operator==(Span<T> a, const U& b) {
477  return span_internal::EqualImpl<Span, const T>(a, b);
478 }
479 
480 // operator!=
481 template <typename T>
483  return !(a == b);
484 }
485 template <typename T>
486 bool operator!=(Span<const T> a, Span<T> b) {
487  return !(a == b);
488 }
489 template <typename T>
490 bool operator!=(Span<T> a, Span<const T> b) {
491  return !(a == b);
492 }
493 template <
494  typename T, typename U,
496 bool operator!=(const U& a, Span<T> b) {
497  return !(a == b);
498 }
499 template <
500  typename T, typename U,
502 bool operator!=(Span<T> a, const U& b) {
503  return !(a == b);
504 }
505 
506 // operator<
507 template <typename T>
508 bool operator<(Span<T> a, Span<T> b) {
509  return span_internal::LessThanImpl<Span, const T>(a, b);
510 }
511 template <typename T>
512 bool operator<(Span<const T> a, Span<T> b) {
513  return span_internal::LessThanImpl<Span, const T>(a, b);
514 }
515 template <typename T>
516 bool operator<(Span<T> a, Span<const T> b) {
517  return span_internal::LessThanImpl<Span, const T>(a, b);
518 }
519 template <
520  typename T, typename U,
522 bool operator<(const U& a, Span<T> b) {
523  return span_internal::LessThanImpl<Span, const T>(a, b);
524 }
525 template <
526  typename T, typename U,
528 bool operator<(Span<T> a, const U& b) {
529  return span_internal::LessThanImpl<Span, const T>(a, b);
530 }
531 
532 // operator>
533 template <typename T>
535  return b < a;
536 }
537 template <typename T>
538 bool operator>(Span<const T> a, Span<T> b) {
539  return b < a;
540 }
541 template <typename T>
542 bool operator>(Span<T> a, Span<const T> b) {
543  return b < a;
544 }
545 template <
546  typename T, typename U,
548 bool operator>(const U& a, Span<T> b) {
549  return b < a;
550 }
551 template <
552  typename T, typename U,
554 bool operator>(Span<T> a, const U& b) {
555  return b < a;
556 }
557 
558 // operator<=
559 template <typename T>
560 bool operator<=(Span<T> a, Span<T> b) {
561  return !(b < a);
562 }
563 template <typename T>
564 bool operator<=(Span<const T> a, Span<T> b) {
565  return !(b < a);
566 }
567 template <typename T>
568 bool operator<=(Span<T> a, Span<const T> b) {
569  return !(b < a);
570 }
571 template <
572  typename T, typename U,
574 bool operator<=(const U& a, Span<T> b) {
575  return !(b < a);
576 }
577 template <
578  typename T, typename U,
580 bool operator<=(Span<T> a, const U& b) {
581  return !(b < a);
582 }
583 
584 // operator>=
585 template <typename T>
587  return !(a < b);
588 }
589 template <typename T>
590 bool operator>=(Span<const T> a, Span<T> b) {
591  return !(a < b);
592 }
593 template <typename T>
594 bool operator>=(Span<T> a, Span<const T> b) {
595  return !(a < b);
596 }
597 template <
598  typename T, typename U,
600 bool operator>=(const U& a, Span<T> b) {
601  return !(a < b);
602 }
603 template <
604  typename T, typename U,
606 bool operator>=(Span<T> a, const U& b) {
607  return !(a < b);
608 }
609 
610 // MakeSpan()
611 //
612 // Constructs a mutable `Span<T>`, deducing `T` automatically from either a
613 // container or pointer+size.
614 //
615 // Because a read-only `Span<const T>` is implicitly constructed from container
616 // types regardless of whether the container itself is a const container,
617 // constructing mutable spans of type `Span<T>` from containers requires
618 // explicit constructors. The container-accepting version of `MakeSpan()`
619 // deduces the type of `T` by the constness of the pointer received from the
620 // container's `data()` member. Similarly, the pointer-accepting version returns
621 // a `Span<const T>` if `T` is `const`, and a `Span<T>` otherwise.
622 //
623 // Examples:
624 //
625 // void MyRoutine(absl::Span<MyComplicatedType> a) {
626 // ...
627 // };
628 // // my_vector is a container of non-const types
629 // std::vector<MyComplicatedType> my_vector;
630 //
631 // // Constructing a Span implicitly attempts to create a Span of type
632 // // `Span<const T>`
633 // MyRoutine(my_vector); // error, type mismatch
634 //
635 // // Explicitly constructing the Span is verbose
636 // MyRoutine(absl::Span<MyComplicatedType>(my_vector));
637 //
638 // // Use MakeSpan() to make an absl::Span<T>
639 // MyRoutine(absl::MakeSpan(my_vector));
640 //
641 // // Construct a span from an array ptr+size
642 // absl::Span<T> my_span() {
643 // return absl::MakeSpan(&array[0], num_elements_);
644 // }
645 //
646 template <int&... ExplicitArgumentBarrier, typename T>
647 constexpr Span<T> MakeSpan(T* ptr, size_t size) noexcept {
648  return Span<T>(ptr, size);
649 }
650 
651 template <int&... ExplicitArgumentBarrier, typename T>
652 Span<T> MakeSpan(T* begin, T* end) noexcept {
653  return ABSL_ASSERT(begin <= end), Span<T>(begin, end - begin);
654 }
655 
656 template <int&... ExplicitArgumentBarrier, typename C>
657 constexpr auto MakeSpan(C& c) noexcept // NOLINT(runtime/references)
658  -> decltype(absl::MakeSpan(span_internal::GetData(c), c.size())) {
659  return MakeSpan(span_internal::GetData(c), c.size());
660 }
661 
662 template <int&... ExplicitArgumentBarrier, typename T, size_t N>
663 constexpr Span<T> MakeSpan(T (&array)[N]) noexcept {
664  return Span<T>(array, N);
665 }
666 
667 // MakeConstSpan()
668 //
669 // Constructs a `Span<const T>` as with `MakeSpan`, deducing `T` automatically,
670 // but always returning a `Span<const T>`.
671 //
672 // Examples:
673 //
674 // void ProcessInts(absl::Span<const int> some_ints);
675 //
676 // // Call with a pointer and size.
677 // int array[3] = { 0, 0, 0 };
678 // ProcessInts(absl::MakeConstSpan(&array[0], 3));
679 //
680 // // Call with a [begin, end) pair.
681 // ProcessInts(absl::MakeConstSpan(&array[0], &array[3]));
682 //
683 // // Call directly with an array.
684 // ProcessInts(absl::MakeConstSpan(array));
685 //
686 // // Call with a contiguous container.
687 // std::vector<int> some_ints = ...;
688 // ProcessInts(absl::MakeConstSpan(some_ints));
689 // ProcessInts(absl::MakeConstSpan(std::vector<int>{ 0, 0, 0 }));
690 //
691 template <int&... ExplicitArgumentBarrier, typename T>
692 constexpr Span<const T> MakeConstSpan(T* ptr, size_t size) noexcept {
693  return Span<const T>(ptr, size);
694 }
695 
696 template <int&... ExplicitArgumentBarrier, typename T>
698  return ABSL_ASSERT(begin <= end), Span<const T>(begin, end - begin);
699 }
700 
701 template <int&... ExplicitArgumentBarrier, typename C>
702 constexpr auto MakeConstSpan(const C& c) noexcept -> decltype(MakeSpan(c)) {
703  return MakeSpan(c);
704 }
705 
706 template <int&... ExplicitArgumentBarrier, typename T, size_t N>
707 constexpr Span<const T> MakeConstSpan(const T (&array)[N]) noexcept {
708  return Span<const T>(array, N);
709 }
710 } // namespace absl
711 #endif // ABSL_TYPES_SPAN_H_
int v
Definition: variant_test.cc:81
std::reverse_iterator< iterator > reverse_iterator
Definition: span.h:180
typename std::enable_if< span_internal::HasData< T, C >::value &&span_internal::HasSize< C >::value >::type EnableIfConvertibleFrom
Definition: span.h:160
constexpr const_iterator cbegin() const noexcept
Definition: span.h:314
const_pointer const_iterator
Definition: span.h:179
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: span.h:181
constexpr reverse_iterator rbegin() const noexcept
Definition: span.h:329
void ThrowStdOutOfRange(const std::string &what_arg)
void remove_prefix(size_type n) noexcept
Definition: span.h:355
constexpr Span subspan(size_type pos=0, size_type len=npos) const
Definition: span.h:385
#define ABSL_ASSERT(expr)
Definition: macros.h:198
constexpr Span() noexcept
Definition: span.h:187
constexpr reverse_iterator rend() const noexcept
Definition: span.h:341
constexpr pointer data() const noexcept
Definition: span.h:256
T * pointer
Definition: span.h:174
friend H AbslHashValue(H h, Span v)
Definition: span.h:427
constexpr iterator end() const noexcept
Definition: span.h:319
constexpr bool empty() const noexcept
Definition: span.h:271
Span(std::initializer_list< value_type > v) noexcept
Definition: span.h:246
constexpr size_type length() const noexcept
Definition: span.h:266
typename std::remove_cv< T >::type remove_cv_t
Definition: type_traits.h:495
constexpr reference at(size_type i) const
Definition: span.h:284
constexpr reference back() const noexcept
Definition: span.h:302
Definition: algorithm.h:29
constexpr reference front() const noexcept
Definition: span.h:295
constexpr size_t Min(size_t a, size_t b) noexcept
Definition: internal/span.h:32
constexpr size_type size() const noexcept
Definition: span.h:261
void remove_suffix(size_type n) noexcept
Definition: span.h:364
constexpr iterator begin() const noexcept
Definition: span.h:309
bool operator>(const absl::InlinedVector< T, N, A > &a, const absl::InlinedVector< T, N, A > &b)
ptrdiff_t difference_type
Definition: span.h:183
typename std::enable_if< std::is_const< T >::value, U >::type EnableIfConstView
Definition: span.h:165
constexpr Span last(size_type len) const
Definition: span.h:419
constexpr auto GetData(C &c) noexcept -> decltype(GetDataImpl(c, 0))
Definition: internal/span.h:48
constexpr Span(const V &v) noexcept
Definition: span.h:206
bool operator==(const absl::InlinedVector< T, N, A > &a, const absl::InlinedVector< T, N, A > &b)
static const size_type npos
Definition: span.h:185
constexpr Span(T(&a)[N]) noexcept
Definition: span.h:193
constexpr reference operator[](size_type i) const noexcept
Definition: span.h:276
bool operator>=(const absl::InlinedVector< T, N, A > &a, const absl::InlinedVector< T, N, A > &b)
typename std::enable_if< IsConvertible< From, To >::value >::type EnableIfConvertibleTo
char * ptr
std::is_integral< absl::decay_t< decltype(std::declval< C & >().size())> > HasSize
Definition: internal/span.h:56
size_type len_
Definition: span.h:434
size_t value
bool operator!=(const absl::InlinedVector< T, N, A > &a, const absl::InlinedVector< T, N, A > &b)
const T & const_reference
Definition: span.h:177
constexpr const_reverse_iterator crend() const noexcept
Definition: span.h:348
pointer iterator
Definition: span.h:178
constexpr Span(pointer array, size_type length) noexcept
Definition: span.h:188
constexpr Span< const T > MakeConstSpan(T *ptr, size_t size) noexcept
Definition: span.h:692
typename std::enable_if<!std::is_const< T >::value, U >::type EnableIfMutableView
Definition: span.h:170
const T * const_pointer
Definition: span.h:175
Span(V &v) noexcept
Definition: span.h:200
#define ABSL_PREDICT_TRUE(x)
Definition: optimization.h:178
absl::remove_cv_t< T > value_type
Definition: span.h:173
T & reference
Definition: span.h:176
constexpr Span< T > MakeSpan(T *ptr, size_t size) noexcept
Definition: span.h:647
uint64_t b
Definition: layout_test.cc:50
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: utility.h:219
pointer ptr_
Definition: span.h:433
#define C(x)
Definition: city_test.cc:47
size_t size_type
Definition: span.h:182
constexpr const_reverse_iterator crbegin() const noexcept
Definition: span.h:336
constexpr Span first(size_type len) const
Definition: span.h:402
constexpr const_iterator cend() const noexcept
Definition: span.h:324


abseil_cpp
Author(s):
autogenerated on Mon Feb 28 2022 21:31:20