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