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-exception 7// 8//===---------------------------------------------------------------------===// 9 10#ifndef _LIBCPP_SPAN 11#define _LIBCPP_SPAN 12 13/* 14 span synopsis 15 16namespace std { 17 18// constants 19inline constexpr size_t dynamic_extent = numeric_limits<size_t>::max(); 20 21// [views.span], class template span 22template <class ElementType, size_t Extent = dynamic_extent> 23 class span; 24 25template<class ElementType, size_t Extent> 26 inline constexpr bool ranges::enable_view<span<ElementType, Extent>> = true; 27 28template<class ElementType, size_t Extent> 29 inline constexpr bool ranges::enable_borrowed_range<span<ElementType, Extent>> = true; 30 31// [span.objectrep], views of object representation 32template <class ElementType, size_t Extent> 33 span<const byte, ((Extent == dynamic_extent) ? dynamic_extent : 34 (sizeof(ElementType) * Extent))> as_bytes(span<ElementType, Extent> s) noexcept; 35 36template <class ElementType, size_t Extent> 37 span< byte, ((Extent == dynamic_extent) ? dynamic_extent : 38 (sizeof(ElementType) * Extent))> as_writable_bytes(span<ElementType, Extent> s) noexcept; 39 40 41template <class ElementType, size_t Extent = dynamic_extent> 42class span { 43public: 44 // constants and types 45 using element_type = ElementType; 46 using value_type = remove_cv_t<ElementType>; 47 using size_type = size_t; 48 using difference_type = ptrdiff_t; 49 using pointer = element_type*; 50 using const_pointer = const element_type*; 51 using reference = element_type&; 52 using const_reference = const element_type&; 53 using iterator = implementation-defined; 54 using reverse_iterator = std::reverse_iterator<iterator>; 55 static constexpr size_type extent = Extent; 56 57 // [span.cons], span constructors, copy, assignment, and destructor 58 constexpr span() noexcept; 59 template <class It> 60 constexpr explicit(Extent != dynamic_extent) span(It first, size_type count); 61 template <class It, class End> 62 constexpr explicit(Extent != dynamic_extent) span(It first, End last); 63 template <size_t N> 64 constexpr span(type_identity_t<element_type> (&arr)[N]) noexcept; 65 template <size_t N> 66 constexpr span(array<value_type, N>& arr) noexcept; 67 template <size_t N> 68 constexpr span(const array<value_type, N>& arr) noexcept; 69 template<class R> 70 constexpr explicit(Extent != dynamic_extent) span(R&& r); 71 constexpr explicit(extent != dynamic_extent) span(std::initializer_list<value_type> il); // Since C++26 72 constexpr span(const span& other) noexcept = default; 73 template <class OtherElementType, size_t OtherExtent> 74 constexpr explicit(Extent != dynamic_extent) span(const span<OtherElementType, OtherExtent>& s) noexcept; 75 constexpr span& operator=(const span& other) noexcept = default; 76 77 // [span.sub], span subviews 78 template <size_t Count> 79 constexpr span<element_type, Count> first() const; 80 template <size_t Count> 81 constexpr span<element_type, Count> last() const; 82 template <size_t Offset, size_t Count = dynamic_extent> 83 constexpr span<element_type, see below> subspan() const; 84 85 constexpr span<element_type, dynamic_extent> first(size_type count) const; 86 constexpr span<element_type, dynamic_extent> last(size_type count) const; 87 constexpr span<element_type, dynamic_extent> subspan(size_type offset, size_type count = dynamic_extent) const; 88 89 // [span.obs], span observers 90 constexpr size_type size() const noexcept; 91 constexpr size_type size_bytes() const noexcept; 92 [[nodiscard]] constexpr bool empty() const noexcept; 93 94 // [span.elem], span element access 95 constexpr reference operator[](size_type idx) const; 96 constexpr reference at(size_type idx) const; // since C++26 97 constexpr reference front() const; 98 constexpr reference back() const; 99 constexpr pointer data() const noexcept; 100 101 // [span.iterators], span iterator support 102 constexpr iterator begin() const noexcept; 103 constexpr iterator end() const noexcept; 104 constexpr reverse_iterator rbegin() const noexcept; 105 constexpr reverse_iterator rend() const noexcept; 106 107private: 108 pointer data_; // exposition only 109 size_type size_; // exposition only 110}; 111 112template<class It, class EndOrSize> 113 span(It, EndOrSize) -> span<remove_reference_t<iter_reference_t<_It>>>; 114 115template<class T, size_t N> 116 span(T (&)[N]) -> span<T, N>; 117 118template<class T, size_t N> 119 span(array<T, N>&) -> span<T, N>; 120 121template<class T, size_t N> 122 span(const array<T, N>&) -> span<const T, N>; 123 124template<class R> 125 span(R&&) -> span<remove_reference_t<ranges::range_reference_t<R>>>; 126 127} // namespace std 128 129*/ 130 131#include <__assert> 132#include <__config> 133#include <__fwd/array.h> 134#include <__fwd/span.h> 135#include <__iterator/bounded_iter.h> 136#include <__iterator/concepts.h> 137#include <__iterator/iterator_traits.h> 138#include <__iterator/reverse_iterator.h> 139#include <__iterator/wrap_iter.h> 140#include <__memory/pointer_traits.h> 141#include <__ranges/concepts.h> 142#include <__ranges/data.h> 143#include <__ranges/enable_borrowed_range.h> 144#include <__ranges/enable_view.h> 145#include <__ranges/size.h> 146#include <__type_traits/is_array.h> 147#include <__type_traits/is_const.h> 148#include <__type_traits/is_convertible.h> 149#include <__type_traits/remove_cv.h> 150#include <__type_traits/remove_cvref.h> 151#include <__type_traits/remove_reference.h> 152#include <__type_traits/type_identity.h> 153#include <__utility/forward.h> 154#include <cstddef> // for byte 155#include <initializer_list> 156#include <stdexcept> 157#include <version> 158 159// standard-mandated includes 160 161// [iterator.range] 162#include <__iterator/access.h> 163#include <__iterator/data.h> 164#include <__iterator/empty.h> 165#include <__iterator/reverse_access.h> 166#include <__iterator/size.h> 167 168#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 169# pragma GCC system_header 170#endif 171 172_LIBCPP_PUSH_MACROS 173#include <__undef_macros> 174 175_LIBCPP_BEGIN_NAMESPACE_STD 176 177#if _LIBCPP_STD_VER >= 20 178 179template <class _Tp> 180struct __is_std_span : false_type {}; 181 182template <class _Tp, size_t _Sz> 183struct __is_std_span<span<_Tp, _Sz>> : true_type {}; 184 185template <class _Range, class _ElementType> 186concept __span_compatible_range = 187 ranges::contiguous_range<_Range> && // 188 ranges::sized_range<_Range> && // 189 (ranges::borrowed_range<_Range> || is_const_v<_ElementType>)&& // 190 !__is_std_span<remove_cvref_t<_Range>>::value && // 191 !__is_std_array<remove_cvref_t<_Range>>::value && // 192 !is_array_v<remove_cvref_t<_Range>> && // 193 is_convertible_v<remove_reference_t<ranges::range_reference_t<_Range>> (*)[], _ElementType (*)[]>; 194 195template <class _From, class _To> 196concept __span_array_convertible = is_convertible_v<_From (*)[], _To (*)[]>; 197 198template <class _It, class _Tp> 199concept __span_compatible_iterator = 200 contiguous_iterator<_It> && __span_array_convertible<remove_reference_t<iter_reference_t<_It>>, _Tp>; 201 202template <class _Sentinel, class _It> 203concept __span_compatible_sentinel_for = sized_sentinel_for<_Sentinel, _It> && !is_convertible_v<_Sentinel, size_t>; 204 205template <typename _Tp, size_t _Extent> 206class _LIBCPP_TEMPLATE_VIS span { 207public: 208 // constants and types 209 using element_type = _Tp; 210 using value_type = remove_cv_t<_Tp>; 211 using size_type = size_t; 212 using difference_type = ptrdiff_t; 213 using pointer = _Tp*; 214 using const_pointer = const _Tp*; 215 using reference = _Tp&; 216 using const_reference = const _Tp&; 217# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS 218 using iterator = __bounded_iter<pointer>; 219# else 220 using iterator = __wrap_iter<pointer>; 221# endif 222 using reverse_iterator = std::reverse_iterator<iterator>; 223 224 static constexpr size_type extent = _Extent; 225 226 // [span.cons], span constructors, copy, assignment, and destructor 227 template <size_t _Sz = _Extent> 228 requires(_Sz == 0) 229 _LIBCPP_HIDE_FROM_ABI constexpr span() noexcept : __data_{nullptr} {} 230 231# if _LIBCPP_STD_VER >= 26 232 _LIBCPP_HIDE_FROM_ABI constexpr explicit span(std::initializer_list<value_type> __il) 233 requires is_const_v<element_type> 234 : __data_{__il.begin()} { 235 _LIBCPP_ASSERT_VALID_INPUT_RANGE( 236 _Extent == __il.size(), "Size mismatch in span's constructor _Extent != __il.size()."); 237 } 238# endif 239 240 constexpr span(const span&) noexcept = default; 241 constexpr span& operator=(const span&) noexcept = default; 242 243 template <__span_compatible_iterator<element_type> _It> 244 _LIBCPP_HIDE_FROM_ABI constexpr explicit span(_It __first, size_type __count) : __data_{std::to_address(__first)} { 245 (void)__count; 246 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Extent == __count, "size mismatch in span's constructor (iterator, len)"); 247 } 248 249 template <__span_compatible_iterator<element_type> _It, __span_compatible_sentinel_for<_It> _End> 250 _LIBCPP_HIDE_FROM_ABI constexpr explicit span(_It __first, _End __last) : __data_{std::to_address(__first)} { 251 // [span.cons]/10 252 // Throws: When and what last - first throws. 253 [[maybe_unused]] auto __dist = __last - __first; 254 _LIBCPP_ASSERT_VALID_INPUT_RANGE(__dist >= 0, "invalid range in span's constructor (iterator, sentinel)"); 255 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 256 __dist == _Extent, "invalid range in span's constructor (iterator, sentinel): last - first != extent"); 257 } 258 259 _LIBCPP_HIDE_FROM_ABI constexpr span(type_identity_t<element_type> (&__arr)[_Extent]) noexcept : __data_{__arr} {} 260 261 template <__span_array_convertible<element_type> _OtherElementType> 262 _LIBCPP_HIDE_FROM_ABI constexpr span(array<_OtherElementType, _Extent>& __arr) noexcept : __data_{__arr.data()} {} 263 264 template <class _OtherElementType> 265 requires __span_array_convertible<const _OtherElementType, element_type> 266 _LIBCPP_HIDE_FROM_ABI constexpr span(const array<_OtherElementType, _Extent>& __arr) noexcept 267 : __data_{__arr.data()} {} 268 269 template <__span_compatible_range<element_type> _Range> 270 _LIBCPP_HIDE_FROM_ABI constexpr explicit span(_Range&& __r) : __data_{ranges::data(__r)} { 271 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(ranges::size(__r) == _Extent, "size mismatch in span's constructor (range)"); 272 } 273 274 template <__span_array_convertible<element_type> _OtherElementType> 275 _LIBCPP_HIDE_FROM_ABI constexpr span(const span<_OtherElementType, _Extent>& __other) : __data_{__other.data()} {} 276 277 template <__span_array_convertible<element_type> _OtherElementType> 278 _LIBCPP_HIDE_FROM_ABI constexpr explicit span(const span<_OtherElementType, dynamic_extent>& __other) noexcept 279 : __data_{__other.data()} { 280 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Extent == __other.size(), "size mismatch in span's constructor (other span)"); 281 } 282 283 template <size_t _Count> 284 _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> first() const noexcept { 285 static_assert(_Count <= _Extent, "span<T, N>::first<Count>(): Count out of range"); 286 return span<element_type, _Count>{data(), _Count}; 287 } 288 289 template <size_t _Count> 290 _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> last() const noexcept { 291 static_assert(_Count <= _Extent, "span<T, N>::last<Count>(): Count out of range"); 292 return span<element_type, _Count>{data() + size() - _Count, _Count}; 293 } 294 295 _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept { 296 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T, N>::first(count): count out of range"); 297 return {data(), __count}; 298 } 299 300 _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> last(size_type __count) const noexcept { 301 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T, N>::last(count): count out of range"); 302 return {data() + size() - __count, __count}; 303 } 304 305 template <size_t _Offset, size_t _Count = dynamic_extent> 306 _LIBCPP_HIDE_FROM_ABI constexpr auto subspan() const noexcept 307 -> span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset> { 308 static_assert(_Offset <= _Extent, "span<T, N>::subspan<Offset, Count>(): Offset out of range"); 309 static_assert(_Count == dynamic_extent || _Count <= _Extent - _Offset, 310 "span<T, N>::subspan<Offset, Count>(): Offset + Count out of range"); 311 312 using _ReturnType = span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset>; 313 return _ReturnType{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; 314 } 315 316 _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> 317 subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept { 318 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__offset <= size(), "span<T, N>::subspan(offset, count): offset out of range"); 319 if (__count == dynamic_extent) 320 return {data() + __offset, size() - __offset}; 321 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 322 __count <= size() - __offset, "span<T, N>::subspan(offset, count): offset + count out of range"); 323 return {data() + __offset, __count}; 324 } 325 326 _LIBCPP_HIDE_FROM_ABI constexpr size_type size() const noexcept { return _Extent; } 327 _LIBCPP_HIDE_FROM_ABI constexpr size_type size_bytes() const noexcept { return _Extent * sizeof(element_type); } 328 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const noexcept { return _Extent == 0; } 329 330 _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](size_type __idx) const noexcept { 331 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__idx < size(), "span<T, N>::operator[](index): index out of range"); 332 return __data_[__idx]; 333 } 334 335# if _LIBCPP_STD_VER >= 26 336 _LIBCPP_HIDE_FROM_ABI constexpr reference at(size_type __index) const { 337 if (__index >= size()) 338 std::__throw_out_of_range("span"); 339 return __data_[__index]; 340 } 341# endif 342 343 _LIBCPP_HIDE_FROM_ABI constexpr reference front() const noexcept { 344 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T, N>::front() on empty span"); 345 return __data_[0]; 346 } 347 348 _LIBCPP_HIDE_FROM_ABI constexpr reference back() const noexcept { 349 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T, N>::back() on empty span"); 350 return __data_[size() - 1]; 351 } 352 353 _LIBCPP_HIDE_FROM_ABI constexpr pointer data() const noexcept { return __data_; } 354 355 // [span.iter], span iterator support 356 _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() const noexcept { 357# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS 358 return std::__make_bounded_iter(data(), data(), data() + size()); 359# else 360 return iterator(data()); 361# endif 362 } 363 _LIBCPP_HIDE_FROM_ABI constexpr iterator end() const noexcept { 364# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS 365 return std::__make_bounded_iter(data() + size(), data(), data() + size()); 366# else 367 return iterator(data() + size()); 368# endif 369 } 370 _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); } 371 _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); } 372 373 _LIBCPP_HIDE_FROM_ABI span<const byte, _Extent * sizeof(element_type)> __as_bytes() const noexcept { 374 return span<const byte, _Extent * sizeof(element_type)>{reinterpret_cast<const byte*>(data()), size_bytes()}; 375 } 376 377 _LIBCPP_HIDE_FROM_ABI span<byte, _Extent * sizeof(element_type)> __as_writable_bytes() const noexcept { 378 return span<byte, _Extent * sizeof(element_type)>{reinterpret_cast<byte*>(data()), size_bytes()}; 379 } 380 381private: 382 pointer __data_; 383}; 384 385template <typename _Tp> 386class _LIBCPP_TEMPLATE_VIS span<_Tp, dynamic_extent> { 387public: 388 // constants and types 389 using element_type = _Tp; 390 using value_type = remove_cv_t<_Tp>; 391 using size_type = size_t; 392 using difference_type = ptrdiff_t; 393 using pointer = _Tp*; 394 using const_pointer = const _Tp*; 395 using reference = _Tp&; 396 using const_reference = const _Tp&; 397# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS 398 using iterator = __bounded_iter<pointer>; 399# else 400 using iterator = __wrap_iter<pointer>; 401# endif 402 using reverse_iterator = std::reverse_iterator<iterator>; 403 404 static constexpr size_type extent = dynamic_extent; 405 406 // [span.cons], span constructors, copy, assignment, and destructor 407 _LIBCPP_HIDE_FROM_ABI constexpr span() noexcept : __data_{nullptr}, __size_{0} {} 408 409# if _LIBCPP_STD_VER >= 26 410 _LIBCPP_HIDE_FROM_ABI constexpr span(std::initializer_list<value_type> __il) 411 requires is_const_v<element_type> 412 : __data_{__il.begin()}, __size_{__il.size()} {} 413# endif 414 415 constexpr span(const span&) noexcept = default; 416 constexpr span& operator=(const span&) noexcept = default; 417 418 template <__span_compatible_iterator<element_type> _It> 419 _LIBCPP_HIDE_FROM_ABI constexpr span(_It __first, size_type __count) 420 : __data_{std::to_address(__first)}, __size_{__count} {} 421 422 template <__span_compatible_iterator<element_type> _It, __span_compatible_sentinel_for<_It> _End> 423 _LIBCPP_HIDE_FROM_ABI constexpr span(_It __first, _End __last) 424 : __data_(std::to_address(__first)), __size_(__last - __first) { 425 _LIBCPP_ASSERT_VALID_INPUT_RANGE(__last - __first >= 0, "invalid range in span's constructor (iterator, sentinel)"); 426 } 427 428 template <size_t _Sz> 429 _LIBCPP_HIDE_FROM_ABI constexpr span(type_identity_t<element_type> (&__arr)[_Sz]) noexcept 430 : __data_{__arr}, __size_{_Sz} {} 431 432 template <__span_array_convertible<element_type> _OtherElementType, size_t _Sz> 433 _LIBCPP_HIDE_FROM_ABI constexpr span(array<_OtherElementType, _Sz>& __arr) noexcept 434 : __data_{__arr.data()}, __size_{_Sz} {} 435 436 template <class _OtherElementType, size_t _Sz> 437 requires __span_array_convertible<const _OtherElementType, element_type> 438 _LIBCPP_HIDE_FROM_ABI constexpr span(const array<_OtherElementType, _Sz>& __arr) noexcept 439 : __data_{__arr.data()}, __size_{_Sz} {} 440 441 template <__span_compatible_range<element_type> _Range> 442 _LIBCPP_HIDE_FROM_ABI constexpr span(_Range&& __r) : __data_(ranges::data(__r)), __size_{ranges::size(__r)} {} 443 444 template <__span_array_convertible<element_type> _OtherElementType, size_t _OtherExtent> 445 _LIBCPP_HIDE_FROM_ABI constexpr span(const span<_OtherElementType, _OtherExtent>& __other) noexcept 446 : __data_{__other.data()}, __size_{__other.size()} {} 447 448 template <size_t _Count> 449 _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> first() const noexcept { 450 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count <= size(), "span<T>::first<Count>(): Count out of range"); 451 return span<element_type, _Count>{data(), _Count}; 452 } 453 454 template <size_t _Count> 455 _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> last() const noexcept { 456 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count <= size(), "span<T>::last<Count>(): Count out of range"); 457 return span<element_type, _Count>{data() + size() - _Count, _Count}; 458 } 459 460 _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept { 461 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T>::first(count): count out of range"); 462 return {data(), __count}; 463 } 464 465 _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> last(size_type __count) const noexcept { 466 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T>::last(count): count out of range"); 467 return {data() + size() - __count, __count}; 468 } 469 470 template <size_t _Offset, size_t _Count = dynamic_extent> 471 _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> subspan() const noexcept { 472 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Offset <= size(), "span<T>::subspan<Offset, Count>(): Offset out of range"); 473 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count == dynamic_extent || _Count <= size() - _Offset, 474 "span<T>::subspan<Offset, Count>(): Offset + Count out of range"); 475 return span<element_type, _Count>{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; 476 } 477 478 constexpr span<element_type, dynamic_extent> _LIBCPP_HIDE_FROM_ABI 479 subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept { 480 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__offset <= size(), "span<T>::subspan(offset, count): offset out of range"); 481 if (__count == dynamic_extent) 482 return {data() + __offset, size() - __offset}; 483 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 484 __count <= size() - __offset, "span<T>::subspan(offset, count): offset + count out of range"); 485 return {data() + __offset, __count}; 486 } 487 488 _LIBCPP_HIDE_FROM_ABI constexpr size_type size() const noexcept { return __size_; } 489 _LIBCPP_HIDE_FROM_ABI constexpr size_type size_bytes() const noexcept { return __size_ * sizeof(element_type); } 490 [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const noexcept { return __size_ == 0; } 491 492 _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](size_type __idx) const noexcept { 493 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__idx < size(), "span<T>::operator[](index): index out of range"); 494 return __data_[__idx]; 495 } 496 497# if _LIBCPP_STD_VER >= 26 498 _LIBCPP_HIDE_FROM_ABI constexpr reference at(size_type __index) const { 499 if (__index >= size()) 500 std::__throw_out_of_range("span"); 501 return __data_[__index]; 502 } 503# endif 504 505 _LIBCPP_HIDE_FROM_ABI constexpr reference front() const noexcept { 506 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T>::front() on empty span"); 507 return __data_[0]; 508 } 509 510 _LIBCPP_HIDE_FROM_ABI constexpr reference back() const noexcept { 511 _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T>::back() on empty span"); 512 return __data_[size() - 1]; 513 } 514 515 _LIBCPP_HIDE_FROM_ABI constexpr pointer data() const noexcept { return __data_; } 516 517 // [span.iter], span iterator support 518 _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() const noexcept { 519# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS 520 return std::__make_bounded_iter(data(), data(), data() + size()); 521# else 522 return iterator(data()); 523# endif 524 } 525 _LIBCPP_HIDE_FROM_ABI constexpr iterator end() const noexcept { 526# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS 527 return std::__make_bounded_iter(data() + size(), data(), data() + size()); 528# else 529 return iterator(data() + size()); 530# endif 531 } 532 _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); } 533 _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); } 534 535 _LIBCPP_HIDE_FROM_ABI span<const byte, dynamic_extent> __as_bytes() const noexcept { 536 return {reinterpret_cast<const byte*>(data()), size_bytes()}; 537 } 538 539 _LIBCPP_HIDE_FROM_ABI span<byte, dynamic_extent> __as_writable_bytes() const noexcept { 540 return {reinterpret_cast<byte*>(data()), size_bytes()}; 541 } 542 543private: 544 pointer __data_; 545 size_type __size_; 546}; 547 548template <class _Tp, size_t _Extent> 549inline constexpr bool ranges::enable_borrowed_range<span<_Tp, _Extent> > = true; 550 551template <class _ElementType, size_t _Extent> 552inline constexpr bool ranges::enable_view<span<_ElementType, _Extent>> = true; 553 554// as_bytes & as_writable_bytes 555template <class _Tp, size_t _Extent> 556_LIBCPP_HIDE_FROM_ABI auto as_bytes(span<_Tp, _Extent> __s) noexcept { 557 return __s.__as_bytes(); 558} 559 560template <class _Tp, size_t _Extent> 561 requires(!is_const_v<_Tp>) 562_LIBCPP_HIDE_FROM_ABI auto as_writable_bytes(span<_Tp, _Extent> __s) noexcept { 563 return __s.__as_writable_bytes(); 564} 565 566template <contiguous_iterator _It, class _EndOrSize> 567span(_It, _EndOrSize) -> span<remove_reference_t<iter_reference_t<_It>>>; 568 569template <class _Tp, size_t _Sz> 570span(_Tp (&)[_Sz]) -> span<_Tp, _Sz>; 571 572template <class _Tp, size_t _Sz> 573span(array<_Tp, _Sz>&) -> span<_Tp, _Sz>; 574 575template <class _Tp, size_t _Sz> 576span(const array<_Tp, _Sz>&) -> span<const _Tp, _Sz>; 577 578template <ranges::contiguous_range _Range> 579span(_Range&&) -> span<remove_reference_t<ranges::range_reference_t<_Range>>>; 580 581#endif // _LIBCPP_STD_VER >= 20 582 583_LIBCPP_END_NAMESPACE_STD 584 585_LIBCPP_POP_MACROS 586 587#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 588# include <array> 589# include <concepts> 590# include <functional> 591# include <iterator> 592# include <type_traits> 593#endif 594 595#endif // _LIBCPP_SPAN 596