span 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591
  1. // -*- C++ -*-
  2. //===------------------------------ span ---------------------------------===//
  3. //
  4. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  5. // See https://llvm.org/LICENSE.txt for license information.
  6. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  7. //
  8. //===---------------------------------------------------------------------===//
  9. #ifndef _LIBCPP_SPAN
  10. #define _LIBCPP_SPAN
  11. /*
  12. span synopsis
  13. namespace std {
  14. // constants
  15. inline constexpr size_t dynamic_extent = numeric_limits<size_t>::max();
  16. // [views.span], class template span
  17. template <class ElementType, size_t Extent = dynamic_extent>
  18. class span;
  19. // [span.objectrep], views of object representation
  20. template <class ElementType, size_t Extent>
  21. span<const byte, ((Extent == dynamic_extent) ? dynamic_extent :
  22. (sizeof(ElementType) * Extent))> as_bytes(span<ElementType, Extent> s) noexcept;
  23. template <class ElementType, size_t Extent>
  24. span< byte, ((Extent == dynamic_extent) ? dynamic_extent :
  25. (sizeof(ElementType) * Extent))> as_writable_bytes(span<ElementType, Extent> s) noexcept;
  26. namespace std {
  27. template <class ElementType, size_t Extent = dynamic_extent>
  28. class span {
  29. public:
  30. // constants and types
  31. using element_type = ElementType;
  32. using value_type = remove_cv_t<ElementType>;
  33. using index_type = size_t;
  34. using difference_type = ptrdiff_t;
  35. using pointer = element_type*;
  36. using const_pointer = const element_type*;
  37. using reference = element_type&;
  38. using const_reference = const element_type&;
  39. using iterator = implementation-defined;
  40. using const_iterator = implementation-defined;
  41. using reverse_iterator = std::reverse_iterator<iterator>;
  42. using const_reverse_iterator = std::reverse_iterator<const_iterator>;
  43. static constexpr index_type extent = Extent;
  44. // [span.cons], span constructors, copy, assignment, and destructor
  45. constexpr span() noexcept;
  46. constexpr span(pointer ptr, index_type count);
  47. constexpr span(pointer firstElem, pointer lastElem);
  48. template <size_t N>
  49. constexpr span(element_type (&arr)[N]) noexcept;
  50. template <size_t N>
  51. constexpr span(array<value_type, N>& arr) noexcept;
  52. template <size_t N>
  53. constexpr span(const array<value_type, N>& arr) noexcept;
  54. template <class Container>
  55. constexpr span(Container& cont);
  56. template <class Container>
  57. constexpr span(const Container& cont);
  58. constexpr span(const span& other) noexcept = default;
  59. template <class OtherElementType, size_t OtherExtent>
  60. constexpr span(const span<OtherElementType, OtherExtent>& s) noexcept;
  61. ~span() noexcept = default;
  62. constexpr span& operator=(const span& other) noexcept = default;
  63. // [span.sub], span subviews
  64. template <size_t Count>
  65. constexpr span<element_type, Count> first() const;
  66. template <size_t Count>
  67. constexpr span<element_type, Count> last() const;
  68. template <size_t Offset, size_t Count = dynamic_extent>
  69. constexpr span<element_type, see below> subspan() const;
  70. constexpr span<element_type, dynamic_extent> first(index_type count) const;
  71. constexpr span<element_type, dynamic_extent> last(index_type count) const;
  72. constexpr span<element_type, dynamic_extent> subspan(index_type offset, index_type count = dynamic_extent) const;
  73. // [span.obs], span observers
  74. constexpr index_type size() const noexcept;
  75. constexpr index_type size_bytes() const noexcept;
  76. constexpr bool empty() const noexcept;
  77. // [span.elem], span element access
  78. constexpr reference operator[](index_type idx) const;
  79. constexpr reference front() const;
  80. constexpr reference back() const;
  81. constexpr pointer data() const noexcept;
  82. // [span.iterators], span iterator support
  83. constexpr iterator begin() const noexcept;
  84. constexpr iterator end() const noexcept;
  85. constexpr const_iterator cbegin() const noexcept;
  86. constexpr const_iterator cend() const noexcept;
  87. constexpr reverse_iterator rbegin() const noexcept;
  88. constexpr reverse_iterator rend() const noexcept;
  89. constexpr const_reverse_iterator crbegin() const noexcept;
  90. constexpr const_reverse_iterator crend() const noexcept;
  91. private:
  92. pointer data_; // exposition only
  93. index_type size_; // exposition only
  94. };
  95. template<class T, size_t N>
  96. span(T (&)[N]) -> span<T, N>;
  97. template<class T, size_t N>
  98. span(array<T, N>&) -> span<T, N>;
  99. template<class T, size_t N>
  100. span(const array<T, N>&) -> span<const T, N>;
  101. template<class Container>
  102. span(Container&) -> span<typename Container::value_type>;
  103. template<class Container>
  104. span(const Container&) -> span<const typename Container::value_type>;
  105. } // namespace std
  106. */
  107. #include <__config>
  108. #include <cstddef> // for ptrdiff_t
  109. #include <iterator> // for iterators
  110. #include <array> // for array
  111. #include <type_traits> // for remove_cv, etc
  112. #include <cstddef> // for byte
  113. #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
  114. #pragma GCC system_header
  115. #endif
  116. _LIBCPP_BEGIN_NAMESPACE_STD
  117. #if _LIBCPP_STD_VER > 17
  118. inline constexpr size_t dynamic_extent = numeric_limits<size_t>::max();
  119. template <typename _Tp, size_t _Extent = dynamic_extent> class span;
  120. template <class _Tp>
  121. struct __is_span_impl : public false_type {};
  122. template <class _Tp, size_t _Extent>
  123. struct __is_span_impl<span<_Tp, _Extent>> : public true_type {};
  124. template <class _Tp>
  125. struct __is_span : public __is_span_impl<remove_cv_t<_Tp>> {};
  126. template <class _Tp>
  127. struct __is_std_array_impl : public false_type {};
  128. template <class _Tp, size_t _Sz>
  129. struct __is_std_array_impl<array<_Tp, _Sz>> : public true_type {};
  130. template <class _Tp>
  131. struct __is_std_array : public __is_std_array_impl<remove_cv_t<_Tp>> {};
  132. template <class _Tp, class _ElementType, class = void>
  133. struct __is_span_compatible_container : public false_type {};
  134. template <class _Tp, class _ElementType>
  135. struct __is_span_compatible_container<_Tp, _ElementType,
  136. void_t<
  137. // is not a specialization of span
  138. typename enable_if<!__is_span<_Tp>::value, nullptr_t>::type,
  139. // is not a specialization of array
  140. typename enable_if<!__is_std_array<_Tp>::value, nullptr_t>::type,
  141. // is_array_v<Container> is false,
  142. typename enable_if<!is_array_v<_Tp>, nullptr_t>::type,
  143. // data(cont) and size(cont) are well formed
  144. decltype(data(declval<_Tp>())),
  145. decltype(size(declval<_Tp>())),
  146. // remove_pointer_t<decltype(data(cont))>(*)[] is convertible to ElementType(*)[]
  147. typename enable_if<
  148. is_convertible_v<remove_pointer_t<decltype(data(declval<_Tp &>()))>(*)[],
  149. _ElementType(*)[]>,
  150. nullptr_t>::type
  151. >>
  152. : public true_type {};
  153. template <typename _Tp, size_t _Extent>
  154. class _LIBCPP_TEMPLATE_VIS span {
  155. public:
  156. // constants and types
  157. using element_type = _Tp;
  158. using value_type = remove_cv_t<_Tp>;
  159. using index_type = size_t;
  160. using difference_type = ptrdiff_t;
  161. using pointer = _Tp *;
  162. using const_pointer = const _Tp *;
  163. using reference = _Tp &;
  164. using const_reference = const _Tp &;
  165. using iterator = __wrap_iter<pointer>;
  166. using const_iterator = __wrap_iter<const_pointer>;
  167. using reverse_iterator = _VSTD::reverse_iterator<iterator>;
  168. using const_reverse_iterator = _VSTD::reverse_iterator<const_iterator>;
  169. static constexpr index_type extent = _Extent;
  170. // [span.cons], span constructors, copy, assignment, and destructor
  171. _LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr}
  172. { static_assert(_Extent == 0, "Can't default construct a statically sized span with size > 0"); }
  173. constexpr span (const span&) noexcept = default;
  174. constexpr span& operator=(const span&) noexcept = default;
  175. _LIBCPP_INLINE_VISIBILITY constexpr span(pointer __ptr, index_type __count) : __data{__ptr}
  176. { (void)__count; _LIBCPP_ASSERT(_Extent == __count, "size mismatch in span's constructor (ptr, len)"); }
  177. _LIBCPP_INLINE_VISIBILITY constexpr span(pointer __f, pointer __l) : __data{__f}
  178. { (void)__l; _LIBCPP_ASSERT(_Extent == distance(__f, __l), "size mismatch in span's constructor (ptr, ptr)"); }
  179. _LIBCPP_INLINE_VISIBILITY constexpr span(element_type (&__arr)[_Extent]) noexcept : __data{__arr} {}
  180. _LIBCPP_INLINE_VISIBILITY constexpr span( array<value_type, _Extent>& __arr) noexcept : __data{__arr.data()} {}
  181. _LIBCPP_INLINE_VISIBILITY constexpr span(const array<value_type, _Extent>& __arr) noexcept : __data{__arr.data()} {}
  182. template <class _OtherElementType>
  183. _LIBCPP_INLINE_VISIBILITY
  184. constexpr span(const span<_OtherElementType, _Extent>& __other,
  185. enable_if_t<
  186. is_convertible_v<_OtherElementType(*)[], element_type (*)[]>,
  187. nullptr_t> = nullptr)
  188. : __data{__other.data()} {}
  189. template <class _OtherElementType>
  190. _LIBCPP_INLINE_VISIBILITY
  191. constexpr span(const span<_OtherElementType, dynamic_extent>& __other,
  192. enable_if_t<
  193. is_convertible_v<_OtherElementType(*)[], element_type (*)[]>,
  194. nullptr_t> = nullptr) noexcept
  195. : __data{__other.data()} { _LIBCPP_ASSERT(_Extent == __other.size(), "size mismatch in span's constructor (other span)"); }
  196. // ~span() noexcept = default;
  197. template <size_t _Count>
  198. _LIBCPP_INLINE_VISIBILITY
  199. constexpr span<element_type, _Count> first() const noexcept
  200. {
  201. static_assert(_Count <= _Extent, "Count out of range in span::first()");
  202. return {data(), _Count};
  203. }
  204. template <size_t _Count>
  205. _LIBCPP_INLINE_VISIBILITY
  206. constexpr span<element_type, _Count> last() const noexcept
  207. {
  208. static_assert(_Count <= _Extent, "Count out of range in span::last()");
  209. return {data() + size() - _Count, _Count};
  210. }
  211. _LIBCPP_INLINE_VISIBILITY
  212. constexpr span<element_type, dynamic_extent> first(index_type __count) const noexcept
  213. {
  214. _LIBCPP_ASSERT(__count <= size(), "Count out of range in span::first(count)");
  215. return {data(), __count};
  216. }
  217. _LIBCPP_INLINE_VISIBILITY
  218. constexpr span<element_type, dynamic_extent> last(index_type __count) const noexcept
  219. {
  220. _LIBCPP_ASSERT(__count <= size(), "Count out of range in span::last(count)");
  221. return {data() + size() - __count, __count};
  222. }
  223. template <size_t _Offset, size_t _Count = dynamic_extent>
  224. _LIBCPP_INLINE_VISIBILITY
  225. constexpr auto subspan() const noexcept
  226. -> span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset>
  227. {
  228. static_assert(_Offset <= _Extent, "Offset out of range in span::subspan()");
  229. return {data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count};
  230. }
  231. _LIBCPP_INLINE_VISIBILITY
  232. constexpr span<element_type, dynamic_extent>
  233. subspan(index_type __offset, index_type __count = dynamic_extent) const noexcept
  234. {
  235. _LIBCPP_ASSERT(__offset <= size(), "Offset out of range in span::subspan(offset, count)");
  236. _LIBCPP_ASSERT(__count <= size() || __count == dynamic_extent, "Count out of range in span::subspan(offset, count)");
  237. if (__count == dynamic_extent)
  238. return {data() + __offset, size() - __offset};
  239. _LIBCPP_ASSERT(__offset <= size() - __count, "count + offset out of range in span::subspan(offset, count)");
  240. return {data() + __offset, __count};
  241. }
  242. _LIBCPP_INLINE_VISIBILITY constexpr index_type size() const noexcept { return _Extent; }
  243. _LIBCPP_INLINE_VISIBILITY constexpr index_type size_bytes() const noexcept { return _Extent * sizeof(element_type); }
  244. _LIBCPP_INLINE_VISIBILITY constexpr bool empty() const noexcept { return _Extent == 0; }
  245. _LIBCPP_INLINE_VISIBILITY constexpr reference operator[](index_type __idx) const noexcept
  246. {
  247. _LIBCPP_ASSERT(__idx >= 0 && __idx < size(), "span<T,N>[] index out of bounds");
  248. return __data[__idx];
  249. }
  250. _LIBCPP_INLINE_VISIBILITY constexpr reference front() const noexcept
  251. {
  252. static_assert(_Extent > 0, "span<T,N>[].front() on empty span");
  253. return __data[0];
  254. }
  255. _LIBCPP_INLINE_VISIBILITY constexpr reference back() const noexcept
  256. {
  257. static_assert(_Extent > 0, "span<T,N>[].back() on empty span");
  258. return __data[size()-1];
  259. }
  260. _LIBCPP_INLINE_VISIBILITY constexpr pointer data() const noexcept { return __data; }
  261. // [span.iter], span iterator support
  262. _LIBCPP_INLINE_VISIBILITY constexpr iterator begin() const noexcept { return iterator(data()); }
  263. _LIBCPP_INLINE_VISIBILITY constexpr iterator end() const noexcept { return iterator(data() + size()); }
  264. _LIBCPP_INLINE_VISIBILITY constexpr const_iterator cbegin() const noexcept { return const_iterator(data()); }
  265. _LIBCPP_INLINE_VISIBILITY constexpr const_iterator cend() const noexcept { return const_iterator(data() + size()); }
  266. _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); }
  267. _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); }
  268. _LIBCPP_INLINE_VISIBILITY constexpr const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(cend()); }
  269. _LIBCPP_INLINE_VISIBILITY constexpr const_reverse_iterator crend() const noexcept { return const_reverse_iterator(cbegin()); }
  270. _LIBCPP_INLINE_VISIBILITY constexpr void swap(span &__other) noexcept
  271. {
  272. pointer __p = __data;
  273. __data = __other.__data;
  274. __other.__data = __p;
  275. }
  276. _LIBCPP_INLINE_VISIBILITY span<const byte, _Extent * sizeof(element_type)> __as_bytes() const noexcept
  277. { return {reinterpret_cast<const byte *>(data()), size_bytes()}; }
  278. _LIBCPP_INLINE_VISIBILITY span<byte, _Extent * sizeof(element_type)> __as_writable_bytes() const noexcept
  279. { return {reinterpret_cast<byte *>(data()), size_bytes()}; }
  280. private:
  281. pointer __data;
  282. };
  283. template <typename _Tp>
  284. class _LIBCPP_TEMPLATE_VIS span<_Tp, dynamic_extent> {
  285. private:
  286. public:
  287. // constants and types
  288. using element_type = _Tp;
  289. using value_type = remove_cv_t<_Tp>;
  290. using index_type = size_t;
  291. using difference_type = ptrdiff_t;
  292. using pointer = _Tp *;
  293. using const_pointer = const _Tp *;
  294. using reference = _Tp &;
  295. using const_reference = const _Tp &;
  296. using iterator = __wrap_iter<pointer>;
  297. using const_iterator = __wrap_iter<const_pointer>;
  298. using reverse_iterator = _VSTD::reverse_iterator<iterator>;
  299. using const_reverse_iterator = _VSTD::reverse_iterator<const_iterator>;
  300. static constexpr index_type extent = dynamic_extent;
  301. // [span.cons], span constructors, copy, assignment, and destructor
  302. _LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr}, __size{0} {}
  303. constexpr span (const span&) noexcept = default;
  304. constexpr span& operator=(const span&) noexcept = default;
  305. _LIBCPP_INLINE_VISIBILITY constexpr span(pointer __ptr, index_type __count) : __data{__ptr}, __size{__count} {}
  306. _LIBCPP_INLINE_VISIBILITY constexpr span(pointer __f, pointer __l) : __data{__f}, __size{static_cast<size_t>(distance(__f, __l))} {}
  307. template <size_t _Sz>
  308. _LIBCPP_INLINE_VISIBILITY
  309. constexpr span(element_type (&__arr)[_Sz]) noexcept : __data{__arr}, __size{_Sz} {}
  310. template <size_t _Sz>
  311. _LIBCPP_INLINE_VISIBILITY
  312. constexpr span(array<value_type, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {}
  313. template <size_t _Sz>
  314. _LIBCPP_INLINE_VISIBILITY
  315. constexpr span(const array<value_type, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {}
  316. template <class _Container>
  317. _LIBCPP_INLINE_VISIBILITY
  318. constexpr span( _Container& __c,
  319. enable_if_t<__is_span_compatible_container<_Container, _Tp>::value, nullptr_t> = nullptr)
  320. : __data{_VSTD::data(__c)}, __size{(index_type) _VSTD::size(__c)} {}
  321. template <class _Container>
  322. _LIBCPP_INLINE_VISIBILITY
  323. constexpr span(const _Container& __c,
  324. enable_if_t<__is_span_compatible_container<const _Container, _Tp>::value, nullptr_t> = nullptr)
  325. : __data{_VSTD::data(__c)}, __size{(index_type) _VSTD::size(__c)} {}
  326. template <class _OtherElementType, size_t _OtherExtent>
  327. _LIBCPP_INLINE_VISIBILITY
  328. constexpr span(const span<_OtherElementType, _OtherExtent>& __other,
  329. enable_if_t<
  330. is_convertible_v<_OtherElementType(*)[], element_type (*)[]>,
  331. nullptr_t> = nullptr) noexcept
  332. : __data{__other.data()}, __size{__other.size()} {}
  333. // ~span() noexcept = default;
  334. template <size_t _Count>
  335. _LIBCPP_INLINE_VISIBILITY
  336. constexpr span<element_type, _Count> first() const noexcept
  337. {
  338. _LIBCPP_ASSERT(_Count <= size(), "Count out of range in span::first()");
  339. return {data(), _Count};
  340. }
  341. template <size_t _Count>
  342. _LIBCPP_INLINE_VISIBILITY
  343. constexpr span<element_type, _Count> last() const noexcept
  344. {
  345. _LIBCPP_ASSERT(_Count <= size(), "Count out of range in span::last()");
  346. return {data() + size() - _Count, _Count};
  347. }
  348. _LIBCPP_INLINE_VISIBILITY
  349. constexpr span<element_type, dynamic_extent> first(index_type __count) const noexcept
  350. {
  351. _LIBCPP_ASSERT(__count <= size(), "Count out of range in span::first(count)");
  352. return {data(), __count};
  353. }
  354. _LIBCPP_INLINE_VISIBILITY
  355. constexpr span<element_type, dynamic_extent> last (index_type __count) const noexcept
  356. {
  357. _LIBCPP_ASSERT(__count <= size(), "Count out of range in span::last(count)");
  358. return {data() + size() - __count, __count};
  359. }
  360. template <size_t _Offset, size_t _Count = dynamic_extent>
  361. _LIBCPP_INLINE_VISIBILITY
  362. constexpr span<_Tp, dynamic_extent> subspan() const noexcept
  363. {
  364. _LIBCPP_ASSERT(_Offset <= size(), "Offset out of range in span::subspan()");
  365. _LIBCPP_ASSERT(_Count == dynamic_extent || _Offset + _Count <= size(), "Count out of range in span::subspan()");
  366. return {data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count};
  367. }
  368. constexpr span<element_type, dynamic_extent>
  369. _LIBCPP_INLINE_VISIBILITY
  370. subspan(index_type __offset, index_type __count = dynamic_extent) const noexcept
  371. {
  372. _LIBCPP_ASSERT(__offset <= size(), "Offset out of range in span::subspan(offset, count)");
  373. _LIBCPP_ASSERT(__count <= size() || __count == dynamic_extent, "count out of range in span::subspan(offset, count)");
  374. if (__count == dynamic_extent)
  375. return {data() + __offset, size() - __offset};
  376. _LIBCPP_ASSERT(__offset <= size() - __count, "Offset + count out of range in span::subspan(offset, count)");
  377. return {data() + __offset, __count};
  378. }
  379. _LIBCPP_INLINE_VISIBILITY constexpr index_type size() const noexcept { return __size; }
  380. _LIBCPP_INLINE_VISIBILITY constexpr index_type size_bytes() const noexcept { return __size * sizeof(element_type); }
  381. _LIBCPP_INLINE_VISIBILITY constexpr bool empty() const noexcept { return __size == 0; }
  382. _LIBCPP_INLINE_VISIBILITY constexpr reference operator[](index_type __idx) const noexcept
  383. {
  384. _LIBCPP_ASSERT(__idx >= 0 && __idx < size(), "span<T>[] index out of bounds");
  385. return __data[__idx];
  386. }
  387. _LIBCPP_INLINE_VISIBILITY constexpr reference front() const noexcept
  388. {
  389. _LIBCPP_ASSERT(!empty(), "span<T>[].front() on empty span");
  390. return __data[0];
  391. }
  392. _LIBCPP_INLINE_VISIBILITY constexpr reference back() const noexcept
  393. {
  394. _LIBCPP_ASSERT(!empty(), "span<T>[].back() on empty span");
  395. return __data[size()-1];
  396. }
  397. _LIBCPP_INLINE_VISIBILITY constexpr pointer data() const noexcept { return __data; }
  398. // [span.iter], span iterator support
  399. _LIBCPP_INLINE_VISIBILITY constexpr iterator begin() const noexcept { return iterator(data()); }
  400. _LIBCPP_INLINE_VISIBILITY constexpr iterator end() const noexcept { return iterator(data() + size()); }
  401. _LIBCPP_INLINE_VISIBILITY constexpr const_iterator cbegin() const noexcept { return const_iterator(data()); }
  402. _LIBCPP_INLINE_VISIBILITY constexpr const_iterator cend() const noexcept { return const_iterator(data() + size()); }
  403. _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); }
  404. _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); }
  405. _LIBCPP_INLINE_VISIBILITY constexpr const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(cend()); }
  406. _LIBCPP_INLINE_VISIBILITY constexpr const_reverse_iterator crend() const noexcept { return const_reverse_iterator(cbegin()); }
  407. _LIBCPP_INLINE_VISIBILITY constexpr void swap(span &__other) noexcept
  408. {
  409. pointer __p = __data;
  410. __data = __other.__data;
  411. __other.__data = __p;
  412. index_type __sz = __size;
  413. __size = __other.__size;
  414. __other.__size = __sz;
  415. }
  416. _LIBCPP_INLINE_VISIBILITY span<const byte, dynamic_extent> __as_bytes() const noexcept
  417. { return {reinterpret_cast<const byte *>(data()), size_bytes()}; }
  418. _LIBCPP_INLINE_VISIBILITY span<byte, dynamic_extent> __as_writable_bytes() const noexcept
  419. { return {reinterpret_cast<byte *>(data()), size_bytes()}; }
  420. private:
  421. pointer __data;
  422. index_type __size;
  423. };
  424. // tuple interface
  425. template <class _Tp, size_t _Size>
  426. struct _LIBCPP_TEMPLATE_VIS tuple_size<span<_Tp, _Size>>
  427. : public integral_constant<size_t, _Size> {};
  428. template <class _Tp>
  429. struct _LIBCPP_TEMPLATE_VIS tuple_size<span<_Tp, dynamic_extent>>; // declared but not defined
  430. template <size_t _Ip, class _Tp, size_t _Size>
  431. struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, span<_Tp, _Size>>
  432. {
  433. static_assert( dynamic_extent != _Size, "std::tuple_element<> not supported for std::span<T, dynamic_extent>");
  434. static_assert(_Ip < _Size, "Index out of bounds in std::tuple_element<> (std::span)");
  435. typedef _Tp type;
  436. };
  437. template <size_t _Ip, class _Tp, size_t _Size>
  438. _LIBCPP_INLINE_VISIBILITY constexpr
  439. _Tp&
  440. get(span<_Tp, _Size> __s) noexcept
  441. {
  442. static_assert( dynamic_extent != _Size, "std::get<> not supported for std::span<T, dynamic_extent>");
  443. static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::span)");
  444. return __s[_Ip];
  445. }
  446. // as_bytes & as_writable_bytes
  447. template <class _Tp, size_t _Extent>
  448. _LIBCPP_INLINE_VISIBILITY
  449. auto as_bytes(span<_Tp, _Extent> __s) noexcept
  450. -> decltype(__s.__as_bytes())
  451. { return __s.__as_bytes(); }
  452. template <class _Tp, size_t _Extent>
  453. _LIBCPP_INLINE_VISIBILITY
  454. auto as_writable_bytes(span<_Tp, _Extent> __s) noexcept
  455. -> enable_if_t<!is_const_v<_Tp>, decltype(__s.__as_writable_bytes())>
  456. { return __s.__as_writable_bytes(); }
  457. template <class _Tp, size_t _Extent>
  458. _LIBCPP_INLINE_VISIBILITY
  459. constexpr void swap(span<_Tp, _Extent> &__lhs, span<_Tp, _Extent> &__rhs) noexcept
  460. { __lhs.swap(__rhs); }
  461. // Deduction guides
  462. template<class _Tp, size_t _Sz>
  463. span(_Tp (&)[_Sz]) -> span<_Tp, _Sz>;
  464. template<class _Tp, size_t _Sz>
  465. span(array<_Tp, _Sz>&) -> span<_Tp, _Sz>;
  466. template<class _Tp, size_t _Sz>
  467. span(const array<_Tp, _Sz>&) -> span<const _Tp, _Sz>;
  468. template<class _Container>
  469. span(_Container&) -> span<typename _Container::value_type>;
  470. template<class _Container>
  471. span(const _Container&) -> span<const typename _Container::value_type>;
  472. #endif // _LIBCPP_STD_VER > 17
  473. _LIBCPP_END_NAMESPACE_STD
  474. #endif // _LIBCPP_SPAN