span.h 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751
  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. // http://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. #include <algorithm>
  58. #include <cassert>
  59. #include <cstddef>
  60. #include <initializer_list>
  61. #include <iterator>
  62. #include <string>
  63. #include <type_traits>
  64. #include <utility>
  65. #include "absl/algorithm/algorithm.h"
  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"
  70. #include "absl/meta/type_traits.h"
  71. namespace absl {
  72. inline namespace lts_2018_06_20 {
  73. template <typename T>
  74. class Span;
  75. namespace span_internal {
  76. // A constexpr min function
  77. constexpr size_t Min(size_t a, size_t b) noexcept { return a < b ? a : b; }
  78. // Wrappers for access to container data pointers.
  79. template <typename C>
  80. constexpr auto GetDataImpl(C& c, char) noexcept // NOLINT(runtime/references)
  81. -> decltype(c.data()) {
  82. return c.data();
  83. }
  84. // Before C++17, std::string::data returns a const char* in all cases.
  85. inline char* GetDataImpl(std::string& s, // NOLINT(runtime/references)
  86. int) noexcept {
  87. return &s[0];
  88. }
  89. template <typename C>
  90. constexpr auto GetData(C& c) noexcept // NOLINT(runtime/references)
  91. -> decltype(GetDataImpl(c, 0)) {
  92. return GetDataImpl(c, 0);
  93. }
  94. // Detection idioms for size() and data().
  95. template <typename C>
  96. using HasSize =
  97. std::is_integral<absl::decay_t<decltype(std::declval<C&>().size())>>;
  98. // We want to enable conversion from vector<T*> to Span<const T* const> but
  99. // disable conversion from vector<Derived> to Span<Base>. Here we use
  100. // the fact that U** is convertible to Q* const* if and only if Q is the same
  101. // type or a more cv-qualified version of U. We also decay the result type of
  102. // data() to avoid problems with classes which have a member function data()
  103. // which returns a reference.
  104. template <typename T, typename C>
  105. using HasData =
  106. std::is_convertible<absl::decay_t<decltype(GetData(std::declval<C&>()))>*,
  107. T* const*>;
  108. // Extracts value type from a Container
  109. template <typename C>
  110. struct ElementType {
  111. using type = typename absl::remove_reference_t<C>::value_type;
  112. };
  113. template <typename T, size_t N>
  114. struct ElementType<T (&)[N]> {
  115. using type = T;
  116. };
  117. template <typename C>
  118. using ElementT = typename ElementType<C>::type;
  119. template <typename T>
  120. using EnableIfMutable =
  121. typename std::enable_if<!std::is_const<T>::value, int>::type;
  122. template <typename T>
  123. bool EqualImpl(Span<T> a, Span<T> b) {
  124. static_assert(std::is_const<T>::value, "");
  125. return absl::equal(a.begin(), a.end(), b.begin(), b.end());
  126. }
  127. template <typename T>
  128. bool LessThanImpl(Span<T> a, Span<T> b) {
  129. static_assert(std::is_const<T>::value, "");
  130. return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end());
  131. }
  132. // The `IsConvertible` classes here are needed because of the
  133. // `std::is_convertible` bug in libcxx when compiled with GCC. This build
  134. // configuration is used by Android NDK toolchain. Reference link:
  135. // https://bugs.llvm.org/show_bug.cgi?id=27538.
  136. template <typename From, typename To>
  137. struct IsConvertibleHelper {
  138. private:
  139. static std::true_type testval(To);
  140. static std::false_type testval(...);
  141. public:
  142. using type = decltype(testval(std::declval<From>()));
  143. };
  144. template <typename From, typename To>
  145. struct IsConvertible : IsConvertibleHelper<From, To>::type {};
  146. // TODO(zhangxy): replace `IsConvertible` with `std::is_convertible` once the
  147. // older version of libcxx is not supported.
  148. template <typename From, typename To>
  149. using EnableIfConvertibleToSpanConst =
  150. typename std::enable_if<IsConvertible<From, Span<const To>>::value>::type;
  151. } // namespace span_internal
  152. //------------------------------------------------------------------------------
  153. // Span
  154. //------------------------------------------------------------------------------
  155. //
  156. // A `Span` is an "array view" type for holding a view of a contiguous data
  157. // array; the `Span` object does not and cannot own such data itself. A span
  158. // provides an easy way to provide overloads for anything operating on
  159. // contiguous sequences without needing to manage pointers and array lengths
  160. // manually.
  161. // A span is conceptually a pointer (ptr) and a length (size) into an already
  162. // existing array of contiguous memory; the array it represents references the
  163. // elements "ptr[0] .. ptr[size-1]". Passing a properly-constructed `Span`
  164. // instead of raw pointers avoids many issues related to index out of bounds
  165. // errors.
  166. //
  167. // Spans may also be constructed from containers holding contiguous sequences.
  168. // Such containers must supply `data()` and `size() const` methods (e.g
  169. // `std::vector<T>`, `absl::InlinedVector<T, N>`). All implicit conversions to
  170. // `absl::Span` from such containers will create spans of type `const T`;
  171. // spans which can mutate their values (of type `T`) must use explicit
  172. // constructors.
  173. //
  174. // A `Span<T>` is somewhat analogous to an `absl::string_view`, but for an array
  175. // of elements of type `T`. A user of `Span` must ensure that the data being
  176. // pointed to outlives the `Span` itself.
  177. //
  178. // You can construct a `Span<T>` in several ways:
  179. //
  180. // * Explicitly from a reference to a container type
  181. // * Explicitly from a pointer and size
  182. // * Implicitly from a container type (but only for spans of type `const T`)
  183. // * Using the `MakeSpan()` or `MakeConstSpan()` factory functions.
  184. //
  185. // Examples:
  186. //
  187. // // Construct a Span explicitly from a container:
  188. // std::vector<int> v = {1, 2, 3, 4, 5};
  189. // auto span = absl::Span<const int>(v);
  190. //
  191. // // Construct a Span explicitly from a C-style array:
  192. // int a[5] = {1, 2, 3, 4, 5};
  193. // auto span = absl::Span<const int>(a);
  194. //
  195. // // Construct a Span implicitly from a container
  196. // void MyRoutine(absl::Span<const int> a) {
  197. // ...
  198. // }
  199. // std::vector v = {1,2,3,4,5};
  200. // MyRoutine(v) // convert to Span<const T>
  201. //
  202. // Note that `Span` objects, in addition to requiring that the memory they
  203. // point to remains alive, must also ensure that such memory does not get
  204. // reallocated. Therefore, to avoid undefined behavior, containers with
  205. // associated span views should not invoke operations that may reallocate memory
  206. // (such as resizing) or invalidate iterators into the container.
  207. //
  208. // One common use for a `Span` is when passing arguments to a routine that can
  209. // accept a variety of array types (e.g. a `std::vector`, `absl::InlinedVector`,
  210. // a C-style array, etc.). Instead of creating overloads for each case, you
  211. // can simply specify a `Span` as the argument to such a routine.
  212. //
  213. // Example:
  214. //
  215. // void MyRoutine(absl::Span<const int> a) {
  216. // ...
  217. // }
  218. //
  219. // std::vector v = {1,2,3,4,5};
  220. // MyRoutine(v);
  221. //
  222. // absl::InlinedVector<int, 4> my_inline_vector;
  223. // MyRoutine(my_inline_vector);
  224. //
  225. // // Explicit constructor from pointer,size
  226. // int* my_array = new int[10];
  227. // MyRoutine(absl::Span<const int>(my_array, 10));
  228. template <typename T>
  229. class Span {
  230. private:
  231. // Used to determine whether a Span can be constructed from a container of
  232. // type C.
  233. template <typename C>
  234. using EnableIfConvertibleFrom =
  235. typename std::enable_if<span_internal::HasData<T, C>::value &&
  236. span_internal::HasSize<C>::value>::type;
  237. // Used to SFINAE-enable a function when the slice elements are const.
  238. template <typename U>
  239. using EnableIfConstView =
  240. typename std::enable_if<std::is_const<T>::value, U>::type;
  241. // Used to SFINAE-enable a function when the slice elements are mutable.
  242. template <typename U>
  243. using EnableIfMutableView =
  244. typename std::enable_if<!std::is_const<T>::value, U>::type;
  245. public:
  246. using value_type = absl::remove_cv_t<T>;
  247. using pointer = T*;
  248. using const_pointer = const T*;
  249. using reference = T&;
  250. using const_reference = const T&;
  251. using iterator = pointer;
  252. using const_iterator = const_pointer;
  253. using reverse_iterator = std::reverse_iterator<iterator>;
  254. using const_reverse_iterator = std::reverse_iterator<const_iterator>;
  255. using size_type = size_t;
  256. using difference_type = ptrdiff_t;
  257. static const size_type npos = ~(size_type(0));
  258. constexpr Span() noexcept : Span(nullptr, 0) {}
  259. constexpr Span(pointer array, size_type length) noexcept
  260. : ptr_(array), len_(length) {}
  261. // Implicit conversion constructors
  262. template <size_t N>
  263. constexpr Span(T (&a)[N]) noexcept // NOLINT(runtime/explicit)
  264. : Span(a, N) {}
  265. // Explicit reference constructor for a mutable `Span<T>` type. Can be
  266. // replaced with MakeSpan() to infer the type parameter.
  267. template <typename V, typename = EnableIfConvertibleFrom<V>,
  268. typename = EnableIfMutableView<V>>
  269. explicit Span(V& v) noexcept // NOLINT(runtime/references)
  270. : Span(span_internal::GetData(v), v.size()) {}
  271. // Implicit reference constructor for a read-only `Span<const T>` type
  272. template <typename V, typename = EnableIfConvertibleFrom<V>,
  273. typename = EnableIfConstView<V>>
  274. constexpr Span(const V& v) noexcept // NOLINT(runtime/explicit)
  275. : Span(span_internal::GetData(v), v.size()) {}
  276. // Implicit constructor from an initializer list, making it possible to pass a
  277. // brace-enclosed initializer list to a function expecting a `Span`. Such
  278. // spans constructed from an initializer list must be of type `Span<const T>`.
  279. //
  280. // void Process(absl::Span<const int> x);
  281. // Process({1, 2, 3});
  282. //
  283. // Note that as always the array referenced by the span must outlive the span.
  284. // Since an initializer list constructor acts as if it is fed a temporary
  285. // array (cf. C++ standard [dcl.init.list]/5), it's safe to use this
  286. // constructor only when the `std::initializer_list` itself outlives the span.
  287. // In order to meet this requirement it's sufficient to ensure that neither
  288. // the span nor a copy of it is used outside of the expression in which it's
  289. // created:
  290. //
  291. // // Assume that this function uses the array directly, not retaining any
  292. // // copy of the span or pointer to any of its elements.
  293. // void Process(absl::Span<const int> ints);
  294. //
  295. // // Okay: the std::initializer_list<int> will reference a temporary array
  296. // // that isn't destroyed until after the call to Process returns.
  297. // Process({ 17, 19 });
  298. //
  299. // // Not okay: the storage used by the std::initializer_list<int> is not
  300. // // allowed to be referenced after the first line.
  301. // absl::Span<const int> ints = { 17, 19 };
  302. // Process(ints);
  303. //
  304. // // Not okay for the same reason as above: even when the elements of the
  305. // // initializer list expression are not temporaries the underlying array
  306. // // is, so the initializer list must still outlive the span.
  307. // const int foo = 17;
  308. // absl::Span<const int> ints = { foo };
  309. // Process(ints);
  310. //
  311. template <typename LazyT = T,
  312. typename = EnableIfConstView<LazyT>>
  313. Span(
  314. std::initializer_list<value_type> v) noexcept // NOLINT(runtime/explicit)
  315. : Span(v.begin(), v.size()) {}
  316. // Accessors
  317. // Span::data()
  318. //
  319. // Returns a pointer to the span's underlying array of data (which is held
  320. // outside the span).
  321. constexpr pointer data() const noexcept { return ptr_; }
  322. // Span::size()
  323. //
  324. // Returns the size of this span.
  325. constexpr size_type size() const noexcept { return len_; }
  326. // Span::length()
  327. //
  328. // Returns the length (size) of this span.
  329. constexpr size_type length() const noexcept { return size(); }
  330. // Span::empty()
  331. //
  332. // Returns a boolean indicating whether or not this span is considered empty.
  333. constexpr bool empty() const noexcept { return size() == 0; }
  334. // Span::operator[]
  335. //
  336. // Returns a reference to the i'th element of this span.
  337. constexpr reference operator[](size_type i) const noexcept {
  338. // MSVC 2015 accepts this as constexpr, but not ptr_[i]
  339. return *(data() + i);
  340. }
  341. // Span::at()
  342. //
  343. // Returns a reference to the i'th element of this span.
  344. constexpr reference at(size_type i) const {
  345. return ABSL_PREDICT_TRUE(i < size())
  346. ? ptr_[i]
  347. : (base_internal::ThrowStdOutOfRange(
  348. "Span::at failed bounds check"),
  349. ptr_[i]);
  350. }
  351. // Span::front()
  352. //
  353. // Returns a reference to the first element of this span.
  354. reference front() const noexcept { return ABSL_ASSERT(size() > 0), ptr_[0]; }
  355. // Span::back()
  356. //
  357. // Returns a reference to the last element of this span.
  358. reference back() const noexcept {
  359. return ABSL_ASSERT(size() > 0), ptr_[size() - 1];
  360. }
  361. // Span::begin()
  362. //
  363. // Returns an iterator to the first element of this span.
  364. constexpr iterator begin() const noexcept { return ptr_; }
  365. // Span::cbegin()
  366. //
  367. // Returns a const iterator to the first element of this span.
  368. constexpr const_iterator cbegin() const noexcept { return ptr_; }
  369. // Span::end()
  370. //
  371. // Returns an iterator to the last element of this span.
  372. iterator end() const noexcept { return ptr_ + len_; }
  373. // Span::cend()
  374. //
  375. // Returns a const iterator to the last element of this span.
  376. const_iterator cend() const noexcept { return end(); }
  377. // Span::rbegin()
  378. //
  379. // Returns a reverse iterator starting at the last element of this span.
  380. reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); }
  381. // Span::crbegin()
  382. //
  383. // Returns a reverse const iterator starting at the last element of this span.
  384. const_reverse_iterator crbegin() const noexcept { return rbegin(); }
  385. // Span::rend()
  386. //
  387. // Returns a reverse iterator starting at the first element of this span.
  388. reverse_iterator rend() const noexcept { return reverse_iterator(begin()); }
  389. // Span::crend()
  390. //
  391. // Returns a reverse iterator starting at the first element of this span.
  392. const_reverse_iterator crend() const noexcept { return rend(); }
  393. // Span mutations
  394. // Span::remove_prefix()
  395. //
  396. // Removes the first `n` elements from the span.
  397. void remove_prefix(size_type n) noexcept {
  398. assert(len_ >= n);
  399. ptr_ += n;
  400. len_ -= n;
  401. }
  402. // Span::remove_suffix()
  403. //
  404. // Removes the last `n` elements from the span.
  405. void remove_suffix(size_type n) noexcept {
  406. assert(len_ >= n);
  407. len_ -= n;
  408. }
  409. // Span::subspan()
  410. //
  411. // Returns a `Span` starting at element `pos` and of length `len`. Both `pos`
  412. // and `len` are of type `size_type` and thus non-negative. Parameter `pos`
  413. // must be <= size(). Any `len` value that points past the end of the span
  414. // will be trimmed to at most size() - `pos`. A default `len` value of `npos`
  415. // ensures the returned subspan continues until the end of the span.
  416. //
  417. // Examples:
  418. //
  419. // std::vector<int> vec = {10, 11, 12, 13};
  420. // absl::MakeSpan(vec).subspan(1, 2); // {11, 12}
  421. // absl::MakeSpan(vec).subspan(2, 8); // {12, 13}
  422. // absl::MakeSpan(vec).subspan(1); // {11, 12, 13}
  423. // absl::MakeSpan(vec).subspan(4); // {}
  424. // absl::MakeSpan(vec).subspan(5); // throws std::out_of_range
  425. constexpr Span subspan(size_type pos = 0, size_type len = npos) const {
  426. return (pos <= len_)
  427. ? Span(ptr_ + pos, span_internal::Min(len_ - pos, len))
  428. : (base_internal::ThrowStdOutOfRange("pos > size()"), Span());
  429. }
  430. private:
  431. pointer ptr_;
  432. size_type len_;
  433. };
  434. template <typename T>
  435. const typename Span<T>::size_type Span<T>::npos;
  436. // Span relationals
  437. // Equality is compared element-by-element, while ordering is lexicographical.
  438. // We provide three overloads for each operator to cover any combination on the
  439. // left or right hand side of mutable Span<T>, read-only Span<const T>, and
  440. // convertible-to-read-only Span<T>.
  441. // TODO(zhangxy): Due to MSVC overload resolution bug with partial ordering
  442. // template functions, 5 overloads per operator is needed as a workaround. We
  443. // should update them to 3 overloads per operator using non-deduced context like
  444. // string_view, i.e.
  445. // - (Span<T>, Span<T>)
  446. // - (Span<T>, non_deduced<Span<const T>>)
  447. // - (non_deduced<Span<const T>>, Span<T>)
  448. // operator==
  449. template <typename T>
  450. bool operator==(Span<T> a, Span<T> b) {
  451. return span_internal::EqualImpl<const T>(a, b);
  452. }
  453. template <typename T>
  454. bool operator==(Span<const T> a, Span<T> b) {
  455. return span_internal::EqualImpl<const T>(a, b);
  456. }
  457. template <typename T>
  458. bool operator==(Span<T> a, Span<const T> b) {
  459. return span_internal::EqualImpl<const T>(a, b);
  460. }
  461. template <typename T, typename U,
  462. typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
  463. bool operator==(const U& a, Span<T> b) {
  464. return span_internal::EqualImpl<const T>(a, b);
  465. }
  466. template <typename T, typename U,
  467. typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
  468. bool operator==(Span<T> a, const U& b) {
  469. return span_internal::EqualImpl<const T>(a, b);
  470. }
  471. // operator!=
  472. template <typename T>
  473. bool operator!=(Span<T> a, Span<T> b) {
  474. return !(a == b);
  475. }
  476. template <typename T>
  477. bool operator!=(Span<const T> a, Span<T> b) {
  478. return !(a == b);
  479. }
  480. template <typename T>
  481. bool operator!=(Span<T> a, Span<const T> b) {
  482. return !(a == b);
  483. }
  484. template <typename T, typename U,
  485. typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
  486. bool operator!=(const U& a, Span<T> b) {
  487. return !(a == b);
  488. }
  489. template <typename T, typename U,
  490. typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
  491. bool operator!=(Span<T> a, const U& b) {
  492. return !(a == b);
  493. }
  494. // operator<
  495. template <typename T>
  496. bool operator<(Span<T> a, Span<T> b) {
  497. return span_internal::LessThanImpl<const T>(a, b);
  498. }
  499. template <typename T>
  500. bool operator<(Span<const T> a, Span<T> b) {
  501. return span_internal::LessThanImpl<const T>(a, b);
  502. }
  503. template <typename T>
  504. bool operator<(Span<T> a, Span<const T> b) {
  505. return span_internal::LessThanImpl<const T>(a, b);
  506. }
  507. template <typename T, typename U,
  508. typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
  509. bool operator<(const U& a, Span<T> b) {
  510. return span_internal::LessThanImpl<const T>(a, b);
  511. }
  512. template <typename T, typename U,
  513. typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
  514. bool operator<(Span<T> a, const U& b) {
  515. return span_internal::LessThanImpl<const T>(a, b);
  516. }
  517. // operator>
  518. template <typename T>
  519. bool operator>(Span<T> a, Span<T> b) {
  520. return b < a;
  521. }
  522. template <typename T>
  523. bool operator>(Span<const T> a, Span<T> b) {
  524. return b < a;
  525. }
  526. template <typename T>
  527. bool operator>(Span<T> a, Span<const T> b) {
  528. return b < a;
  529. }
  530. template <typename T, typename U,
  531. typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
  532. bool operator>(const U& a, Span<T> b) {
  533. return b < a;
  534. }
  535. template <typename T, typename U,
  536. typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
  537. bool operator>(Span<T> a, const U& b) {
  538. return b < a;
  539. }
  540. // operator<=
  541. template <typename T>
  542. bool operator<=(Span<T> a, Span<T> b) {
  543. return !(b < a);
  544. }
  545. template <typename T>
  546. bool operator<=(Span<const T> a, Span<T> b) {
  547. return !(b < a);
  548. }
  549. template <typename T>
  550. bool operator<=(Span<T> a, Span<const T> b) {
  551. return !(b < a);
  552. }
  553. template <typename T, typename U,
  554. typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
  555. bool operator<=(const U& a, Span<T> b) {
  556. return !(b < a);
  557. }
  558. template <typename T, typename U,
  559. typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
  560. bool operator<=(Span<T> a, const U& b) {
  561. return !(b < a);
  562. }
  563. // operator>=
  564. template <typename T>
  565. bool operator>=(Span<T> a, Span<T> b) {
  566. return !(a < b);
  567. }
  568. template <typename T>
  569. bool operator>=(Span<const T> a, Span<T> b) {
  570. return !(a < b);
  571. }
  572. template <typename T>
  573. bool operator>=(Span<T> a, Span<const T> b) {
  574. return !(a < b);
  575. }
  576. template <typename T, typename U,
  577. typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
  578. bool operator>=(const U& a, Span<T> b) {
  579. return !(a < b);
  580. }
  581. template <typename T, typename U,
  582. typename = span_internal::EnableIfConvertibleToSpanConst<U, T>>
  583. bool operator>=(Span<T> a, const U& b) {
  584. return !(a < b);
  585. }
  586. // MakeSpan()
  587. //
  588. // Constructs a mutable `Span<T>`, deducing `T` automatically from either a
  589. // container or pointer+size.
  590. //
  591. // Because a read-only `Span<const T>` is implicitly constructed from container
  592. // types regardless of whether the container itself is a const container,
  593. // constructing mutable spans of type `Span<T>` from containers requires
  594. // explicit constructors. The container-accepting version of `MakeSpan()`
  595. // deduces the type of `T` by the constness of the pointer received from the
  596. // container's `data()` member. Similarly, the pointer-accepting version returns
  597. // a `Span<const T>` if `T` is `const`, and a `Span<T>` otherwise.
  598. //
  599. // Examples:
  600. //
  601. // void MyRoutine(absl::Span<MyComplicatedType> a) {
  602. // ...
  603. // };
  604. // // my_vector is a container of non-const types
  605. // std::vector<MyComplicatedType> my_vector;
  606. //
  607. // // Constructing a Span implicitly attempts to create a Span of type
  608. // // `Span<const T>`
  609. // MyRoutine(my_vector); // error, type mismatch
  610. //
  611. // // Explicitly constructing the Span is verbose
  612. // MyRoutine(absl::Span<MyComplicatedType>(my_vector));
  613. //
  614. // // Use MakeSpan() to make an absl::Span<T>
  615. // MyRoutine(absl::MakeSpan(my_vector));
  616. //
  617. // // Construct a span from an array ptr+size
  618. // absl::Span<T> my_span() {
  619. // return absl::MakeSpan(&array[0], num_elements_);
  620. // }
  621. //
  622. template <int&... ExplicitArgumentBarrier, typename T>
  623. constexpr Span<T> MakeSpan(T* ptr, size_t size) noexcept {
  624. return Span<T>(ptr, size);
  625. }
  626. template <int&... ExplicitArgumentBarrier, typename T>
  627. Span<T> MakeSpan(T* begin, T* end) noexcept {
  628. return ABSL_ASSERT(begin <= end), Span<T>(begin, end - begin);
  629. }
  630. template <int&... ExplicitArgumentBarrier, typename C>
  631. constexpr auto MakeSpan(C& c) noexcept // NOLINT(runtime/references)
  632. -> decltype(absl::MakeSpan(span_internal::GetData(c), c.size())) {
  633. return MakeSpan(span_internal::GetData(c), c.size());
  634. }
  635. template <int&... ExplicitArgumentBarrier, typename T, size_t N>
  636. constexpr Span<T> MakeSpan(T (&array)[N]) noexcept {
  637. return Span<T>(array, N);
  638. }
  639. // MakeConstSpan()
  640. //
  641. // Constructs a `Span<const T>` as with `MakeSpan`, deducing `T` automatically,
  642. // but always returning a `Span<const T>`.
  643. //
  644. // Examples:
  645. //
  646. // void ProcessInts(absl::Span<const int> some_ints);
  647. //
  648. // // Call with a pointer and size.
  649. // int array[3] = { 0, 0, 0 };
  650. // ProcessInts(absl::MakeConstSpan(&array[0], 3));
  651. //
  652. // // Call with a [begin, end) pair.
  653. // ProcessInts(absl::MakeConstSpan(&array[0], &array[3]));
  654. //
  655. // // Call directly with an array.
  656. // ProcessInts(absl::MakeConstSpan(array));
  657. //
  658. // // Call with a contiguous container.
  659. // std::vector<int> some_ints = ...;
  660. // ProcessInts(absl::MakeConstSpan(some_ints));
  661. // ProcessInts(absl::MakeConstSpan(std::vector<int>{ 0, 0, 0 }));
  662. //
  663. template <int&... ExplicitArgumentBarrier, typename T>
  664. constexpr Span<const T> MakeConstSpan(T* ptr, size_t size) noexcept {
  665. return Span<const T>(ptr, size);
  666. }
  667. template <int&... ExplicitArgumentBarrier, typename T>
  668. Span<const T> MakeConstSpan(T* begin, T* end) noexcept {
  669. return ABSL_ASSERT(begin <= end), Span<const T>(begin, end - begin);
  670. }
  671. template <int&... ExplicitArgumentBarrier, typename C>
  672. constexpr auto MakeConstSpan(const C& c) noexcept -> decltype(MakeSpan(c)) {
  673. return MakeSpan(c);
  674. }
  675. template <int&... ExplicitArgumentBarrier, typename T, size_t N>
  676. constexpr Span<const T> MakeConstSpan(const T (&array)[N]) noexcept {
  677. return Span<const T>(array, N);
  678. }
  679. } // inline namespace lts_2018_06_20
  680. } // namespace absl
  681. #endif // ABSL_TYPES_SPAN_H_