663 lines · plain
1// -*- C++ -*-2//===----------------------------------------------------------------------===//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-exception7//8//===---------------------------------------------------------------------===//9 10#ifndef _LIBCPP_SPAN11#define _LIBCPP_SPAN12 13/*14 span synopsis15 16namespace std {17 18// constants19inline constexpr size_t dynamic_extent = numeric_limits<size_t>::max();20 21template<class T>22 concept integral-constant-like = // exposition only, since C++2623 is_integral_v<decltype(T::value)> &&24 !is_same_v<bool, remove_const_t<decltype(T::value)>> &&25 convertible_to<T, decltype(T::value)> &&26 equality_comparable_with<T, decltype(T::value)> &&27 bool_constant<T() == T::value>::value &&28 bool_constant<static_cast<decltype(T::value)>(T()) == T::value>::value;29 30template<class T>31 constexpr size_t maybe-static-ext = dynamic_extent; // exposition only, since C++2632template<integral-constant-like T>33 constexpr size_t maybe-static-ext<T> = {T::value};34 35// [views.span], class template span36template <class ElementType, size_t Extent = dynamic_extent>37 class span;38 39template<class ElementType, size_t Extent>40 inline constexpr bool ranges::enable_view<span<ElementType, Extent>> = true;41 42template<class ElementType, size_t Extent>43 inline constexpr bool ranges::enable_borrowed_range<span<ElementType, Extent>> = true;44 45// [span.objectrep], views of object representation46template <class ElementType, size_t Extent>47 span<const byte, ((Extent == dynamic_extent) ? dynamic_extent :48 (sizeof(ElementType) * Extent))> as_bytes(span<ElementType, Extent> s) noexcept;49 50template <class ElementType, size_t Extent>51 span< byte, ((Extent == dynamic_extent) ? dynamic_extent :52 (sizeof(ElementType) * Extent))> as_writable_bytes(span<ElementType, Extent> s) noexcept;53 54 55template <class ElementType, size_t Extent = dynamic_extent>56class span {57public:58 // constants and types59 using element_type = ElementType;60 using value_type = remove_cv_t<ElementType>;61 using size_type = size_t;62 using difference_type = ptrdiff_t;63 using pointer = element_type*;64 using const_pointer = const element_type*;65 using reference = element_type&;66 using const_reference = const element_type&;67 using iterator = implementation-defined;68 using reverse_iterator = std::reverse_iterator<iterator>;69 static constexpr size_type extent = Extent;70 71 // [span.cons], span constructors, copy, assignment, and destructor72 constexpr span() noexcept;73 template <class It>74 constexpr explicit(Extent != dynamic_extent) span(It first, size_type count);75 template <class It, class End>76 constexpr explicit(Extent != dynamic_extent) span(It first, End last);77 template <size_t N>78 constexpr span(type_identity_t<element_type> (&arr)[N]) noexcept;79 template <size_t N>80 constexpr span(array<value_type, N>& arr) noexcept;81 template <size_t N>82 constexpr span(const array<value_type, N>& arr) noexcept;83 template<class R>84 constexpr explicit(Extent != dynamic_extent) span(R&& r);85 constexpr explicit(extent != dynamic_extent) span(std::initializer_list<value_type> il); // Since C++2686 constexpr span(const span& other) noexcept = default;87 template <class OtherElementType, size_t OtherExtent>88 constexpr explicit(Extent != dynamic_extent) span(const span<OtherElementType, OtherExtent>& s) noexcept;89 constexpr span& operator=(const span& other) noexcept = default;90 91 // [span.sub], span subviews92 template <size_t Count>93 constexpr span<element_type, Count> first() const;94 template <size_t Count>95 constexpr span<element_type, Count> last() const;96 template <size_t Offset, size_t Count = dynamic_extent>97 constexpr span<element_type, see below> subspan() const;98 99 constexpr span<element_type, dynamic_extent> first(size_type count) const;100 constexpr span<element_type, dynamic_extent> last(size_type count) const;101 constexpr span<element_type, dynamic_extent> subspan(size_type offset, size_type count = dynamic_extent) const;102 103 // [span.obs], span observers104 constexpr size_type size() const noexcept;105 constexpr size_type size_bytes() const noexcept;106 [[nodiscard]] constexpr bool empty() const noexcept;107 108 // [span.elem], span element access109 constexpr reference operator[](size_type idx) const;110 constexpr reference at(size_type idx) const; // since C++26111 constexpr reference front() const;112 constexpr reference back() const;113 constexpr pointer data() const noexcept;114 115 // [span.iterators], span iterator support116 constexpr iterator begin() const noexcept;117 constexpr iterator end() const noexcept;118 constexpr reverse_iterator rbegin() const noexcept;119 constexpr reverse_iterator rend() const noexcept;120 121private:122 pointer data_; // exposition only123 size_type size_; // exposition only124};125 126template<class It, class EndOrSize>127 span(It, EndOrSize) -> span<remove_reference_t<iter_reference_t<_It>>>; // until C++26128template<class It, class EndOrSize>129 span(It, EndOrSize) -> span<remove_reference_t<iter_reference_t<It>>, maybe-static-ext<EndOrSize>>; // since C++26130 131template<class T, size_t N>132 span(T (&)[N]) -> span<T, N>;133 134template<class T, size_t N>135 span(array<T, N>&) -> span<T, N>;136 137template<class T, size_t N>138 span(const array<T, N>&) -> span<const T, N>;139 140template<class R>141 span(R&&) -> span<remove_reference_t<ranges::range_reference_t<R>>>;142 143} // namespace std144 145*/146 147#if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)148# include <__cxx03/__config>149#else150# include <__assert>151# include <__concepts/convertible_to.h>152# include <__concepts/equality_comparable.h>153# include <__config>154# include <__cstddef/byte.h>155# include <__cstddef/ptrdiff_t.h>156# include <__fwd/array.h>157# include <__fwd/span.h>158# include <__iterator/bounded_iter.h>159# include <__iterator/concepts.h>160# include <__iterator/iterator_traits.h>161# include <__iterator/reverse_iterator.h>162# include <__iterator/wrap_iter.h>163# include <__memory/pointer_traits.h>164# include <__ranges/concepts.h>165# include <__ranges/data.h>166# include <__ranges/enable_borrowed_range.h>167# include <__ranges/enable_view.h>168# include <__ranges/size.h>169# include <__type_traits/integral_constant.h>170# include <__type_traits/is_array.h>171# include <__type_traits/is_const.h>172# include <__type_traits/is_convertible.h>173# include <__type_traits/is_integral.h>174# include <__type_traits/is_same.h>175# include <__type_traits/remove_const.h>176# include <__type_traits/remove_cv.h>177# include <__type_traits/remove_cvref.h>178# include <__type_traits/remove_reference.h>179# include <__type_traits/type_identity.h>180# include <__utility/forward.h>181# include <initializer_list>182# include <stdexcept>183# include <version>184 185// standard-mandated includes186 187// [iterator.range]188# include <__iterator/access.h>189# include <__iterator/data.h>190# include <__iterator/empty.h>191# include <__iterator/reverse_access.h>192# include <__iterator/size.h>193 194# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)195# pragma GCC system_header196# endif197 198_LIBCPP_PUSH_MACROS199# include <__undef_macros>200 201_LIBCPP_BEGIN_NAMESPACE_STD202 203# if _LIBCPP_STD_VER >= 20204 205template <class _Tp>206struct __is_std_span : false_type {};207 208template <class _Tp, size_t _Sz>209struct __is_std_span<span<_Tp, _Sz>> : true_type {};210 211template <class _Range, class _ElementType>212concept __span_compatible_range =213 !__is_std_span<remove_cvref_t<_Range>>::value && //214 ranges::contiguous_range<_Range> && //215 ranges::sized_range<_Range> && //216 (ranges::borrowed_range<_Range> || is_const_v<_ElementType>) && //217 !__is_std_array_v<remove_cvref_t<_Range>> && //218 !is_array_v<remove_cvref_t<_Range>> && //219 is_convertible_v<remove_reference_t<ranges::range_reference_t<_Range>> (*)[], _ElementType (*)[]>;220 221template <class _From, class _To>222concept __span_array_convertible = is_convertible_v<_From (*)[], _To (*)[]>;223 224template <class _It, class _Tp>225concept __span_compatible_iterator =226 contiguous_iterator<_It> && __span_array_convertible<remove_reference_t<iter_reference_t<_It>>, _Tp>;227 228template <class _Sentinel, class _It>229concept __span_compatible_sentinel_for = sized_sentinel_for<_Sentinel, _It> && !is_convertible_v<_Sentinel, size_t>;230 231template <typename _Tp, size_t _Extent>232class span {233public:234 // constants and types235 using element_type = _Tp;236 using value_type = remove_cv_t<_Tp>;237 using size_type = size_t;238 using difference_type = ptrdiff_t;239 using pointer = _Tp*;240 using const_pointer = const _Tp*;241 using reference = _Tp&;242 using const_reference = const _Tp&;243# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS244 using iterator = __bounded_iter<pointer>;245# else246 using iterator = __wrap_iter<pointer>;247# endif248 using reverse_iterator = std::reverse_iterator<iterator>;249 250 static constexpr size_type extent = _Extent;251 252 // [span.cons], span constructors, copy, assignment, and destructor253 template <size_t _Sz = _Extent>254 requires(_Sz == 0)255 _LIBCPP_HIDE_FROM_ABI constexpr span() noexcept : __data_{nullptr} {}256 257# if _LIBCPP_STD_VER >= 26258 _LIBCPP_HIDE_FROM_ABI constexpr explicit span(std::initializer_list<value_type> __il)259 requires is_const_v<element_type>260 : __data_{__il.begin()} {261 _LIBCPP_ASSERT_VALID_INPUT_RANGE(262 _Extent == __il.size(), "Size mismatch in span's constructor _Extent != __il.size().");263 }264# endif265 266 constexpr span(const span&) noexcept = default;267 constexpr span& operator=(const span&) noexcept = default;268 269 template <__span_compatible_iterator<element_type> _It>270 _LIBCPP_HIDE_FROM_ABI constexpr explicit span(_It __first, size_type __count) : __data_{std::to_address(__first)} {271 (void)__count;272 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Extent == __count, "size mismatch in span's constructor (iterator, len)");273 _LIBCPP_ASSERT_VALID_INPUT_RANGE(__count == 0 || std::to_address(__first) != nullptr,274 "passed nullptr with non-zero length in span's constructor (iterator, len)");275 }276 277 template <__span_compatible_iterator<element_type> _It, __span_compatible_sentinel_for<_It> _End>278 _LIBCPP_HIDE_FROM_ABI constexpr explicit span(_It __first, _End __last) : __data_{std::to_address(__first)} {279 // [span.cons]/10280 // Throws: When and what last - first throws.281 [[maybe_unused]] auto __dist = __last - __first;282 _LIBCPP_ASSERT_VALID_INPUT_RANGE(__dist >= 0, "invalid range in span's constructor (iterator, sentinel)");283 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(284 __dist == _Extent, "invalid range in span's constructor (iterator, sentinel): last - first != extent");285 }286 287 _LIBCPP_HIDE_FROM_ABI constexpr span(type_identity_t<element_type> (&__arr)[_Extent]) noexcept : __data_{__arr} {}288 289 template <__span_array_convertible<element_type> _OtherElementType>290 _LIBCPP_HIDE_FROM_ABI constexpr span(array<_OtherElementType, _Extent>& __arr) noexcept : __data_{__arr.data()} {}291 292 template <class _OtherElementType>293 requires __span_array_convertible<const _OtherElementType, element_type>294 _LIBCPP_HIDE_FROM_ABI constexpr span(const array<_OtherElementType, _Extent>& __arr) noexcept295 : __data_{__arr.data()} {}296 297 template <__span_compatible_range<element_type> _Range>298 _LIBCPP_HIDE_FROM_ABI constexpr explicit span(_Range&& __r) : __data_{ranges::data(__r)} {299 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(ranges::size(__r) == _Extent, "size mismatch in span's constructor (range)");300 }301 302 template <__span_array_convertible<element_type> _OtherElementType>303 _LIBCPP_HIDE_FROM_ABI constexpr span(const span<_OtherElementType, _Extent>& __other) noexcept304 : __data_{__other.data()} {}305 306 template <__span_array_convertible<element_type> _OtherElementType>307 _LIBCPP_HIDE_FROM_ABI constexpr explicit span(const span<_OtherElementType, dynamic_extent>& __other) noexcept308 : __data_{__other.data()} {309 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Extent == __other.size(), "size mismatch in span's constructor (other span)");310 }311 312 template <size_t _Count>313 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> first() const noexcept {314 static_assert(_Count <= _Extent, "span<T, N>::first<Count>(): Count out of range");315 return span<element_type, _Count>{data(), _Count};316 }317 318 template <size_t _Count>319 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> last() const noexcept {320 static_assert(_Count <= _Extent, "span<T, N>::last<Count>(): Count out of range");321 return span<element_type, _Count>{data() + size() - _Count, _Count};322 }323 324 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent>325 first(size_type __count) const noexcept {326 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T, N>::first(count): count out of range");327 return {data(), __count};328 }329 330 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent>331 last(size_type __count) const noexcept {332 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T, N>::last(count): count out of range");333 return {data() + size() - __count, __count};334 }335 336 template <size_t _Offset, size_t _Count = dynamic_extent>337 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto subspan() const noexcept338 -> span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset> {339 static_assert(_Offset <= _Extent, "span<T, N>::subspan<Offset, Count>(): Offset out of range");340 static_assert(_Count == dynamic_extent || _Count <= _Extent - _Offset,341 "span<T, N>::subspan<Offset, Count>(): Offset + Count out of range");342 343 using _ReturnType = span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset>;344 return _ReturnType{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count};345 }346 347 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent>348 subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept {349 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__offset <= size(), "span<T, N>::subspan(offset, count): offset out of range");350 if (__count == dynamic_extent)351 return {data() + __offset, size() - __offset};352 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(353 __count <= size() - __offset, "span<T, N>::subspan(offset, count): offset + count out of range");354 return {data() + __offset, __count};355 }356 357 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_type size() const noexcept { return _Extent; }358 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_type size_bytes() const noexcept {359 return _Extent * sizeof(element_type);360 }361 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const noexcept { return _Extent == 0; }362 363 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](size_type __idx) const noexcept {364 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__idx < size(), "span<T, N>::operator[](index): index out of range");365 return __data_[__idx];366 }367 368# if _LIBCPP_STD_VER >= 26369 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference at(size_type __index) const {370 if (__index >= size())371 std::__throw_out_of_range("span");372 return __data_[__index];373 }374# endif375 376 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference front() const noexcept {377 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T, N>::front() on empty span");378 return __data_[0];379 }380 381 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference back() const noexcept {382 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T, N>::back() on empty span");383 return __data_[size() - 1];384 }385 386 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr pointer data() const noexcept { return __data_; }387 388 // [span.iter], span iterator support389 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() const noexcept {390# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS391 return std::__make_bounded_iter(data(), data(), data() + size());392# else393 return iterator(data());394# endif395 }396 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator end() const noexcept {397# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS398 return std::__make_bounded_iter(data() + size(), data(), data() + size());399# else400 return iterator(data() + size());401# endif402 }403 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rbegin() const noexcept {404 return reverse_iterator(end());405 }406 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rend() const noexcept {407 return reverse_iterator(begin());408 }409 410 _LIBCPP_HIDE_FROM_ABI span<const byte, _Extent * sizeof(element_type)> __as_bytes() const noexcept {411 return span<const byte, _Extent * sizeof(element_type)>{reinterpret_cast<const byte*>(data()), size_bytes()};412 }413 414 _LIBCPP_HIDE_FROM_ABI span<byte, _Extent * sizeof(element_type)> __as_writable_bytes() const noexcept {415 return span<byte, _Extent * sizeof(element_type)>{reinterpret_cast<byte*>(data()), size_bytes()};416 }417 418private:419 pointer __data_;420};421 422template <typename _Tp>423class span<_Tp, dynamic_extent> {424public:425 // constants and types426 using element_type = _Tp;427 using value_type = remove_cv_t<_Tp>;428 using size_type = size_t;429 using difference_type = ptrdiff_t;430 using pointer = _Tp*;431 using const_pointer = const _Tp*;432 using reference = _Tp&;433 using const_reference = const _Tp&;434# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS435 using iterator = __bounded_iter<pointer>;436# else437 using iterator = __wrap_iter<pointer>;438# endif439 using reverse_iterator = std::reverse_iterator<iterator>;440 441 static constexpr size_type extent = dynamic_extent;442 443 // [span.cons], span constructors, copy, assignment, and destructor444 _LIBCPP_HIDE_FROM_ABI constexpr span() noexcept : __data_{nullptr}, __size_{0} {}445 446# if _LIBCPP_STD_VER >= 26447 _LIBCPP_HIDE_FROM_ABI constexpr span(std::initializer_list<value_type> __il)448 requires is_const_v<element_type>449 : __data_{__il.begin()}, __size_{__il.size()} {}450# endif451 452 constexpr span(const span&) noexcept = default;453 constexpr span& operator=(const span&) noexcept = default;454 455 template <__span_compatible_iterator<element_type> _It>456 _LIBCPP_HIDE_FROM_ABI constexpr span(_It __first, size_type __count)457 : __data_{std::to_address(__first)}, __size_{__count} {458 _LIBCPP_ASSERT_VALID_INPUT_RANGE(__count == 0 || std::to_address(__first) != nullptr,459 "passed nullptr with non-zero length in span's constructor (iterator, len)");460 }461 462 template <__span_compatible_iterator<element_type> _It, __span_compatible_sentinel_for<_It> _End>463 _LIBCPP_HIDE_FROM_ABI constexpr span(_It __first, _End __last)464 : __data_(std::to_address(__first)), __size_(__last - __first) {465 _LIBCPP_ASSERT_VALID_INPUT_RANGE(__last - __first >= 0, "invalid range in span's constructor (iterator, sentinel)");466 }467 468 template <size_t _Sz>469 _LIBCPP_HIDE_FROM_ABI constexpr span(type_identity_t<element_type> (&__arr)[_Sz]) noexcept470 : __data_{__arr}, __size_{_Sz} {}471 472 template <__span_array_convertible<element_type> _OtherElementType, size_t _Sz>473 _LIBCPP_HIDE_FROM_ABI constexpr span(array<_OtherElementType, _Sz>& __arr) noexcept474 : __data_{__arr.data()}, __size_{_Sz} {}475 476 template <class _OtherElementType, size_t _Sz>477 requires __span_array_convertible<const _OtherElementType, element_type>478 _LIBCPP_HIDE_FROM_ABI constexpr span(const array<_OtherElementType, _Sz>& __arr) noexcept479 : __data_{__arr.data()}, __size_{_Sz} {}480 481 template <__span_compatible_range<element_type> _Range>482 _LIBCPP_HIDE_FROM_ABI constexpr span(_Range&& __r) : __data_(ranges::data(__r)), __size_{ranges::size(__r)} {}483 484 template <__span_array_convertible<element_type> _OtherElementType, size_t _OtherExtent>485 _LIBCPP_HIDE_FROM_ABI constexpr span(const span<_OtherElementType, _OtherExtent>& __other) noexcept486 : __data_{__other.data()}, __size_{__other.size()} {}487 488 template <size_t _Count>489 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> first() const noexcept {490 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count <= size(), "span<T>::first<Count>(): Count out of range");491 return span<element_type, _Count>{data(), _Count};492 }493 494 template <size_t _Count>495 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> last() const noexcept {496 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count <= size(), "span<T>::last<Count>(): Count out of range");497 return span<element_type, _Count>{data() + size() - _Count, _Count};498 }499 500 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent>501 first(size_type __count) const noexcept {502 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T>::first(count): count out of range");503 return {data(), __count};504 }505 506 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent>507 last(size_type __count) const noexcept {508 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T>::last(count): count out of range");509 return {data() + size() - __count, __count};510 }511 512 template <size_t _Offset, size_t _Count = dynamic_extent>513 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> subspan() const noexcept {514 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Offset <= size(), "span<T>::subspan<Offset, Count>(): Offset out of range");515 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count == dynamic_extent || _Count <= size() - _Offset,516 "span<T>::subspan<Offset, Count>(): Offset + Count out of range");517 return span<element_type, _Count>{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count};518 }519 520 [[nodiscard]] constexpr span<element_type, dynamic_extent> _LIBCPP_HIDE_FROM_ABI521 subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept {522 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__offset <= size(), "span<T>::subspan(offset, count): offset out of range");523 if (__count == dynamic_extent)524 return {data() + __offset, size() - __offset};525 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(526 __count <= size() - __offset, "span<T>::subspan(offset, count): offset + count out of range");527 return {data() + __offset, __count};528 }529 530 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_type size() const noexcept { return __size_; }531 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr size_type size_bytes() const noexcept {532 return __size_ * sizeof(element_type);533 }534 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const noexcept { return __size_ == 0; }535 536 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](size_type __idx) const noexcept {537 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__idx < size(), "span<T>::operator[](index): index out of range");538 return __data_[__idx];539 }540 541# if _LIBCPP_STD_VER >= 26542 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference at(size_type __index) const {543 if (__index >= size())544 std::__throw_out_of_range("span");545 return __data_[__index];546 }547# endif548 549 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference front() const noexcept {550 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T>::front() on empty span");551 return __data_[0];552 }553 554 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reference back() const noexcept {555 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T>::back() on empty span");556 return __data_[size() - 1];557 }558 559 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr pointer data() const noexcept { return __data_; }560 561 // [span.iter], span iterator support562 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() const noexcept {563# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS564 return std::__make_bounded_iter(data(), data(), data() + size());565# else566 return iterator(data());567# endif568 }569 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr iterator end() const noexcept {570# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS571 return std::__make_bounded_iter(data() + size(), data(), data() + size());572# else573 return iterator(data() + size());574# endif575 }576 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rbegin() const noexcept {577 return reverse_iterator(end());578 }579 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rend() const noexcept {580 return reverse_iterator(begin());581 }582 583 _LIBCPP_HIDE_FROM_ABI span<const byte, dynamic_extent> __as_bytes() const noexcept {584 return {reinterpret_cast<const byte*>(data()), size_bytes()};585 }586 587 _LIBCPP_HIDE_FROM_ABI span<byte, dynamic_extent> __as_writable_bytes() const noexcept {588 return {reinterpret_cast<byte*>(data()), size_bytes()};589 }590 591private:592 pointer __data_;593 size_type __size_;594};595 596template <class _Tp, size_t _Extent>597inline constexpr bool ranges::enable_borrowed_range<span<_Tp, _Extent> > = true;598 599template <class _ElementType, size_t _Extent>600inline constexpr bool ranges::enable_view<span<_ElementType, _Extent>> = true;601 602// as_bytes & as_writable_bytes603template <class _Tp, size_t _Extent>604[[nodiscard]] _LIBCPP_HIDE_FROM_ABI auto as_bytes(span<_Tp, _Extent> __s) noexcept {605 return __s.__as_bytes();606}607 608template <class _Tp, size_t _Extent>609 requires(!is_const_v<_Tp>)610[[nodiscard]] _LIBCPP_HIDE_FROM_ABI auto as_writable_bytes(span<_Tp, _Extent> __s) noexcept {611 return __s.__as_writable_bytes();612}613 614# if _LIBCPP_STD_VER >= 26615template <class _Tp>616concept __integral_constant_like =617 is_integral_v<decltype(_Tp::value)> && !is_same_v<bool, remove_const_t<decltype(_Tp::value)>> &&618 convertible_to<_Tp, decltype(_Tp::value)> && equality_comparable_with<_Tp, decltype(_Tp::value)> &&619 bool_constant<_Tp() == _Tp::value>::value &&620 bool_constant<static_cast<decltype(_Tp::value)>(_Tp()) == _Tp::value>::value;621 622template <class _Tp>623inline constexpr size_t __maybe_static_ext = dynamic_extent;624 625template <__integral_constant_like _Tp>626inline constexpr size_t __maybe_static_ext<_Tp> = {_Tp::value};627 628template <contiguous_iterator _It, class _EndOrSize>629span(_It, _EndOrSize) -> span<remove_reference_t<iter_reference_t<_It>>, __maybe_static_ext<_EndOrSize>>;630# else631template <contiguous_iterator _It, class _EndOrSize>632span(_It, _EndOrSize) -> span<remove_reference_t<iter_reference_t<_It>>>;633# endif634 635template <class _Tp, size_t _Sz>636span(_Tp (&)[_Sz]) -> span<_Tp, _Sz>;637 638template <class _Tp, size_t _Sz>639span(array<_Tp, _Sz>&) -> span<_Tp, _Sz>;640 641template <class _Tp, size_t _Sz>642span(const array<_Tp, _Sz>&) -> span<const _Tp, _Sz>;643 644template <ranges::contiguous_range _Range>645span(_Range&&) -> span<remove_reference_t<ranges::range_reference_t<_Range>>>;646 647# endif // _LIBCPP_STD_VER >= 20648 649_LIBCPP_END_NAMESPACE_STD650 651_LIBCPP_POP_MACROS652 653# if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20654# include <array>655# include <concepts>656# include <functional>657# include <iterator>658# include <type_traits>659# endif660#endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS)661 662#endif // _LIBCPP_SPAN663