abseil-cpp/absl/types/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 reference to existing
21 // array data. The `Span` object, much like the `absl::string_view` object,
22 // does not own such data itself, and the data being referenced by the span must
23 // outlive the span itself. Unlike `view` type references, a span can hold a
24 // reference to mutable data (and can mutate it for underlying types of
25 // non-const T.) A span provides a lightweight way to pass a reference to such
26 // data.
27 //
28 // Additionally, this header file defines `MakeSpan()` and `MakeConstSpan()`
29 // factory functions, for clearly creating spans of type `Span<T>` or read-only
30 // `Span<const T>` when such types may be difficult to identify due to issues
31 // with implicit conversion.
32 //
33 // The C++20 draft standard includes a `std::span` type. As of June 2020, the
34 // differences between `absl::Span` and `std::span` are:
35 // * `absl::Span` has `operator==` (which is likely a design bug,
36 // per https://abseil.io/blog/20180531-regular-types)
37 // * `absl::Span` has the factory functions `MakeSpan()` and
38 // `MakeConstSpan()`
39 // * bounds-checked access to `absl::Span` is accomplished with `at()`
40 // * `absl::Span` has compiler-provided move and copy constructors and
41 // assignment. This is due to them being specified as `constexpr`, but that
42 // implies const in C++11.
43 // * A read-only `absl::Span<const T>` can be implicitly constructed from an
44 // initializer list.
45 // * `absl::Span` has no `bytes()`, `size_bytes()`, `as_bytes()`, or
46 // `as_mutable_bytes()` methods
47 // * `absl::Span` has no static extent template parameter, nor constructors
48 // which exist only because of the static extent parameter.
49 // * `absl::Span` has an explicit mutable-reference constructor
50 //
51 // For more information, see the class comments below.
52 #ifndef ABSL_TYPES_SPAN_H_
53 #define ABSL_TYPES_SPAN_H_
54 
55 #include <algorithm>
56 #include <cassert>
57 #include <cstddef>
58 #include <initializer_list>
59 #include <iterator>
60 #include <type_traits>
61 #include <utility>
62 
63 #include "absl/base/internal/throw_delegate.h"
64 #include "absl/base/macros.h"
65 #include "absl/base/optimization.h"
66 #include "absl/base/port.h" // TODO(strel): remove this include
67 #include "absl/meta/type_traits.h"
68 #include "absl/types/internal/span.h"
69 
70 namespace absl {
72 
73 //------------------------------------------------------------------------------
74 // Span
75 //------------------------------------------------------------------------------
76 //
77 // A `Span` is an "array reference" type for holding a reference of contiguous
78 // array data; the `Span` object does not and cannot own such data itself. A
79 // span provides an easy way to provide overloads for anything operating on
80 // contiguous sequences without needing to manage pointers and array lengths
81 // manually.
82 
83 // A span is conceptually a pointer (ptr) and a length (size) into an already
84 // existing array of contiguous memory; the array it represents references the
85 // elements "ptr[0] .. ptr[size-1]". Passing a properly-constructed `Span`
86 // instead of raw pointers avoids many issues related to index out of bounds
87 // errors.
88 //
89 // Spans may also be constructed from containers holding contiguous sequences.
90 // Such containers must supply `data()` and `size() const` methods (e.g
91 // `std::vector<T>`, `absl::InlinedVector<T, N>`). All implicit conversions to
92 // `absl::Span` from such containers will create spans of type `const T`;
93 // spans which can mutate their values (of type `T`) must use explicit
94 // constructors.
95 //
96 // A `Span<T>` is somewhat analogous to an `absl::string_view`, but for an array
97 // of elements of type `T`, and unlike an `absl::string_view`, a span can hold a
98 // reference to mutable data. A user of `Span` must ensure that the data being
99 // pointed to outlives the `Span` itself.
100 //
101 // You can construct a `Span<T>` in several ways:
102 //
103 // * Explicitly from a reference to a container type
104 // * Explicitly from a pointer and size
105 // * Implicitly from a container type (but only for spans of type `const T`)
106 // * Using the `MakeSpan()` or `MakeConstSpan()` factory functions.
107 //
108 // Examples:
109 //
110 // // Construct a Span explicitly from a container:
111 // std::vector<int> v = {1, 2, 3, 4, 5};
112 // auto span = absl::Span<const int>(v);
113 //
114 // // Construct a Span explicitly from a C-style array:
115 // int a[5] = {1, 2, 3, 4, 5};
116 // auto span = absl::Span<const int>(a);
117 //
118 // // Construct a Span implicitly from a container
119 // void MyRoutine(absl::Span<const int> a) {
120 // ...
121 // }
122 // std::vector v = {1,2,3,4,5};
123 // MyRoutine(v) // convert to Span<const T>
124 //
125 // Note that `Span` objects, in addition to requiring that the memory they
126 // point to remains alive, must also ensure that such memory does not get
127 // reallocated. Therefore, to avoid undefined behavior, containers with
128 // associated spans should not invoke operations that may reallocate memory
129 // (such as resizing) or invalidate iterators into the container.
130 //
131 // One common use for a `Span` is when passing arguments to a routine that can
132 // accept a variety of array types (e.g. a `std::vector`, `absl::InlinedVector`,
133 // a C-style array, etc.). Instead of creating overloads for each case, you
134 // can simply specify a `Span` as the argument to such a routine.
135 //
136 // Example:
137 //
138 // void MyRoutine(absl::Span<const int> a) {
139 // ...
140 // }
141 //
142 // std::vector v = {1,2,3,4,5};
143 // MyRoutine(v);
144 //
145 // absl::InlinedVector<int, 4> my_inline_vector;
146 // MyRoutine(my_inline_vector);
147 //
148 // // Explicit constructor from pointer,size
149 // int* my_array = new int[10];
150 // MyRoutine(absl::Span<const int>(my_array, 10));
151 template <typename T>
152 class Span {
153  private:
154  // Used to determine whether a Span can be constructed from a container of
155  // type C.
156  template <typename C>
160 
161  // Used to SFINAE-enable a function when the slice elements are const.
162  template <typename U>
163  using EnableIfConstView =
165 
166  // Used to SFINAE-enable a function when the slice elements are mutable.
167  template <typename U>
168  using EnableIfMutableView =
170 
171  public:
172  using element_type = T;
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>>
246  Span(std::initializer_list<value_type> v
247  ABSL_ATTRIBUTE_LIFETIME_BOUND) 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 ABSL_HARDENING_ASSERT(i < size()), *(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. The span must not
295  // be empty.
296  constexpr reference front() const noexcept {
297  return ABSL_HARDENING_ASSERT(size() > 0), *data();
298  }
299 
300  // Span::back()
301  //
302  // Returns a reference to the last element of this span. The span must not
303  // be empty.
304  constexpr reference back() const noexcept {
305  return ABSL_HARDENING_ASSERT(size() > 0), *(data() + size() - 1);
306  }
307 
308  // Span::begin()
309  //
310  // Returns an iterator pointing to the first element of this span, or `end()`
311  // if the span is empty.
312  constexpr iterator begin() const noexcept { return data(); }
313 
314  // Span::cbegin()
315  //
316  // Returns a const iterator pointing to the first element of this span, or
317  // `end()` if the span is empty.
318  constexpr const_iterator cbegin() const noexcept { return begin(); }
319 
320  // Span::end()
321  //
322  // Returns an iterator pointing just beyond the last element at the
323  // end of this span. This iterator acts as a placeholder; attempting to
324  // access it results in undefined behavior.
325  constexpr iterator end() const noexcept { return data() + size(); }
326 
327  // Span::cend()
328  //
329  // Returns a const iterator pointing just beyond the last element at the
330  // end of this span. This iterator acts as a placeholder; attempting to
331  // access it results in undefined behavior.
332  constexpr const_iterator cend() const noexcept { return end(); }
333 
334  // Span::rbegin()
335  //
336  // Returns a reverse iterator pointing to the last element at the end of this
337  // span, or `rend()` if the span is empty.
338  constexpr reverse_iterator rbegin() const noexcept {
339  return reverse_iterator(end());
340  }
341 
342  // Span::crbegin()
343  //
344  // Returns a const reverse iterator pointing to the last element at the end of
345  // this span, or `crend()` if the span is empty.
346  constexpr const_reverse_iterator crbegin() const noexcept { return rbegin(); }
347 
348  // Span::rend()
349  //
350  // Returns a reverse iterator pointing just before the first element
351  // at the beginning of this span. This pointer acts as a placeholder;
352  // attempting to access its element results in undefined behavior.
353  constexpr reverse_iterator rend() const noexcept {
354  return reverse_iterator(begin());
355  }
356 
357  // Span::crend()
358  //
359  // Returns a reverse const iterator pointing just before the first element
360  // at the beginning of this span. This pointer acts as a placeholder;
361  // attempting to access its element results in undefined behavior.
362  constexpr const_reverse_iterator crend() const noexcept { return rend(); }
363 
364  // Span mutations
365 
366  // Span::remove_prefix()
367  //
368  // Removes the first `n` elements from the span.
369  void remove_prefix(size_type n) noexcept {
371  ptr_ += n;
372  len_ -= n;
373  }
374 
375  // Span::remove_suffix()
376  //
377  // Removes the last `n` elements from the span.
378  void remove_suffix(size_type n) noexcept {
380  len_ -= n;
381  }
382 
383  // Span::subspan()
384  //
385  // Returns a `Span` starting at element `pos` and of length `len`. Both `pos`
386  // and `len` are of type `size_type` and thus non-negative. Parameter `pos`
387  // must be <= size(). Any `len` value that points past the end of the span
388  // will be trimmed to at most size() - `pos`. A default `len` value of `npos`
389  // ensures the returned subspan continues until the end of the span.
390  //
391  // Examples:
392  //
393  // std::vector<int> vec = {10, 11, 12, 13};
394  // absl::MakeSpan(vec).subspan(1, 2); // {11, 12}
395  // absl::MakeSpan(vec).subspan(2, 8); // {12, 13}
396  // absl::MakeSpan(vec).subspan(1); // {11, 12, 13}
397  // absl::MakeSpan(vec).subspan(4); // {}
398  // absl::MakeSpan(vec).subspan(5); // throws std::out_of_range
399  constexpr Span subspan(size_type pos = 0, size_type len = npos) const {
400  return (pos <= size())
401  ? Span(data() + pos, span_internal::Min(size() - pos, len))
402  : (base_internal::ThrowStdOutOfRange("pos > size()"), Span());
403  }
404 
405  // Span::first()
406  //
407  // Returns a `Span` containing first `len` elements. Parameter `len` is of
408  // type `size_type` and thus non-negative. `len` value must be <= size().
409  //
410  // Examples:
411  //
412  // std::vector<int> vec = {10, 11, 12, 13};
413  // absl::MakeSpan(vec).first(1); // {10}
414  // absl::MakeSpan(vec).first(3); // {10, 11, 12}
415  // absl::MakeSpan(vec).first(5); // throws std::out_of_range
416  constexpr Span first(size_type len) const {
417  return (len <= size())
418  ? Span(data(), len)
419  : (base_internal::ThrowStdOutOfRange("len > size()"), Span());
420  }
421 
422  // Span::last()
423  //
424  // Returns a `Span` containing last `len` elements. Parameter `len` is of
425  // type `size_type` and thus non-negative. `len` value must be <= size().
426  //
427  // Examples:
428  //
429  // std::vector<int> vec = {10, 11, 12, 13};
430  // absl::MakeSpan(vec).last(1); // {13}
431  // absl::MakeSpan(vec).last(3); // {11, 12, 13}
432  // absl::MakeSpan(vec).last(5); // throws std::out_of_range
433  constexpr Span last(size_type len) const {
434  return (len <= size())
435  ? Span(size() - len + data(), len)
436  : (base_internal::ThrowStdOutOfRange("len > size()"), Span());
437  }
438 
439  // Support for absl::Hash.
440  template <typename H>
441  friend H AbslHashValue(H h, Span v) {
442  return H::combine(H::combine_contiguous(std::move(h), v.data(), v.size()),
443  v.size());
444  }
445 
446  private:
449 };
450 
451 template <typename T>
452 const typename Span<T>::size_type Span<T>::npos;
453 
454 // Span relationals
455 
456 // Equality is compared element-by-element, while ordering is lexicographical.
457 // We provide three overloads for each operator to cover any combination on the
458 // left or right hand side of mutable Span<T>, read-only Span<const T>, and
459 // convertible-to-read-only Span<T>.
460 // TODO(zhangxy): Due to MSVC overload resolution bug with partial ordering
461 // template functions, 5 overloads per operator is needed as a workaround. We
462 // should update them to 3 overloads per operator using non-deduced context like
463 // string_view, i.e.
464 // - (Span<T>, Span<T>)
465 // - (Span<T>, non_deduced<Span<const T>>)
466 // - (non_deduced<Span<const T>>, Span<T>)
467 
468 // operator==
469 template <typename T>
471  return span_internal::EqualImpl<Span, const T>(a, b);
472 }
473 template <typename T>
475  return span_internal::EqualImpl<Span, const T>(a, b);
476 }
477 template <typename T>
479  return span_internal::EqualImpl<Span, const T>(a, b);
480 }
481 template <
482  typename T, typename U,
483  typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
484 bool operator==(const U& a, Span<T> b) {
485  return span_internal::EqualImpl<Span, const T>(a, b);
486 }
487 template <
488  typename T, typename U,
489  typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
490 bool operator==(Span<T> a, const U& b) {
491  return span_internal::EqualImpl<Span, const T>(a, b);
492 }
493 
494 // operator!=
495 template <typename T>
497  return !(a == b);
498 }
499 template <typename T>
501  return !(a == b);
502 }
503 template <typename T>
505  return !(a == b);
506 }
507 template <
508  typename T, typename U,
509  typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
510 bool operator!=(const U& a, Span<T> b) {
511  return !(a == b);
512 }
513 template <
514  typename T, typename U,
515  typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
516 bool operator!=(Span<T> a, const U& b) {
517  return !(a == b);
518 }
519 
520 // operator<
521 template <typename T>
523  return span_internal::LessThanImpl<Span, const T>(a, b);
524 }
525 template <typename T>
526 bool operator<(Span<const T> a, Span<T> b) {
527  return span_internal::LessThanImpl<Span, const T>(a, b);
528 }
529 template <typename T>
530 bool operator<(Span<T> a, Span<const T> b) {
531  return span_internal::LessThanImpl<Span, const T>(a, b);
532 }
533 template <
534  typename T, typename U,
535  typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
536 bool operator<(const U& a, Span<T> b) {
537  return span_internal::LessThanImpl<Span, const T>(a, b);
538 }
539 template <
540  typename T, typename U,
541  typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
542 bool operator<(Span<T> a, const U& b) {
543  return span_internal::LessThanImpl<Span, const T>(a, b);
544 }
545 
546 // operator>
547 template <typename T>
549  return b < a;
550 }
551 template <typename T>
552 bool operator>(Span<const T> a, Span<T> b) {
553  return b < a;
554 }
555 template <typename T>
556 bool operator>(Span<T> a, Span<const T> b) {
557  return b < a;
558 }
559 template <
560  typename T, typename U,
561  typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
562 bool operator>(const U& a, Span<T> b) {
563  return b < a;
564 }
565 template <
566  typename T, typename U,
567  typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
568 bool operator>(Span<T> a, const U& b) {
569  return b < a;
570 }
571 
572 // operator<=
573 template <typename T>
575  return !(b < a);
576 }
577 template <typename T>
579  return !(b < a);
580 }
581 template <typename T>
583  return !(b < a);
584 }
585 template <
586  typename T, typename U,
587  typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
588 bool operator<=(const U& a, Span<T> b) {
589  return !(b < a);
590 }
591 template <
592  typename T, typename U,
593  typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
594 bool operator<=(Span<T> a, const U& b) {
595  return !(b < a);
596 }
597 
598 // operator>=
599 template <typename T>
601  return !(a < b);
602 }
603 template <typename T>
605  return !(a < b);
606 }
607 template <typename T>
609  return !(a < b);
610 }
611 template <
612  typename T, typename U,
613  typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
614 bool operator>=(const U& a, Span<T> b) {
615  return !(a < b);
616 }
617 template <
618  typename T, typename U,
619  typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
620 bool operator>=(Span<T> a, const U& b) {
621  return !(a < b);
622 }
623 
624 // MakeSpan()
625 //
626 // Constructs a mutable `Span<T>`, deducing `T` automatically from either a
627 // container or pointer+size.
628 //
629 // Because a read-only `Span<const T>` is implicitly constructed from container
630 // types regardless of whether the container itself is a const container,
631 // constructing mutable spans of type `Span<T>` from containers requires
632 // explicit constructors. The container-accepting version of `MakeSpan()`
633 // deduces the type of `T` by the constness of the pointer received from the
634 // container's `data()` member. Similarly, the pointer-accepting version returns
635 // a `Span<const T>` if `T` is `const`, and a `Span<T>` otherwise.
636 //
637 // Examples:
638 //
639 // void MyRoutine(absl::Span<MyComplicatedType> a) {
640 // ...
641 // };
642 // // my_vector is a container of non-const types
643 // std::vector<MyComplicatedType> my_vector;
644 //
645 // // Constructing a Span implicitly attempts to create a Span of type
646 // // `Span<const T>`
647 // MyRoutine(my_vector); // error, type mismatch
648 //
649 // // Explicitly constructing the Span is verbose
650 // MyRoutine(absl::Span<MyComplicatedType>(my_vector));
651 //
652 // // Use MakeSpan() to make an absl::Span<T>
653 // MyRoutine(absl::MakeSpan(my_vector));
654 //
655 // // Construct a span from an array ptr+size
656 // absl::Span<T> my_span() {
657 // return absl::MakeSpan(&array[0], num_elements_);
658 // }
659 //
660 template <int&... ExplicitArgumentBarrier, typename T>
661 constexpr Span<T> MakeSpan(T* ptr, size_t size) noexcept {
662  return Span<T>(ptr, size);
663 }
664 
665 template <int&... ExplicitArgumentBarrier, typename T>
666 Span<T> MakeSpan(T* begin, T* end) noexcept {
667  return ABSL_HARDENING_ASSERT(begin <= end),
668  Span<T>(begin, static_cast<size_t>(end - begin));
669 }
670 
671 template <int&... ExplicitArgumentBarrier, typename C>
672 constexpr auto MakeSpan(C& c) noexcept // NOLINT(runtime/references)
673  -> decltype(absl::MakeSpan(span_internal::GetData(c), c.size())) {
674  return MakeSpan(span_internal::GetData(c), c.size());
675 }
676 
677 template <int&... ExplicitArgumentBarrier, typename T, size_t N>
678 constexpr Span<T> MakeSpan(T (&array)[N]) noexcept {
679  return Span<T>(array, N);
680 }
681 
682 // MakeConstSpan()
683 //
684 // Constructs a `Span<const T>` as with `MakeSpan`, deducing `T` automatically,
685 // but always returning a `Span<const T>`.
686 //
687 // Examples:
688 //
689 // void ProcessInts(absl::Span<const int> some_ints);
690 //
691 // // Call with a pointer and size.
692 // int array[3] = { 0, 0, 0 };
693 // ProcessInts(absl::MakeConstSpan(&array[0], 3));
694 //
695 // // Call with a [begin, end) pair.
696 // ProcessInts(absl::MakeConstSpan(&array[0], &array[3]));
697 //
698 // // Call directly with an array.
699 // ProcessInts(absl::MakeConstSpan(array));
700 //
701 // // Call with a contiguous container.
702 // std::vector<int> some_ints = ...;
703 // ProcessInts(absl::MakeConstSpan(some_ints));
704 // ProcessInts(absl::MakeConstSpan(std::vector<int>{ 0, 0, 0 }));
705 //
706 template <int&... ExplicitArgumentBarrier, typename T>
707 constexpr Span<const T> MakeConstSpan(T* ptr, size_t size) noexcept {
708  return Span<const T>(ptr, size);
709 }
710 
711 template <int&... ExplicitArgumentBarrier, typename T>
714 }
715 
716 template <int&... ExplicitArgumentBarrier, typename C>
717 constexpr auto MakeConstSpan(const C& c) noexcept -> decltype(MakeSpan(c)) {
718  return MakeSpan(c);
719 }
720 
721 template <int&... ExplicitArgumentBarrier, typename T, size_t N>
722 constexpr Span<const T> MakeConstSpan(const T (&array)[N]) noexcept {
723  return Span<const T>(array, N);
724 }
726 } // namespace absl
727 #endif // ABSL_TYPES_SPAN_H_
ptr
char * ptr
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:45
absl::str_format_internal::FormatArgImpl
Definition: abseil-cpp/absl/strings/internal/str_format/arg.h:312
absl::Span< const absl::str_format_internal::FormatArgImpl >::EnableIfConstView
typename std::enable_if< std::is_const< const absl::str_format_internal::FormatArgImpl >::value, U >::type EnableIfConstView
Definition: abseil-cpp/absl/types/span.h:164
pos
int pos
Definition: libuv/docs/code/tty-gravity/main.c:11
absl::Span< const absl::str_format_internal::FormatArgImpl >::const_pointer
const const absl::str_format_internal::FormatArgImpl * const_pointer
Definition: abseil-cpp/absl/types/span.h:175
const
#define const
Definition: bloaty/third_party/zlib/zconf.h:230
absl::Span< const absl::str_format_internal::FormatArgImpl >::EnableIfMutableView
typename std::enable_if<!std::is_const< const absl::str_format_internal::FormatArgImpl >::value, U >::type EnableIfMutableView
Definition: abseil-cpp/absl/types/span.h:169
absl::remove_cv_t
typename std::remove_cv< T >::type remove_cv_t
Definition: abseil-cpp/absl/meta/type_traits.h:579
absl::Span::npos
static const size_type npos
Definition: abseil-cpp/absl/types/span.h:185
begin
char * begin
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1007
absl::Span::Span
Span(V &v) noexcept
Definition: abseil-cpp/absl/types/span.h:200
absl::Span::len_
size_type len_
Definition: abseil-cpp/absl/types/span.h:448
absl::Span::rbegin
constexpr reverse_iterator rbegin() const noexcept
Definition: abseil-cpp/absl/types/span.h:338
absl::span_internal::Min
constexpr size_t Min(size_t a, size_t b) noexcept
Definition: abseil-cpp/absl/types/internal/span.h:33
C
#define C(x)
Definition: abseil-cpp/absl/hash/internal/city_test.cc:49
absl::Span
Definition: abseil-cpp/absl/types/span.h:152
absl::Span::Span
constexpr Span(pointer array, size_type length) noexcept
Definition: abseil-cpp/absl/types/span.h:188
absl::span_internal::HasSize
std::is_integral< absl::decay_t< decltype(std::declval< C & >().size())> > HasSize
Definition: abseil-cpp/absl/types/internal/span.h:57
absl::Span::pointer
T * pointer
Definition: abseil-cpp/absl/types/span.h:174
a
int a
Definition: abseil-cpp/absl/container/internal/hash_policy_traits_test.cc:88
absl::Span::EnableIfConvertibleFrom
typename std::enable_if< span_internal::HasData< T, C >::value &&span_internal::HasSize< C >::value >::type EnableIfConvertibleFrom
Definition: abseil-cpp/absl/types/span.h:159
absl::Span::crend
constexpr const_reverse_iterator crend() const noexcept
Definition: abseil-cpp/absl/types/span.h:362
ABSL_NAMESPACE_END
#define ABSL_NAMESPACE_END
Definition: third_party/abseil-cpp/absl/base/config.h:171
absl::Span::empty
constexpr bool empty() const noexcept
Definition: abseil-cpp/absl/types/span.h:271
absl::operator>
bool operator>(const absl::InlinedVector< T, N, A > &a, const absl::InlinedVector< T, N, A > &b)
Definition: abseil-cpp/absl/container/inlined_vector.h:828
absl::Span::back
constexpr reference back() const noexcept
Definition: abseil-cpp/absl/types/span.h:304
ABSL_HARDENING_ASSERT
#define ABSL_HARDENING_ASSERT(expr)
Definition: abseil-cpp/absl/base/macros.h:134
T
#define T(upbtypeconst, upbtype, ctype, default_value)
absl::Span< const absl::str_format_internal::FormatArgImpl >::const_reference
const const absl::str_format_internal::FormatArgImpl & const_reference
Definition: abseil-cpp/absl/types/span.h:177
absl::Span::AbslHashValue
friend H AbslHashValue(H h, Span v)
Definition: abseil-cpp/absl/types/span.h:441
absl::base_internal::ThrowStdOutOfRange
void ThrowStdOutOfRange(const std::string &what_arg)
Definition: abseil-cpp/absl/base/internal/throw_delegate.cc:109
ABSL_NAMESPACE_BEGIN
#define ABSL_NAMESPACE_BEGIN
Definition: third_party/abseil-cpp/absl/base/config.h:170
absl::Span::remove_suffix
void remove_suffix(size_type n) noexcept
Definition: abseil-cpp/absl/types/span.h:378
absl::Span::cbegin
constexpr const_iterator cbegin() const noexcept
Definition: abseil-cpp/absl/types/span.h:318
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
end
char * end
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1008
array
Definition: undname.c:101
setup.v
v
Definition: third_party/bloaty/third_party/capstone/bindings/python/setup.py:42
absl::Span::remove_prefix
void remove_prefix(size_type n) noexcept
Definition: abseil-cpp/absl/types/span.h:369
absl::Span::operator[]
constexpr reference operator[](size_type i) const noexcept
Definition: abseil-cpp/absl/types/span.h:276
absl::operator==
bool operator==(const absl::InlinedVector< T, N, A > &a, const absl::InlinedVector< T, N, A > &b)
Definition: abseil-cpp/absl/container/inlined_vector.h:794
absl::Span::Span
constexpr Span() noexcept
Definition: abseil-cpp/absl/types/span.h:187
absl::Span::end
constexpr iterator end() const noexcept
Definition: abseil-cpp/absl/types/span.h:325
absl::Span< const absl::str_format_internal::FormatArgImpl >::difference_type
ptrdiff_t difference_type
Definition: abseil-cpp/absl/types/span.h:183
b
uint64_t b
Definition: abseil-cpp/absl/container/internal/layout_test.cc:53
Span
Definition: boringssl-with-bazel/src/include/openssl/span.h:32
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
H
#define H(b, c, d)
Definition: md4.c:114
absl::operator!=
bool operator!=(const absl::InlinedVector< T, N, A > &a, const absl::InlinedVector< T, N, A > &b)
Definition: abseil-cpp/absl/container/inlined_vector.h:805
ABSL_PREDICT_TRUE
#define ABSL_PREDICT_TRUE(x)
Definition: abseil-cpp/absl/base/optimization.h:181
absl::Span::begin
constexpr iterator begin() const noexcept
Definition: abseil-cpp/absl/types/span.h:312
absl::Span::last
constexpr Span last(size_type len) const
Definition: abseil-cpp/absl/types/span.h:433
value
const char * value
Definition: hpack_parser_table.cc:165
absl::Span< const absl::str_format_internal::FormatArgImpl >::size_type
size_t size_type
Definition: abseil-cpp/absl/types/span.h:182
absl::Span::rend
constexpr reverse_iterator rend() const noexcept
Definition: abseil-cpp/absl/types/span.h:353
N
#define N
Definition: sync_test.cc:37
absl::Span::ptr_
pointer ptr_
Definition: abseil-cpp/absl/types/span.h:447
absl::operator>=
bool operator>=(const absl::InlinedVector< T, N, A > &a, const absl::InlinedVector< T, N, A > &b)
Definition: abseil-cpp/absl/container/inlined_vector.h:848
absl::Span::Span
constexpr Span(const V &v) noexcept
Definition: abseil-cpp/absl/types/span.h:206
absl::operator<=
bool operator<=(const absl::InlinedVector< T, N, A > &a, const absl::InlinedVector< T, N, A > &b)
Definition: abseil-cpp/absl/container/inlined_vector.h:838
absl::Span::size
constexpr size_type size() const noexcept
Definition: abseil-cpp/absl/types/span.h:261
absl::span_internal::GetData
constexpr auto GetData(C &c) noexcept -> decltype(GetDataImpl(c, 0))
Definition: abseil-cpp/absl/types/internal/span.h:49
absl::Span< const absl::str_format_internal::FormatArgImpl >::reverse_iterator
std::reverse_iterator< iterator > reverse_iterator
Definition: abseil-cpp/absl/types/span.h:180
absl::Span::at
constexpr reference at(size_type i) const
Definition: abseil-cpp/absl/types/span.h:284
absl::Span::first
constexpr Span first(size_type len) const
Definition: abseil-cpp/absl/types/span.h:416
absl::Span< const absl::str_format_internal::FormatArgImpl >::const_reverse_iterator
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: abseil-cpp/absl/types/span.h:181
absl::Span< const absl::str_format_internal::FormatArgImpl >::const_iterator
const_pointer const_iterator
Definition: abseil-cpp/absl/types/span.h:179
absl::Span::cend
constexpr const_iterator cend() const noexcept
Definition: abseil-cpp/absl/types/span.h:332
absl::Span::Span
Span(std::initializer_list< value_type > v ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept
Definition: abseil-cpp/absl/types/span.h:246
absl
Definition: abseil-cpp/absl/algorithm/algorithm.h:31
absl::Span< const absl::str_format_internal::FormatArgImpl >::value_type
absl::remove_cv_t< const absl::str_format_internal::FormatArgImpl > value_type
Definition: abseil-cpp/absl/types/span.h:173
absl::Span::crbegin
constexpr const_reverse_iterator crbegin() const noexcept
Definition: abseil-cpp/absl/types/span.h:346
asyncio_get_stats.type
type
Definition: asyncio_get_stats.py:37
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
ABSL_ATTRIBUTE_LIFETIME_BOUND
#define ABSL_ATTRIBUTE_LIFETIME_BOUND
Definition: abseil-cpp/absl/base/attributes.h:759
size
voidpf void uLong size
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
absl::operator<
bool operator<(const absl::InlinedVector< T, N, A > &a, const absl::InlinedVector< T, N, A > &b)
Definition: abseil-cpp/absl/container/inlined_vector.h:815
absl::Span::Span
constexpr Span(T(&a)[N]) noexcept
Definition: abseil-cpp/absl/types/span.h:193
absl::Span::subspan
constexpr Span subspan(size_type pos=0, size_type len=npos) const
Definition: abseil-cpp/absl/types/span.h:399
absl::MakeSpan
constexpr Span< T > MakeSpan(T *ptr, size_t size) noexcept
Definition: abseil-cpp/absl/types/span.h:661
absl::Span::data
constexpr pointer data() const noexcept
Definition: abseil-cpp/absl/types/span.h:256
absl::Span::front
constexpr reference front() const noexcept
Definition: abseil-cpp/absl/types/span.h:296
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
absl::Span::length
constexpr size_type length() const noexcept
Definition: abseil-cpp/absl/types/span.h:266
absl::MakeConstSpan
constexpr Span< const T > MakeConstSpan(T *ptr, size_t size) noexcept
Definition: abseil-cpp/absl/types/span.h:707


grpc
Author(s):
autogenerated on Fri May 16 2025 03:00:14