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