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
70namespace absl {
71ABSL_NAMESPACE_BEGIN
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));
151template <typename T>
152class Span {
153 private:
154 // Used to determine whether a Span can be constructed from a container of
155 // type C.
156 template <typename C>
157 using EnableIfConvertibleFrom =
158 typename std::enable_if<span_internal::HasData<T, C>::value &&
159 span_internal::HasSize<C>::value>::type;
160
161 // Used to SFINAE-enable a function when the slice elements are const.
162 template <typename U>
163 using EnableIfConstView =
164 typename std::enable_if<std::is_const<T>::value, U>::type;
165
166 // Used to SFINAE-enable a function when the slice elements are mutable.
167 template <typename U>
168 using EnableIfMutableView =
169 typename std::enable_if<!std::is_const<T>::value, U>::type;
170
171 public:
172 using element_type = T;
173 using value_type = absl::remove_cv_t<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;
179 using const_iterator = const_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)
287 : (base_internal::ThrowStdOutOfRange(
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 {
370 ABSL_HARDENING_ASSERT(size() >= n);
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 {
379 ABSL_HARDENING_ASSERT(size() >= n);
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:
447 pointer ptr_;
448 size_type len_;
449};
450
451template <typename T>
452const 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==
469template <typename T>
470bool operator==(Span<T> a, Span<T> b) {
471 return span_internal::EqualImpl<Span, const T>(a, b);
472}
473template <typename T>
474bool operator==(Span<const T> a, Span<T> b) {
475 return span_internal::EqualImpl<Span, const T>(a, b);
476}
477template <typename T>
478bool operator==(Span<T> a, Span<const T> b) {
479 return span_internal::EqualImpl<Span, const T>(a, b);
480}
481template <
482 typename T, typename U,
483 typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
484bool operator==(const U& a, Span<T> b) {
485 return span_internal::EqualImpl<Span, const T>(a, b);
486}
487template <
488 typename T, typename U,
489 typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
490bool operator==(Span<T> a, const U& b) {
491 return span_internal::EqualImpl<Span, const T>(a, b);
492}
493
494// operator!=
495template <typename T>
496bool operator!=(Span<T> a, Span<T> b) {
497 return !(a == b);
498}
499template <typename T>
500bool operator!=(Span<const T> a, Span<T> b) {
501 return !(a == b);
502}
503template <typename T>
504bool operator!=(Span<T> a, Span<const T> b) {
505 return !(a == b);
506}
507template <
508 typename T, typename U,
509 typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
510bool operator!=(const U& a, Span<T> b) {
511 return !(a == b);
512}
513template <
514 typename T, typename U,
515 typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
516bool operator!=(Span<T> a, const U& b) {
517 return !(a == b);
518}
519
520// operator<
521template <typename T>
522bool operator<(Span<T> a, Span<T> b) {
523 return span_internal::LessThanImpl<Span, const T>(a, b);
524}
525template <typename T>
526bool operator<(Span<const T> a, Span<T> b) {
527 return span_internal::LessThanImpl<Span, const T>(a, b);
528}
529template <typename T>
530bool operator<(Span<T> a, Span<const T> b) {
531 return span_internal::LessThanImpl<Span, const T>(a, b);
532}
533template <
534 typename T, typename U,
535 typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
536bool operator<(const U& a, Span<T> b) {
537 return span_internal::LessThanImpl<Span, const T>(a, b);
538}
539template <
540 typename T, typename U,
541 typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
542bool operator<(Span<T> a, const U& b) {
543 return span_internal::LessThanImpl<Span, const T>(a, b);
544}
545
546// operator>
547template <typename T>
548bool operator>(Span<T> a, Span<T> b) {
549 return b < a;
550}
551template <typename T>
552bool operator>(Span<const T> a, Span<T> b) {
553 return b < a;
554}
555template <typename T>
556bool operator>(Span<T> a, Span<const T> b) {
557 return b < a;
558}
559template <
560 typename T, typename U,
561 typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
562bool operator>(const U& a, Span<T> b) {
563 return b < a;
564}
565template <
566 typename T, typename U,
567 typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
568bool operator>(Span<T> a, const U& b) {
569 return b < a;
570}
571
572// operator<=
573template <typename T>
574bool operator<=(Span<T> a, Span<T> b) {
575 return !(b < a);
576}
577template <typename T>
578bool operator<=(Span<const T> a, Span<T> b) {
579 return !(b < a);
580}
581template <typename T>
582bool operator<=(Span<T> a, Span<const T> b) {
583 return !(b < a);
584}
585template <
586 typename T, typename U,
587 typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
588bool operator<=(const U& a, Span<T> b) {
589 return !(b < a);
590}
591template <
592 typename T, typename U,
593 typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
594bool operator<=(Span<T> a, const U& b) {
595 return !(b < a);
596}
597
598// operator>=
599template <typename T>
600bool operator>=(Span<T> a, Span<T> b) {
601 return !(a < b);
602}
603template <typename T>
604bool operator>=(Span<const T> a, Span<T> b) {
605 return !(a < b);
606}
607template <typename T>
608bool operator>=(Span<T> a, Span<const T> b) {
609 return !(a < b);
610}
611template <
612 typename T, typename U,
613 typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
614bool operator>=(const U& a, Span<T> b) {
615 return !(a < b);
616}
617template <
618 typename T, typename U,
619 typename = span_internal::EnableIfConvertibleTo<U, absl::Span<const T>>>
620bool 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//
660template <int&... ExplicitArgumentBarrier, typename T>
661constexpr Span<T> MakeSpan(T* ptr, size_t size) noexcept {
662 return Span<T>(ptr, size);
663}
664
665template <int&... ExplicitArgumentBarrier, typename T>
666Span<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
671template <int&... ExplicitArgumentBarrier, typename C>
672constexpr 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
677template <int&... ExplicitArgumentBarrier, typename T, size_t N>
678constexpr 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//
706template <int&... ExplicitArgumentBarrier, typename T>
707constexpr Span<const T> MakeConstSpan(T* ptr, size_t size) noexcept {
708 return Span<const T>(ptr, size);
709}
710
711template <int&... ExplicitArgumentBarrier, typename T>
712Span<const T> MakeConstSpan(T* begin, T* end) noexcept {
713 return ABSL_HARDENING_ASSERT(begin <= end), Span<const T>(begin, end - begin);
714}
715
716template <int&... ExplicitArgumentBarrier, typename C>
717constexpr auto MakeConstSpan(const C& c) noexcept -> decltype(MakeSpan(c)) {
718 return MakeSpan(c);
719}
720
721template <int&... ExplicitArgumentBarrier, typename T, size_t N>
722constexpr Span<const T> MakeConstSpan(const T (&array)[N]) noexcept {
723 return Span<const T>(array, N);
724}
725ABSL_NAMESPACE_END
726} // namespace absl
727#endif // ABSL_TYPES_SPAN_H_
728