Coverage Report

Created: 2024-09-08 06:07

/proc/self/cwd/external/com_google_absl/absl/types/span.h
Line
Count
Source (jump to first uncovered line)
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_writable_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/attributes.h"
64
#include "absl/base/internal/throw_delegate.h"
65
#include "absl/base/macros.h"
66
#include "absl/base/nullability.h"
67
#include "absl/base/optimization.h"
68
#include "absl/base/port.h"    // TODO(strel): remove this include
69
#include "absl/meta/type_traits.h"
70
#include "absl/types/internal/span.h"
71
72
namespace absl {
73
ABSL_NAMESPACE_BEGIN
74
75
//------------------------------------------------------------------------------
76
// Span
77
//------------------------------------------------------------------------------
78
//
79
// A `Span` is an "array reference" type for holding a reference of contiguous
80
// array data; the `Span` object does not and cannot own such data itself. A
81
// span 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`, and unlike an `absl::string_view`, a span can hold a
100
// reference to mutable data. A user of `Span` must ensure that the data being
101
// pointed to outlives the `Span` itself.
102
//
103
// You can construct a `Span<T>` in several ways:
104
//
105
//   * Explicitly from a reference to a container type
106
//   * Explicitly from a pointer and size
107
//   * Implicitly from a container type (but only for spans of type `const T`)
108
//   * Using the `MakeSpan()` or `MakeConstSpan()` factory functions.
109
//
110
// Examples:
111
//
112
//   // Construct a Span explicitly from a container:
113
//   std::vector<int> v = {1, 2, 3, 4, 5};
114
//   auto span = absl::Span<const int>(v);
115
//
116
//   // Construct a Span explicitly from a C-style array:
117
//   int a[5] =  {1, 2, 3, 4, 5};
118
//   auto span = absl::Span<const int>(a);
119
//
120
//   // Construct a Span implicitly from a container
121
//   void MyRoutine(absl::Span<const int> a) {
122
//     ...
123
//   }
124
//   std::vector v = {1,2,3,4,5};
125
//   MyRoutine(v)                     // convert to Span<const T>
126
//
127
// Note that `Span` objects, in addition to requiring that the memory they
128
// point to remains alive, must also ensure that such memory does not get
129
// reallocated. Therefore, to avoid undefined behavior, containers with
130
// associated spans should not invoke operations that may reallocate memory
131
// (such as resizing) or invalidate iterators into the container.
132
//
133
// One common use for a `Span` is when passing arguments to a routine that can
134
// accept a variety of array types (e.g. a `std::vector`, `absl::InlinedVector`,
135
// a C-style array, etc.). Instead of creating overloads for each case, you
136
// can simply specify a `Span` as the argument to such a routine.
137
//
138
// Example:
139
//
140
//   void MyRoutine(absl::Span<const int> a) {
141
//     ...
142
//   }
143
//
144
//   std::vector v = {1,2,3,4,5};
145
//   MyRoutine(v);
146
//
147
//   absl::InlinedVector<int, 4> my_inline_vector;
148
//   MyRoutine(my_inline_vector);
149
//
150
//   // Explicit constructor from pointer,size
151
//   int* my_array = new int[10];
152
//   MyRoutine(absl::Span<const int>(my_array, 10));
153
template <typename T>
154
class ABSL_ATTRIBUTE_VIEW Span {
155
 private:
156
  // Used to determine whether a Span can be constructed from a container of
157
  // type C.
158
  template <typename C>
159
  using EnableIfConvertibleFrom =
160
      typename std::enable_if<span_internal::HasData<T, C>::value &&
161
                              span_internal::HasSize<C>::value>::type;
162
163
  // Used to SFINAE-enable a function when the slice elements are const.
164
  template <typename U>
165
  using EnableIfValueIsConst =
166
      typename std::enable_if<std::is_const<T>::value, U>::type;
167
168
  // Used to SFINAE-enable a function when the slice elements are mutable.
169
  template <typename U>
170
  using EnableIfValueIsMutable =
171
      typename std::enable_if<!std::is_const<T>::value, U>::type;
172
173
 public:
174
  using element_type = T;
175
  using value_type = absl::remove_cv_t<T>;
176
  // TODO(b/316099902) - pointer should be Nullable<T*>, but this makes it hard
177
  // to recognize foreach loops as safe.
178
  using pointer = T*;
179
  using const_pointer = const T*;
180
  using reference = T&;
181
  using const_reference = const T&;
182
  using iterator = pointer;
183
  using const_iterator = const_pointer;
184
  using reverse_iterator = std::reverse_iterator<iterator>;
185
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;
186
  using size_type = size_t;
187
  using difference_type = ptrdiff_t;
188
  using absl_internal_is_view = std::true_type;
189
190
  static const size_type npos = ~(size_type(0));
191
192
  constexpr Span() noexcept : Span(nullptr, 0) {}
193
  constexpr Span(pointer array, size_type length) noexcept
194
4.96k
      : ptr_(array), len_(length) {}
absl::Span<absl::str_format_internal::FormatArgImpl const>::Span(absl::str_format_internal::FormatArgImpl const*, unsigned long)
Line
Count
Source
194
4.96k
      : ptr_(array), len_(length) {}
Unexecuted instantiation: absl::Span<unsigned int>::Span(unsigned int*, unsigned long)
195
196
  // Implicit conversion constructors
197
  template <size_t N>
198
  constexpr Span(T (&a)[N]) noexcept  // NOLINT(runtime/explicit)
199
      : Span(a, N) {}
200
201
  // Explicit reference constructor for a mutable `Span<T>` type. Can be
202
  // replaced with MakeSpan() to infer the type parameter.
203
  template <typename V, typename = EnableIfConvertibleFrom<V>,
204
            typename = EnableIfValueIsMutable<V>,
205
            typename = span_internal::EnableIfNotIsView<V>>
206
  explicit Span(
207
      V& v
208
          ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept  // NOLINT(runtime/references)
209
      : Span(span_internal::GetData(v), v.size()) {}
210
211
  // Implicit reference constructor for a read-only `Span<const T>` type
212
  template <typename V, typename = EnableIfConvertibleFrom<V>,
213
            typename = EnableIfValueIsConst<V>,
214
            typename = span_internal::EnableIfNotIsView<V>>
215
  constexpr Span(
216
      const V& v
217
          ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept  // NOLINT(runtime/explicit)
218
0
      : Span(span_internal::GetData(v), v.size()) {}
219
220
  // Overloads of the above two functions that are only enabled for view types.
221
  // This is so we can drop the ABSL_ATTRIBUTE_LIFETIME_BOUND annotation. These
222
  // overloads must be made unique by using a different template parameter list
223
  // (hence the = 0 for the IsView enabler).
224
  template <typename V, typename = EnableIfConvertibleFrom<V>,
225
            typename = EnableIfValueIsMutable<V>,
226
            span_internal::EnableIfIsView<V> = 0>
227
  explicit Span(V& v) noexcept  // NOLINT(runtime/references)
228
0
      : Span(span_internal::GetData(v), v.size()) {}
229
  template <typename V, typename = EnableIfConvertibleFrom<V>,
230
            typename = EnableIfValueIsConst<V>,
231
            span_internal::EnableIfIsView<V> = 0>
232
  constexpr Span(const V& v) noexcept  // NOLINT(runtime/explicit)
233
      : Span(span_internal::GetData(v), v.size()) {}
234
235
  // Implicit constructor from an initializer list, making it possible to pass a
236
  // brace-enclosed initializer list to a function expecting a `Span`. Such
237
  // spans constructed from an initializer list must be of type `Span<const T>`.
238
  //
239
  //   void Process(absl::Span<const int> x);
240
  //   Process({1, 2, 3});
241
  //
242
  // Note that as always the array referenced by the span must outlive the span.
243
  // Since an initializer list constructor acts as if it is fed a temporary
244
  // array (cf. C++ standard [dcl.init.list]/5), it's safe to use this
245
  // constructor only when the `std::initializer_list` itself outlives the span.
246
  // In order to meet this requirement it's sufficient to ensure that neither
247
  // the span nor a copy of it is used outside of the expression in which it's
248
  // created:
249
  //
250
  //   // Assume that this function uses the array directly, not retaining any
251
  //   // copy of the span or pointer to any of its elements.
252
  //   void Process(absl::Span<const int> ints);
253
  //
254
  //   // Okay: the std::initializer_list<int> will reference a temporary array
255
  //   // that isn't destroyed until after the call to Process returns.
256
  //   Process({ 17, 19 });
257
  //
258
  //   // Not okay: the storage used by the std::initializer_list<int> is not
259
  //   // allowed to be referenced after the first line.
260
  //   absl::Span<const int> ints = { 17, 19 };
261
  //   Process(ints);
262
  //
263
  //   // Not okay for the same reason as above: even when the elements of the
264
  //   // initializer list expression are not temporaries the underlying array
265
  //   // is, so the initializer list must still outlive the span.
266
  //   const int foo = 17;
267
  //   absl::Span<const int> ints = { foo };
268
  //   Process(ints);
269
  //
270
  template <typename LazyT = T,
271
            typename = EnableIfValueIsConst<LazyT>>
272
  Span(std::initializer_list<value_type> v
273
           ABSL_ATTRIBUTE_LIFETIME_BOUND) noexcept  // NOLINT(runtime/explicit)
274
4.96k
      : Span(v.begin(), v.size()) {}
275
276
  // Accessors
277
278
  // Span::data()
279
  //
280
  // Returns a pointer to the span's underlying array of data (which is held
281
  // outside the span).
282
0
  constexpr pointer data() const noexcept { return ptr_; }
Unexecuted instantiation: absl::Span<absl::str_format_internal::FormatArgImpl const>::data() const
Unexecuted instantiation: absl::Span<unsigned int>::data() const
283
284
  // Span::size()
285
  //
286
  // Returns the size of this span.
287
9.92k
  constexpr size_type size() const noexcept { return len_; }
absl::Span<absl::str_format_internal::FormatArgImpl const>::size() const
Line
Count
Source
287
9.92k
  constexpr size_type size() const noexcept { return len_; }
Unexecuted instantiation: absl::Span<unsigned int>::size() const
288
289
  // Span::length()
290
  //
291
  // Returns the length (size) of this span.
292
  constexpr size_type length() const noexcept { return size(); }
293
294
  // Span::empty()
295
  //
296
  // Returns a boolean indicating whether or not this span is considered empty.
297
  constexpr bool empty() const noexcept { return size() == 0; }
298
299
  // Span::operator[]
300
  //
301
  // Returns a reference to the i'th element of this span.
302
4.96k
  constexpr reference operator[](size_type i) const noexcept {
303
4.96k
    return ABSL_HARDENING_ASSERT(i < size()), ptr_[i];
304
4.96k
  }
absl::Span<absl::str_format_internal::FormatArgImpl const>::operator[](unsigned long) const
Line
Count
Source
302
4.96k
  constexpr reference operator[](size_type i) const noexcept {
303
4.96k
    return ABSL_HARDENING_ASSERT(i < size()), ptr_[i];
304
4.96k
  }
Unexecuted instantiation: absl::Span<unsigned int>::operator[](unsigned long) const
305
306
  // Span::at()
307
  //
308
  // Returns a reference to the i'th element of this span.
309
  constexpr reference at(size_type i) const {
310
    return ABSL_PREDICT_TRUE(i < size())  //
311
               ? *(data() + i)
312
               : (base_internal::ThrowStdOutOfRange(
313
                      "Span::at failed bounds check"),
314
                  *(data() + i));
315
  }
316
317
  // Span::front()
318
  //
319
  // Returns a reference to the first element of this span. The span must not
320
  // be empty.
321
  constexpr reference front() const noexcept {
322
    return ABSL_HARDENING_ASSERT(size() > 0), *data();
323
  }
324
325
  // Span::back()
326
  //
327
  // Returns a reference to the last element of this span. The span must not
328
  // be empty.
329
  constexpr reference back() const noexcept {
330
    return ABSL_HARDENING_ASSERT(size() > 0), *(data() + size() - 1);
331
  }
332
333
  // Span::begin()
334
  //
335
  // Returns an iterator pointing to the first element of this span, or `end()`
336
  // if the span is empty.
337
0
  constexpr iterator begin() const noexcept { return data(); }
338
339
  // Span::cbegin()
340
  //
341
  // Returns a const iterator pointing to the first element of this span, or
342
  // `end()` if the span is empty.
343
  constexpr const_iterator cbegin() const noexcept { return begin(); }
344
345
  // Span::end()
346
  //
347
  // Returns an iterator pointing just beyond the last element at the
348
  // end of this span. This iterator acts as a placeholder; attempting to
349
  // access it results in undefined behavior.
350
0
  constexpr iterator end() const noexcept { return data() + size(); }
351
352
  // Span::cend()
353
  //
354
  // Returns a const iterator pointing just beyond the last element at the
355
  // end of this span. This iterator acts as a placeholder; attempting to
356
  // access it results in undefined behavior.
357
  constexpr const_iterator cend() const noexcept { return end(); }
358
359
  // Span::rbegin()
360
  //
361
  // Returns a reverse iterator pointing to the last element at the end of this
362
  // span, or `rend()` if the span is empty.
363
  constexpr reverse_iterator rbegin() const noexcept {
364
    return reverse_iterator(end());
365
  }
366
367
  // Span::crbegin()
368
  //
369
  // Returns a const reverse iterator pointing to the last element at the end of
370
  // this span, or `crend()` if the span is empty.
371
  constexpr const_reverse_iterator crbegin() const noexcept { return rbegin(); }
372
373
  // Span::rend()
374
  //
375
  // Returns a reverse iterator pointing just before the first element
376
  // at the beginning of this span. This pointer acts as a placeholder;
377
  // attempting to access its element results in undefined behavior.
378
  constexpr reverse_iterator rend() const noexcept {
379
    return reverse_iterator(begin());
380
  }
381
382
  // Span::crend()
383
  //
384
  // Returns a reverse const iterator pointing just before the first element
385
  // at the beginning of this span. This pointer acts as a placeholder;
386
  // attempting to access its element results in undefined behavior.
387
  constexpr const_reverse_iterator crend() const noexcept { return rend(); }
388
389
  // Span mutations
390
391
  // Span::remove_prefix()
392
  //
393
  // Removes the first `n` elements from the span.
394
  void remove_prefix(size_type n) noexcept {
395
    ABSL_HARDENING_ASSERT(size() >= n);
396
    ptr_ += n;
397
    len_ -= n;
398
  }
399
400
  // Span::remove_suffix()
401
  //
402
  // Removes the last `n` elements from the span.
403
  void remove_suffix(size_type n) noexcept {
404
    ABSL_HARDENING_ASSERT(size() >= n);
405
    len_ -= n;
406
  }
407
408
  // Span::subspan()
409
  //
410
  // Returns a `Span` starting at element `pos` and of length `len`. Both `pos`
411
  // and `len` are of type `size_type` and thus non-negative. Parameter `pos`
412
  // must be <= size(). Any `len` value that points past the end of the span
413
  // will be trimmed to at most size() - `pos`. A default `len` value of `npos`
414
  // ensures the returned subspan continues until the end of the span.
415
  //
416
  // Examples:
417
  //
418
  //   std::vector<int> vec = {10, 11, 12, 13};
419
  //   absl::MakeSpan(vec).subspan(1, 2);  // {11, 12}
420
  //   absl::MakeSpan(vec).subspan(2, 8);  // {12, 13}
421
  //   absl::MakeSpan(vec).subspan(1);     // {11, 12, 13}
422
  //   absl::MakeSpan(vec).subspan(4);     // {}
423
  //   absl::MakeSpan(vec).subspan(5);     // throws std::out_of_range
424
  constexpr Span subspan(size_type pos = 0, size_type len = npos) const {
425
    return (pos <= size())
426
               ? Span(data() + pos, (std::min)(size() - pos, len))
427
               : (base_internal::ThrowStdOutOfRange("pos > size()"), Span());
428
  }
429
430
  // Span::first()
431
  //
432
  // Returns a `Span` containing first `len` elements. Parameter `len` is of
433
  // type `size_type` and thus non-negative. `len` value must be <= size().
434
  //
435
  // Examples:
436
  //
437
  //   std::vector<int> vec = {10, 11, 12, 13};
438
  //   absl::MakeSpan(vec).first(1);  // {10}
439
  //   absl::MakeSpan(vec).first(3);  // {10, 11, 12}
440
  //   absl::MakeSpan(vec).first(5);  // throws std::out_of_range
441
  constexpr Span first(size_type len) const {
442
    return (len <= size())
443
               ? Span(data(), len)
444
               : (base_internal::ThrowStdOutOfRange("len > size()"), Span());
445
  }
446
447
  // Span::last()
448
  //
449
  // Returns a `Span` containing last `len` elements. Parameter `len` is of
450
  // type `size_type` and thus non-negative. `len` value must be <= size().
451
  //
452
  // Examples:
453
  //
454
  //   std::vector<int> vec = {10, 11, 12, 13};
455
  //   absl::MakeSpan(vec).last(1);  // {13}
456
  //   absl::MakeSpan(vec).last(3);  // {11, 12, 13}
457
  //   absl::MakeSpan(vec).last(5);  // throws std::out_of_range
458
  constexpr Span last(size_type len) const {
459
    return (len <= size())
460
               ? Span(size() - len + data(), len)
461
               : (base_internal::ThrowStdOutOfRange("len > size()"), Span());
462
  }
463
464
  // Support for absl::Hash.
465
  template <typename H>
466
  friend H AbslHashValue(H h, Span v) {
467
    return H::combine(H::combine_contiguous(std::move(h), v.data(), v.size()),
468
                      v.size());
469
  }
470
471
 private:
472
  pointer ptr_;
473
  size_type len_;
474
};
475
476
template <typename T>
477
const typename Span<T>::size_type Span<T>::npos;
478
479
// Span relationals
480
481
// Equality is compared element-by-element, while ordering is lexicographical.
482
// We provide three overloads for each operator to cover any combination on the
483
// left or right hand side of mutable Span<T>, read-only Span<const T>, and
484
// convertible-to-read-only Span<T>.
485
// TODO(zhangxy): Due to MSVC overload resolution bug with partial ordering
486
// template functions, 5 overloads per operator is needed as a workaround. We
487
// should update them to 3 overloads per operator using non-deduced context like
488
// string_view, i.e.
489
// - (Span<T>, Span<T>)
490
// - (Span<T>, non_deduced<Span<const T>>)
491
// - (non_deduced<Span<const T>>, Span<T>)
492
493
// operator==
494
template <typename T>
495
bool operator==(Span<T> a, Span<T> b) {
496
  return span_internal::EqualImpl<Span, const T>(a, b);
497
}
498
template <typename T>
499
bool operator==(Span<const T> a, Span<T> b) {
500
  return span_internal::EqualImpl<Span, const T>(a, b);
501
}
502
template <typename T>
503
bool operator==(Span<T> a, Span<const T> b) {
504
  return span_internal::EqualImpl<Span, const T>(a, b);
505
}
506
template <
507
    typename T, typename U,
508
    typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
509
bool operator==(const U& a, Span<T> b) {
510
  return span_internal::EqualImpl<Span, const T>(a, b);
511
}
512
template <
513
    typename T, typename U,
514
    typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
515
bool operator==(Span<T> a, const U& b) {
516
  return span_internal::EqualImpl<Span, const T>(a, b);
517
}
518
519
// operator!=
520
template <typename T>
521
bool operator!=(Span<T> a, Span<T> b) {
522
  return !(a == b);
523
}
524
template <typename T>
525
bool operator!=(Span<const T> a, Span<T> b) {
526
  return !(a == b);
527
}
528
template <typename T>
529
bool operator!=(Span<T> a, Span<const T> b) {
530
  return !(a == b);
531
}
532
template <
533
    typename T, typename U,
534
    typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
535
bool operator!=(const U& a, Span<T> b) {
536
  return !(a == b);
537
}
538
template <
539
    typename T, typename U,
540
    typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
541
bool operator!=(Span<T> a, const U& b) {
542
  return !(a == b);
543
}
544
545
// operator<
546
template <typename T>
547
bool operator<(Span<T> a, Span<T> b) {
548
  return span_internal::LessThanImpl<Span, const T>(a, b);
549
}
550
template <typename T>
551
bool operator<(Span<const T> a, Span<T> b) {
552
  return span_internal::LessThanImpl<Span, const T>(a, b);
553
}
554
template <typename T>
555
bool operator<(Span<T> a, Span<const T> b) {
556
  return span_internal::LessThanImpl<Span, const T>(a, b);
557
}
558
template <
559
    typename T, typename U,
560
    typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
561
bool operator<(const U& a, Span<T> b) {
562
  return span_internal::LessThanImpl<Span, const T>(a, b);
563
}
564
template <
565
    typename T, typename U,
566
    typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
567
bool operator<(Span<T> a, const U& b) {
568
  return span_internal::LessThanImpl<Span, const T>(a, b);
569
}
570
571
// operator>
572
template <typename T>
573
bool operator>(Span<T> a, Span<T> b) {
574
  return b < a;
575
}
576
template <typename T>
577
bool operator>(Span<const T> a, Span<T> b) {
578
  return b < a;
579
}
580
template <typename T>
581
bool operator>(Span<T> a, Span<const T> b) {
582
  return b < a;
583
}
584
template <
585
    typename T, typename U,
586
    typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
587
bool operator>(const U& a, Span<T> b) {
588
  return b < a;
589
}
590
template <
591
    typename T, typename U,
592
    typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
593
bool operator>(Span<T> a, const U& b) {
594
  return b < a;
595
}
596
597
// operator<=
598
template <typename T>
599
bool operator<=(Span<T> a, Span<T> b) {
600
  return !(b < a);
601
}
602
template <typename T>
603
bool operator<=(Span<const T> a, Span<T> b) {
604
  return !(b < a);
605
}
606
template <typename T>
607
bool operator<=(Span<T> a, Span<const T> b) {
608
  return !(b < a);
609
}
610
template <
611
    typename T, typename U,
612
    typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
613
bool operator<=(const U& a, Span<T> b) {
614
  return !(b < a);
615
}
616
template <
617
    typename T, typename U,
618
    typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
619
bool operator<=(Span<T> a, const U& b) {
620
  return !(b < a);
621
}
622
623
// operator>=
624
template <typename T>
625
bool operator>=(Span<T> a, Span<T> b) {
626
  return !(a < b);
627
}
628
template <typename T>
629
bool operator>=(Span<const T> a, Span<T> b) {
630
  return !(a < b);
631
}
632
template <typename T>
633
bool operator>=(Span<T> a, Span<const T> b) {
634
  return !(a < b);
635
}
636
template <
637
    typename T, typename U,
638
    typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
639
bool operator>=(const U& a, Span<T> b) {
640
  return !(a < b);
641
}
642
template <
643
    typename T, typename U,
644
    typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
645
bool operator>=(Span<T> a, const U& b) {
646
  return !(a < b);
647
}
648
649
// MakeSpan()
650
//
651
// Constructs a mutable `Span<T>`, deducing `T` automatically from either a
652
// container or pointer+size.
653
//
654
// Because a read-only `Span<const T>` is implicitly constructed from container
655
// types regardless of whether the container itself is a const container,
656
// constructing mutable spans of type `Span<T>` from containers requires
657
// explicit constructors. The container-accepting version of `MakeSpan()`
658
// deduces the type of `T` by the constness of the pointer received from the
659
// container's `data()` member. Similarly, the pointer-accepting version returns
660
// a `Span<const T>` if `T` is `const`, and a `Span<T>` otherwise.
661
//
662
// Examples:
663
//
664
//   void MyRoutine(absl::Span<MyComplicatedType> a) {
665
//     ...
666
//   };
667
//   // my_vector is a container of non-const types
668
//   std::vector<MyComplicatedType> my_vector;
669
//
670
//   // Constructing a Span implicitly attempts to create a Span of type
671
//   // `Span<const T>`
672
//   MyRoutine(my_vector);                // error, type mismatch
673
//
674
//   // Explicitly constructing the Span is verbose
675
//   MyRoutine(absl::Span<MyComplicatedType>(my_vector));
676
//
677
//   // Use MakeSpan() to make an absl::Span<T>
678
//   MyRoutine(absl::MakeSpan(my_vector));
679
//
680
//   // Construct a span from an array ptr+size
681
//   absl::Span<T> my_span() {
682
//     return absl::MakeSpan(&array[0], num_elements_);
683
//   }
684
//
685
template <int&... ExplicitArgumentBarrier, typename T>
686
constexpr Span<T> MakeSpan(absl::Nullable<T*> ptr, size_t size) noexcept {
687
  return Span<T>(ptr, size);
688
}
689
690
template <int&... ExplicitArgumentBarrier, typename T>
691
Span<T> MakeSpan(absl::Nullable<T*> begin, absl::Nullable<T*> end) noexcept {
692
  return ABSL_HARDENING_ASSERT(begin <= end),
693
         Span<T>(begin, static_cast<size_t>(end - begin));
694
}
695
696
template <int&... ExplicitArgumentBarrier, typename C>
697
constexpr auto MakeSpan(C& c) noexcept  // NOLINT(runtime/references)
698
    -> decltype(absl::MakeSpan(span_internal::GetData(c), c.size())) {
699
  return MakeSpan(span_internal::GetData(c), c.size());
700
}
701
702
template <int&... ExplicitArgumentBarrier, typename T, size_t N>
703
0
constexpr Span<T> MakeSpan(T (&array)[N]) noexcept {
704
0
  return Span<T>(array, N);
705
0
}
Unexecuted instantiation: absl::Span<unsigned int> absl::MakeSpan<, unsigned int, 128ul>(unsigned int (&) [128ul])
Unexecuted instantiation: absl::Span<unsigned int> absl::MakeSpan<, unsigned int, 256ul>(unsigned int (&) [256ul])
Unexecuted instantiation: absl::Span<unsigned int> absl::MakeSpan<, unsigned int, 384ul>(unsigned int (&) [384ul])
Unexecuted instantiation: absl::Span<unsigned int> absl::MakeSpan<, unsigned int, 512ul>(unsigned int (&) [512ul])
Unexecuted instantiation: absl::Span<unsigned int> absl::MakeSpan<, unsigned int, 640ul>(unsigned int (&) [640ul])
706
707
// MakeConstSpan()
708
//
709
// Constructs a `Span<const T>` as with `MakeSpan`, deducing `T` automatically,
710
// but always returning a `Span<const T>`.
711
//
712
// Examples:
713
//
714
//   void ProcessInts(absl::Span<const int> some_ints);
715
//
716
//   // Call with a pointer and size.
717
//   int array[3] = { 0, 0, 0 };
718
//   ProcessInts(absl::MakeConstSpan(&array[0], 3));
719
//
720
//   // Call with a [begin, end) pair.
721
//   ProcessInts(absl::MakeConstSpan(&array[0], &array[3]));
722
//
723
//   // Call directly with an array.
724
//   ProcessInts(absl::MakeConstSpan(array));
725
//
726
//   // Call with a contiguous container.
727
//   std::vector<int> some_ints = ...;
728
//   ProcessInts(absl::MakeConstSpan(some_ints));
729
//   ProcessInts(absl::MakeConstSpan(std::vector<int>{ 0, 0, 0 }));
730
//
731
template <int&... ExplicitArgumentBarrier, typename T>
732
constexpr Span<const T> MakeConstSpan(absl::Nullable<T*> ptr,
733
                                      size_t size) noexcept {
734
  return Span<const T>(ptr, size);
735
}
736
737
template <int&... ExplicitArgumentBarrier, typename T>
738
Span<const T> MakeConstSpan(absl::Nullable<T*> begin,
739
                            absl::Nullable<T*> end) noexcept {
740
  return ABSL_HARDENING_ASSERT(begin <= end), Span<const T>(begin, end - begin);
741
}
742
743
template <int&... ExplicitArgumentBarrier, typename C>
744
constexpr auto MakeConstSpan(const C& c) noexcept -> decltype(MakeSpan(c)) {
745
  return MakeSpan(c);
746
}
747
748
template <int&... ExplicitArgumentBarrier, typename T, size_t N>
749
constexpr Span<const T> MakeConstSpan(const T (&array)[N]) noexcept {
750
  return Span<const T>(array, N);
751
}
752
ABSL_NAMESPACE_END
753
}  // namespace absl
754
#endif  // ABSL_TYPES_SPAN_H_