146035553Spatrick// -*- C++ -*- 2*4bdff4beSrobert//===----------------------------------------------------------------------===// 346035553Spatrick// 446035553Spatrick// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 546035553Spatrick// See https://llvm.org/LICENSE.txt for license information. 646035553Spatrick// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 746035553Spatrick// 846035553Spatrick//===---------------------------------------------------------------------===// 946035553Spatrick 1046035553Spatrick#ifndef _LIBCPP_SPAN 1146035553Spatrick#define _LIBCPP_SPAN 1246035553Spatrick 1346035553Spatrick/* 1446035553Spatrick span synopsis 1546035553Spatrick 1646035553Spatricknamespace std { 1746035553Spatrick 1846035553Spatrick// constants 1946035553Spatrickinline constexpr size_t dynamic_extent = numeric_limits<size_t>::max(); 2046035553Spatrick 2146035553Spatrick// [views.span], class template span 2246035553Spatricktemplate <class ElementType, size_t Extent = dynamic_extent> 2346035553Spatrick class span; 2446035553Spatrick 2576d0caaeSpatricktemplate<class ElementType, size_t Extent> 2676d0caaeSpatrick inline constexpr bool ranges::enable_view<span<ElementType, Extent>> = true; 2776d0caaeSpatrick 2876d0caaeSpatricktemplate<class ElementType, size_t Extent> 2976d0caaeSpatrick inline constexpr bool ranges::enable_borrowed_range<span<ElementType, Extent>> = true; 3076d0caaeSpatrick 3146035553Spatrick// [span.objectrep], views of object representation 3246035553Spatricktemplate <class ElementType, size_t Extent> 3346035553Spatrick span<const byte, ((Extent == dynamic_extent) ? dynamic_extent : 3446035553Spatrick (sizeof(ElementType) * Extent))> as_bytes(span<ElementType, Extent> s) noexcept; 3546035553Spatrick 3646035553Spatricktemplate <class ElementType, size_t Extent> 3746035553Spatrick span< byte, ((Extent == dynamic_extent) ? dynamic_extent : 3846035553Spatrick (sizeof(ElementType) * Extent))> as_writable_bytes(span<ElementType, Extent> s) noexcept; 3946035553Spatrick 4046035553Spatrick 4146035553Spatricktemplate <class ElementType, size_t Extent = dynamic_extent> 4246035553Spatrickclass span { 4346035553Spatrickpublic: 4446035553Spatrick // constants and types 4546035553Spatrick using element_type = ElementType; 4646035553Spatrick using value_type = remove_cv_t<ElementType>; 4746035553Spatrick using size_type = size_t; 4846035553Spatrick using difference_type = ptrdiff_t; 4946035553Spatrick using pointer = element_type*; 5046035553Spatrick using const_pointer = const element_type*; 5146035553Spatrick using reference = element_type&; 5246035553Spatrick using const_reference = const element_type&; 5346035553Spatrick using iterator = implementation-defined; 5446035553Spatrick using reverse_iterator = std::reverse_iterator<iterator>; 5546035553Spatrick static constexpr size_type extent = Extent; 5646035553Spatrick 5746035553Spatrick // [span.cons], span constructors, copy, assignment, and destructor 5846035553Spatrick constexpr span() noexcept; 59*4bdff4beSrobert template <class It> 60*4bdff4beSrobert constexpr explicit(Extent != dynamic_extent) span(It first, size_type count); 61*4bdff4beSrobert template <class It, class End> 62*4bdff4beSrobert constexpr explicit(Extent != dynamic_extent) span(It first, End last); 6346035553Spatrick template <size_t N> 64*4bdff4beSrobert constexpr span(type_identity_t<element_type> (&arr)[N]) noexcept; 6546035553Spatrick template <size_t N> 6646035553Spatrick constexpr span(array<value_type, N>& arr) noexcept; 6746035553Spatrick template <size_t N> 6846035553Spatrick constexpr span(const array<value_type, N>& arr) noexcept; 69*4bdff4beSrobert template<class R> 70*4bdff4beSrobert constexpr explicit(Extent != dynamic_extent) span(R&& r); 7146035553Spatrick constexpr span(const span& other) noexcept = default; 7246035553Spatrick template <class OtherElementType, size_t OtherExtent> 73037e7968Spatrick constexpr explicit(Extent != dynamic_extent) span(const span<OtherElementType, OtherExtent>& s) noexcept; 7446035553Spatrick ~span() noexcept = default; 7546035553Spatrick constexpr span& operator=(const span& other) noexcept = default; 7646035553Spatrick 7746035553Spatrick // [span.sub], span subviews 7846035553Spatrick template <size_t Count> 7946035553Spatrick constexpr span<element_type, Count> first() const; 8046035553Spatrick template <size_t Count> 8146035553Spatrick constexpr span<element_type, Count> last() const; 8246035553Spatrick template <size_t Offset, size_t Count = dynamic_extent> 8346035553Spatrick constexpr span<element_type, see below> subspan() const; 8446035553Spatrick 8546035553Spatrick constexpr span<element_type, dynamic_extent> first(size_type count) const; 8646035553Spatrick constexpr span<element_type, dynamic_extent> last(size_type count) const; 8746035553Spatrick constexpr span<element_type, dynamic_extent> subspan(size_type offset, size_type count = dynamic_extent) const; 8846035553Spatrick 8946035553Spatrick // [span.obs], span observers 9046035553Spatrick constexpr size_type size() const noexcept; 9146035553Spatrick constexpr size_type size_bytes() const noexcept; 92*4bdff4beSrobert [[nodiscard]] constexpr bool empty() const noexcept; 9346035553Spatrick 9446035553Spatrick // [span.elem], span element access 9546035553Spatrick constexpr reference operator[](size_type idx) const; 9646035553Spatrick constexpr reference front() const; 9746035553Spatrick constexpr reference back() const; 9846035553Spatrick constexpr pointer data() const noexcept; 9946035553Spatrick 10046035553Spatrick // [span.iterators], span iterator support 10146035553Spatrick constexpr iterator begin() const noexcept; 10246035553Spatrick constexpr iterator end() const noexcept; 10346035553Spatrick constexpr reverse_iterator rbegin() const noexcept; 10446035553Spatrick constexpr reverse_iterator rend() const noexcept; 10546035553Spatrick 10646035553Spatrickprivate: 10746035553Spatrick pointer data_; // exposition only 10846035553Spatrick size_type size_; // exposition only 10946035553Spatrick}; 11046035553Spatrick 111*4bdff4beSroberttemplate<class It, class EndOrSize> 112*4bdff4beSrobert span(It, EndOrSize) -> span<remove_reference_t<iter_reference_t<_It>>>; 113*4bdff4beSrobert 11446035553Spatricktemplate<class T, size_t N> 11546035553Spatrick span(T (&)[N]) -> span<T, N>; 11646035553Spatrick 11746035553Spatricktemplate<class T, size_t N> 11846035553Spatrick span(array<T, N>&) -> span<T, N>; 11946035553Spatrick 12046035553Spatricktemplate<class T, size_t N> 12146035553Spatrick span(const array<T, N>&) -> span<const T, N>; 12246035553Spatrick 123*4bdff4beSroberttemplate<class R> 124*4bdff4beSrobert span(R&&) -> span<remove_reference_t<ranges::range_reference_t<R>>>; 12546035553Spatrick 12646035553Spatrick} // namespace std 12746035553Spatrick 12846035553Spatrick*/ 12946035553Spatrick 130*4bdff4beSrobert#include <__assert> // all public C++ headers provide the assertion handler 13146035553Spatrick#include <__config> 13276d0caaeSpatrick#include <__debug> 133*4bdff4beSrobert#include <__fwd/span.h> 134*4bdff4beSrobert#include <__iterator/bounded_iter.h> 135*4bdff4beSrobert#include <__iterator/concepts.h> 136*4bdff4beSrobert#include <__iterator/iterator_traits.h> 13776d0caaeSpatrick#include <__iterator/wrap_iter.h> 138*4bdff4beSrobert#include <__memory/pointer_traits.h> 139*4bdff4beSrobert#include <__ranges/concepts.h> 140*4bdff4beSrobert#include <__ranges/data.h> 14176d0caaeSpatrick#include <__ranges/enable_borrowed_range.h> 14276d0caaeSpatrick#include <__ranges/enable_view.h> 143*4bdff4beSrobert#include <__ranges/size.h> 144*4bdff4beSrobert#include <__utility/forward.h> 14546035553Spatrick#include <array> // for array 14646035553Spatrick#include <cstddef> // for byte 14776d0caaeSpatrick#include <limits> 148037e7968Spatrick#include <type_traits> // for remove_cv, etc 14976d0caaeSpatrick#include <version> 15046035553Spatrick 151*4bdff4beSrobert// standard-mandated includes 152*4bdff4beSrobert 153*4bdff4beSrobert// [iterator.range] 154*4bdff4beSrobert#include <__iterator/access.h> 155*4bdff4beSrobert#include <__iterator/data.h> 156*4bdff4beSrobert#include <__iterator/empty.h> 157*4bdff4beSrobert#include <__iterator/reverse_access.h> 158*4bdff4beSrobert#include <__iterator/size.h> 159*4bdff4beSrobert 16046035553Spatrick#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 16146035553Spatrick# pragma GCC system_header 16246035553Spatrick#endif 16346035553Spatrick 16476d0caaeSpatrick_LIBCPP_PUSH_MACROS 16576d0caaeSpatrick#include <__undef_macros> 16676d0caaeSpatrick 16746035553Spatrick_LIBCPP_BEGIN_NAMESPACE_STD 16846035553Spatrick 16946035553Spatrick#if _LIBCPP_STD_VER > 17 17046035553Spatrick 17146035553Spatricktemplate <class _Tp> 172*4bdff4beSrobertstruct __is_std_array : false_type {}; 17346035553Spatrick 17446035553Spatricktemplate <class _Tp, size_t _Sz> 175*4bdff4beSrobertstruct __is_std_array<array<_Tp, _Sz>> : true_type {}; 17646035553Spatrick 17746035553Spatricktemplate <class _Tp> 178*4bdff4beSrobertstruct __is_std_span : false_type {}; 17946035553Spatrick 180*4bdff4beSroberttemplate <class _Tp, size_t _Sz> 181*4bdff4beSrobertstruct __is_std_span<span<_Tp, _Sz>> : true_type {}; 18246035553Spatrick 183*4bdff4beSroberttemplate <class _Range, class _ElementType> 184*4bdff4beSrobertconcept __span_compatible_range = 185*4bdff4beSrobert ranges::contiguous_range<_Range> && 186*4bdff4beSrobert ranges::sized_range<_Range> && 187*4bdff4beSrobert (ranges::borrowed_range<_Range> || is_const_v<_ElementType>) && 188*4bdff4beSrobert !__is_std_span<remove_cvref_t<_Range>>::value && 189*4bdff4beSrobert !__is_std_array<remove_cvref_t<_Range>>::value && 190*4bdff4beSrobert !is_array_v<remove_cvref_t<_Range>> && 191*4bdff4beSrobert is_convertible_v<remove_reference_t<ranges::range_reference_t<_Range>>(*)[], _ElementType(*)[]>; 19246035553Spatrick 193*4bdff4beSroberttemplate <class _From, class _To> 194*4bdff4beSrobertconcept __span_array_convertible = is_convertible_v<_From(*)[], _To(*)[]>; 195*4bdff4beSrobert 196*4bdff4beSroberttemplate <class _It, class _Tp> 197*4bdff4beSrobertconcept __span_compatible_iterator = contiguous_iterator<_It> && __span_array_convertible<remove_reference_t<iter_reference_t<_It>>, _Tp>; 198*4bdff4beSrobert 199*4bdff4beSroberttemplate <class _Sentinel, class _It> 200*4bdff4beSrobertconcept __span_compatible_sentinel_for = sized_sentinel_for<_Sentinel, _It> && !is_convertible_v<_Sentinel, size_t>; 20146035553Spatrick 20246035553Spatricktemplate <typename _Tp, size_t _Extent> 20346035553Spatrickclass _LIBCPP_TEMPLATE_VIS span { 20446035553Spatrickpublic: 20546035553Spatrick// constants and types 20646035553Spatrick using element_type = _Tp; 20746035553Spatrick using value_type = remove_cv_t<_Tp>; 20846035553Spatrick using size_type = size_t; 20946035553Spatrick using difference_type = ptrdiff_t; 21046035553Spatrick using pointer = _Tp *; 21146035553Spatrick using const_pointer = const _Tp *; 21246035553Spatrick using reference = _Tp &; 21346035553Spatrick using const_reference = const _Tp &; 214*4bdff4beSrobert#ifdef _LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING 215*4bdff4beSrobert using iterator = __bounded_iter<pointer>; 21676d0caaeSpatrick#else 21746035553Spatrick using iterator = __wrap_iter<pointer>; 21876d0caaeSpatrick#endif 21946035553Spatrick using reverse_iterator = _VSTD::reverse_iterator<iterator>; 22046035553Spatrick 22146035553Spatrick static constexpr size_type extent = _Extent; 22246035553Spatrick 22346035553Spatrick// [span.cons], span constructors, copy, assignment, and destructor 224*4bdff4beSrobert template <size_t _Sz = _Extent> requires(_Sz == 0) 225*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data_{nullptr} {} 22646035553Spatrick 22746035553Spatrick constexpr span (const span&) noexcept = default; 22846035553Spatrick constexpr span& operator=(const span&) noexcept = default; 22946035553Spatrick 230*4bdff4beSrobert template <__span_compatible_iterator<element_type> _It> 231037e7968Spatrick _LIBCPP_INLINE_VISIBILITY 232*4bdff4beSrobert constexpr explicit span(_It __first, size_type __count) 233*4bdff4beSrobert : __data_{_VSTD::to_address(__first)} { 234*4bdff4beSrobert (void)__count; 235*4bdff4beSrobert _LIBCPP_ASSERT(_Extent == __count, "size mismatch in span's constructor (iterator, len)"); 236037e7968Spatrick } 237037e7968Spatrick 238*4bdff4beSrobert template <__span_compatible_iterator<element_type> _It, __span_compatible_sentinel_for<_It> _End> 239037e7968Spatrick _LIBCPP_INLINE_VISIBILITY 240*4bdff4beSrobert constexpr explicit span(_It __first, _End __last) : __data_{_VSTD::to_address(__first)} { 241*4bdff4beSrobert (void)__last; 242*4bdff4beSrobert _LIBCPP_ASSERT((__last - __first >= 0), "invalid range in span's constructor (iterator, sentinel)"); 243*4bdff4beSrobert _LIBCPP_ASSERT(__last - __first == _Extent, 244*4bdff4beSrobert "invalid range in span's constructor (iterator, sentinel): last - first != extent"); 245037e7968Spatrick } 24646035553Spatrick 247*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY constexpr span(type_identity_t<element_type> (&__arr)[_Extent]) noexcept : __data_{__arr} {} 248*4bdff4beSrobert 249*4bdff4beSrobert template <__span_array_convertible<element_type> _OtherElementType> 25046035553Spatrick _LIBCPP_INLINE_VISIBILITY 251*4bdff4beSrobert constexpr span(array<_OtherElementType, _Extent>& __arr) noexcept : __data_{__arr.data()} {} 25246035553Spatrick 25346035553Spatrick template <class _OtherElementType> 254*4bdff4beSrobert requires __span_array_convertible<const _OtherElementType, element_type> 25546035553Spatrick _LIBCPP_INLINE_VISIBILITY 256*4bdff4beSrobert constexpr span(const array<_OtherElementType, _Extent>& __arr) noexcept : __data_{__arr.data()} {} 257*4bdff4beSrobert 258*4bdff4beSrobert template <__span_compatible_range<element_type> _Range> 259*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY 260*4bdff4beSrobert constexpr explicit span(_Range&& __r) : __data_{ranges::data(__r)} { 261*4bdff4beSrobert _LIBCPP_ASSERT(ranges::size(__r) == _Extent, "size mismatch in span's constructor (range)"); 262*4bdff4beSrobert } 263*4bdff4beSrobert 264*4bdff4beSrobert template <__span_array_convertible<element_type> _OtherElementType> 265*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY 266*4bdff4beSrobert constexpr span(const span<_OtherElementType, _Extent>& __other) 267*4bdff4beSrobert : __data_{__other.data()} {} 268*4bdff4beSrobert 269*4bdff4beSrobert template <__span_array_convertible<element_type> _OtherElementType> 270*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY 271*4bdff4beSrobert constexpr explicit span(const span<_OtherElementType, dynamic_extent>& __other) noexcept 272*4bdff4beSrobert : __data_{__other.data()} { _LIBCPP_ASSERT(_Extent == __other.size(), "size mismatch in span's constructor (other span)"); } 27346035553Spatrick 27446035553Spatrick 27546035553Spatrick// ~span() noexcept = default; 27646035553Spatrick 27746035553Spatrick template <size_t _Count> 27846035553Spatrick _LIBCPP_INLINE_VISIBILITY 27946035553Spatrick constexpr span<element_type, _Count> first() const noexcept 28046035553Spatrick { 281*4bdff4beSrobert static_assert(_Count <= _Extent, "span<T, N>::first<Count>(): Count out of range"); 282037e7968Spatrick return span<element_type, _Count>{data(), _Count}; 28346035553Spatrick } 28446035553Spatrick 28546035553Spatrick template <size_t _Count> 28646035553Spatrick _LIBCPP_INLINE_VISIBILITY 28746035553Spatrick constexpr span<element_type, _Count> last() const noexcept 28846035553Spatrick { 289*4bdff4beSrobert static_assert(_Count <= _Extent, "span<T, N>::last<Count>(): Count out of range"); 290037e7968Spatrick return span<element_type, _Count>{data() + size() - _Count, _Count}; 29146035553Spatrick } 29246035553Spatrick 29346035553Spatrick _LIBCPP_INLINE_VISIBILITY 29446035553Spatrick constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept 29546035553Spatrick { 296*4bdff4beSrobert _LIBCPP_ASSERT(__count <= size(), "span<T, N>::first(count): count out of range"); 29746035553Spatrick return {data(), __count}; 29846035553Spatrick } 29946035553Spatrick 30046035553Spatrick _LIBCPP_INLINE_VISIBILITY 30146035553Spatrick constexpr span<element_type, dynamic_extent> last(size_type __count) const noexcept 30246035553Spatrick { 303*4bdff4beSrobert _LIBCPP_ASSERT(__count <= size(), "span<T, N>::last(count): count out of range"); 30446035553Spatrick return {data() + size() - __count, __count}; 30546035553Spatrick } 30646035553Spatrick 30746035553Spatrick template <size_t _Offset, size_t _Count = dynamic_extent> 30846035553Spatrick _LIBCPP_INLINE_VISIBILITY 30946035553Spatrick constexpr auto subspan() const noexcept 31046035553Spatrick -> span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset> 31146035553Spatrick { 312*4bdff4beSrobert static_assert(_Offset <= _Extent, "span<T, N>::subspan<Offset, Count>(): Offset out of range"); 313*4bdff4beSrobert static_assert(_Count == dynamic_extent || _Count <= _Extent - _Offset, "span<T, N>::subspan<Offset, Count>(): Offset + Count out of range"); 314037e7968Spatrick 315037e7968Spatrick using _ReturnType = span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset>; 316037e7968Spatrick return _ReturnType{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; 31746035553Spatrick } 31846035553Spatrick 31946035553Spatrick 32046035553Spatrick _LIBCPP_INLINE_VISIBILITY 32146035553Spatrick constexpr span<element_type, dynamic_extent> 32246035553Spatrick subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept 32346035553Spatrick { 324*4bdff4beSrobert _LIBCPP_ASSERT(__offset <= size(), "span<T, N>::subspan(offset, count): offset out of range"); 325*4bdff4beSrobert _LIBCPP_ASSERT(__count <= size() || __count == dynamic_extent, "span<T, N>::subspan(offset, count): count out of range"); 32646035553Spatrick if (__count == dynamic_extent) 32746035553Spatrick return {data() + __offset, size() - __offset}; 328*4bdff4beSrobert _LIBCPP_ASSERT(__count <= size() - __offset, "span<T, N>::subspan(offset, count): offset + count out of range"); 32946035553Spatrick return {data() + __offset, __count}; 33046035553Spatrick } 33146035553Spatrick 33246035553Spatrick _LIBCPP_INLINE_VISIBILITY constexpr size_type size() const noexcept { return _Extent; } 33346035553Spatrick _LIBCPP_INLINE_VISIBILITY constexpr size_type size_bytes() const noexcept { return _Extent * sizeof(element_type); } 334*4bdff4beSrobert [[nodiscard]] _LIBCPP_INLINE_VISIBILITY constexpr bool empty() const noexcept { return _Extent == 0; } 33546035553Spatrick 33646035553Spatrick _LIBCPP_INLINE_VISIBILITY constexpr reference operator[](size_type __idx) const noexcept 33746035553Spatrick { 338*4bdff4beSrobert _LIBCPP_ASSERT(__idx < size(), "span<T, N>::operator[](index): index out of range"); 339*4bdff4beSrobert return __data_[__idx]; 34046035553Spatrick } 34146035553Spatrick 34246035553Spatrick _LIBCPP_INLINE_VISIBILITY constexpr reference front() const noexcept 34346035553Spatrick { 344037e7968Spatrick _LIBCPP_ASSERT(!empty(), "span<T, N>::front() on empty span"); 345*4bdff4beSrobert return __data_[0]; 34646035553Spatrick } 34746035553Spatrick 34846035553Spatrick _LIBCPP_INLINE_VISIBILITY constexpr reference back() const noexcept 34946035553Spatrick { 350037e7968Spatrick _LIBCPP_ASSERT(!empty(), "span<T, N>::back() on empty span"); 351*4bdff4beSrobert return __data_[size()-1]; 35246035553Spatrick } 35346035553Spatrick 354*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY constexpr pointer data() const noexcept { return __data_; } 35546035553Spatrick 35646035553Spatrick// [span.iter], span iterator support 357*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY constexpr iterator begin() const noexcept { 358*4bdff4beSrobert#ifdef _LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING 359*4bdff4beSrobert return std::__make_bounded_iter(data(), data(), data() + size()); 360*4bdff4beSrobert#else 361*4bdff4beSrobert return iterator(this, data()); 362*4bdff4beSrobert#endif 363*4bdff4beSrobert } 364*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY constexpr iterator end() const noexcept { 365*4bdff4beSrobert#ifdef _LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING 366*4bdff4beSrobert return std::__make_bounded_iter(data() + size(), data(), data() + size()); 367*4bdff4beSrobert#else 368*4bdff4beSrobert return iterator(this, data() + size()); 369*4bdff4beSrobert#endif 370*4bdff4beSrobert } 37146035553Spatrick _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); } 37246035553Spatrick _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); } 37346035553Spatrick 37446035553Spatrick _LIBCPP_INLINE_VISIBILITY span<const byte, _Extent * sizeof(element_type)> __as_bytes() const noexcept 375037e7968Spatrick { return span<const byte, _Extent * sizeof(element_type)>{reinterpret_cast<const byte *>(data()), size_bytes()}; } 37646035553Spatrick 37746035553Spatrick _LIBCPP_INLINE_VISIBILITY span<byte, _Extent * sizeof(element_type)> __as_writable_bytes() const noexcept 378037e7968Spatrick { return span<byte, _Extent * sizeof(element_type)>{reinterpret_cast<byte *>(data()), size_bytes()}; } 37946035553Spatrick 38046035553Spatrickprivate: 381*4bdff4beSrobert pointer __data_; 38246035553Spatrick}; 38346035553Spatrick 38446035553Spatrick 38546035553Spatricktemplate <typename _Tp> 38646035553Spatrickclass _LIBCPP_TEMPLATE_VIS span<_Tp, dynamic_extent> { 38746035553Spatrickpublic: 38846035553Spatrick// constants and types 38946035553Spatrick using element_type = _Tp; 39046035553Spatrick using value_type = remove_cv_t<_Tp>; 39146035553Spatrick using size_type = size_t; 39246035553Spatrick using difference_type = ptrdiff_t; 39346035553Spatrick using pointer = _Tp *; 39446035553Spatrick using const_pointer = const _Tp *; 39546035553Spatrick using reference = _Tp &; 39646035553Spatrick using const_reference = const _Tp &; 397*4bdff4beSrobert#ifdef _LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING 398*4bdff4beSrobert using iterator = __bounded_iter<pointer>; 39976d0caaeSpatrick#else 40046035553Spatrick using iterator = __wrap_iter<pointer>; 40176d0caaeSpatrick#endif 40246035553Spatrick using reverse_iterator = _VSTD::reverse_iterator<iterator>; 40346035553Spatrick 40446035553Spatrick static constexpr size_type extent = dynamic_extent; 40546035553Spatrick 40646035553Spatrick// [span.cons], span constructors, copy, assignment, and destructor 407*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data_{nullptr}, __size_{0} {} 40846035553Spatrick 40946035553Spatrick constexpr span (const span&) noexcept = default; 41046035553Spatrick constexpr span& operator=(const span&) noexcept = default; 41146035553Spatrick 412*4bdff4beSrobert template <__span_compatible_iterator<element_type> _It> 413*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY 414*4bdff4beSrobert constexpr span(_It __first, size_type __count) 415*4bdff4beSrobert : __data_{_VSTD::to_address(__first)}, __size_{__count} {} 416*4bdff4beSrobert 417*4bdff4beSrobert template <__span_compatible_iterator<element_type> _It, __span_compatible_sentinel_for<_It> _End> 418*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY constexpr span(_It __first, _End __last) 419*4bdff4beSrobert : __data_(_VSTD::to_address(__first)), __size_(__last - __first) { 420*4bdff4beSrobert _LIBCPP_ASSERT(__last - __first >= 0, "invalid range in span's constructor (iterator, sentinel)"); 421*4bdff4beSrobert } 42246035553Spatrick 42346035553Spatrick template <size_t _Sz> 42446035553Spatrick _LIBCPP_INLINE_VISIBILITY 425*4bdff4beSrobert constexpr span(type_identity_t<element_type> (&__arr)[_Sz]) noexcept : __data_{__arr}, __size_{_Sz} {} 42646035553Spatrick 427*4bdff4beSrobert template <__span_array_convertible<element_type> _OtherElementType, size_t _Sz> 42846035553Spatrick _LIBCPP_INLINE_VISIBILITY 429*4bdff4beSrobert constexpr span(array<_OtherElementType, _Sz>& __arr) noexcept : __data_{__arr.data()}, __size_{_Sz} {} 43046035553Spatrick 431*4bdff4beSrobert template <class _OtherElementType, size_t _Sz> 432*4bdff4beSrobert requires __span_array_convertible<const _OtherElementType, element_type> 43346035553Spatrick _LIBCPP_INLINE_VISIBILITY 434*4bdff4beSrobert constexpr span(const array<_OtherElementType, _Sz>& __arr) noexcept : __data_{__arr.data()}, __size_{_Sz} {} 43546035553Spatrick 436*4bdff4beSrobert template <__span_compatible_range<element_type> _Range> 43746035553Spatrick _LIBCPP_INLINE_VISIBILITY 438*4bdff4beSrobert constexpr span(_Range&& __r) : __data_(ranges::data(__r)), __size_{ranges::size(__r)} {} 43946035553Spatrick 440*4bdff4beSrobert template <__span_array_convertible<element_type> _OtherElementType, size_t _OtherExtent> 44146035553Spatrick _LIBCPP_INLINE_VISIBILITY 442*4bdff4beSrobert constexpr span(const span<_OtherElementType, _OtherExtent>& __other) noexcept 443*4bdff4beSrobert : __data_{__other.data()}, __size_{__other.size()} {} 44446035553Spatrick 44546035553Spatrick// ~span() noexcept = default; 44646035553Spatrick 44746035553Spatrick template <size_t _Count> 44846035553Spatrick _LIBCPP_INLINE_VISIBILITY 44946035553Spatrick constexpr span<element_type, _Count> first() const noexcept 45046035553Spatrick { 451*4bdff4beSrobert _LIBCPP_ASSERT(_Count <= size(), "span<T>::first<Count>(): Count out of range"); 452037e7968Spatrick return span<element_type, _Count>{data(), _Count}; 45346035553Spatrick } 45446035553Spatrick 45546035553Spatrick template <size_t _Count> 45646035553Spatrick _LIBCPP_INLINE_VISIBILITY 45746035553Spatrick constexpr span<element_type, _Count> last() const noexcept 45846035553Spatrick { 459*4bdff4beSrobert _LIBCPP_ASSERT(_Count <= size(), "span<T>::last<Count>(): Count out of range"); 460037e7968Spatrick return span<element_type, _Count>{data() + size() - _Count, _Count}; 46146035553Spatrick } 46246035553Spatrick 46346035553Spatrick _LIBCPP_INLINE_VISIBILITY 46446035553Spatrick constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept 46546035553Spatrick { 466*4bdff4beSrobert _LIBCPP_ASSERT(__count <= size(), "span<T>::first(count): count out of range"); 46746035553Spatrick return {data(), __count}; 46846035553Spatrick } 46946035553Spatrick 47046035553Spatrick _LIBCPP_INLINE_VISIBILITY 47146035553Spatrick constexpr span<element_type, dynamic_extent> last (size_type __count) const noexcept 47246035553Spatrick { 473*4bdff4beSrobert _LIBCPP_ASSERT(__count <= size(), "span<T>::last(count): count out of range"); 47446035553Spatrick return {data() + size() - __count, __count}; 47546035553Spatrick } 47646035553Spatrick 47746035553Spatrick template <size_t _Offset, size_t _Count = dynamic_extent> 47846035553Spatrick _LIBCPP_INLINE_VISIBILITY 479037e7968Spatrick constexpr span<element_type, _Count> subspan() const noexcept 48046035553Spatrick { 481*4bdff4beSrobert _LIBCPP_ASSERT(_Offset <= size(), "span<T>::subspan<Offset, Count>(): Offset out of range"); 482*4bdff4beSrobert _LIBCPP_ASSERT(_Count == dynamic_extent || _Count <= size() - _Offset, "span<T>::subspan<Offset, Count>(): Offset + Count out of range"); 483037e7968Spatrick return span<element_type, _Count>{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; 48446035553Spatrick } 48546035553Spatrick 48646035553Spatrick constexpr span<element_type, dynamic_extent> 48746035553Spatrick _LIBCPP_INLINE_VISIBILITY 48846035553Spatrick subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept 48946035553Spatrick { 490*4bdff4beSrobert _LIBCPP_ASSERT(__offset <= size(), "span<T>::subspan(offset, count): offset out of range"); 491*4bdff4beSrobert _LIBCPP_ASSERT(__count <= size() || __count == dynamic_extent, "span<T>::subspan(offset, count): count out of range"); 49246035553Spatrick if (__count == dynamic_extent) 49346035553Spatrick return {data() + __offset, size() - __offset}; 494*4bdff4beSrobert _LIBCPP_ASSERT(__count <= size() - __offset, "span<T>::subspan(offset, count): offset + count out of range"); 49546035553Spatrick return {data() + __offset, __count}; 49646035553Spatrick } 49746035553Spatrick 498*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY constexpr size_type size() const noexcept { return __size_; } 499*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY constexpr size_type size_bytes() const noexcept { return __size_ * sizeof(element_type); } 500*4bdff4beSrobert [[nodiscard]] _LIBCPP_INLINE_VISIBILITY constexpr bool empty() const noexcept { return __size_ == 0; } 50146035553Spatrick 50246035553Spatrick _LIBCPP_INLINE_VISIBILITY constexpr reference operator[](size_type __idx) const noexcept 50346035553Spatrick { 504*4bdff4beSrobert _LIBCPP_ASSERT(__idx < size(), "span<T>::operator[](index): index out of range"); 505*4bdff4beSrobert return __data_[__idx]; 50646035553Spatrick } 50746035553Spatrick 50846035553Spatrick _LIBCPP_INLINE_VISIBILITY constexpr reference front() const noexcept 50946035553Spatrick { 510*4bdff4beSrobert _LIBCPP_ASSERT(!empty(), "span<T>::front() on empty span"); 511*4bdff4beSrobert return __data_[0]; 51246035553Spatrick } 51346035553Spatrick 51446035553Spatrick _LIBCPP_INLINE_VISIBILITY constexpr reference back() const noexcept 51546035553Spatrick { 516*4bdff4beSrobert _LIBCPP_ASSERT(!empty(), "span<T>::back() on empty span"); 517*4bdff4beSrobert return __data_[size()-1]; 51846035553Spatrick } 51946035553Spatrick 52046035553Spatrick 521*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY constexpr pointer data() const noexcept { return __data_; } 52246035553Spatrick 52346035553Spatrick// [span.iter], span iterator support 524*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY constexpr iterator begin() const noexcept { 525*4bdff4beSrobert#ifdef _LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING 526*4bdff4beSrobert return std::__make_bounded_iter(data(), data(), data() + size()); 527*4bdff4beSrobert#else 528*4bdff4beSrobert return iterator(this, data()); 529*4bdff4beSrobert#endif 530*4bdff4beSrobert } 531*4bdff4beSrobert _LIBCPP_INLINE_VISIBILITY constexpr iterator end() const noexcept { 532*4bdff4beSrobert#ifdef _LIBCPP_DEBUG_ITERATOR_BOUNDS_CHECKING 533*4bdff4beSrobert return std::__make_bounded_iter(data() + size(), data(), data() + size()); 534*4bdff4beSrobert#else 535*4bdff4beSrobert return iterator(this, data() + size()); 536*4bdff4beSrobert#endif 537*4bdff4beSrobert } 53846035553Spatrick _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); } 53946035553Spatrick _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); } 54046035553Spatrick 54146035553Spatrick _LIBCPP_INLINE_VISIBILITY span<const byte, dynamic_extent> __as_bytes() const noexcept 54246035553Spatrick { return {reinterpret_cast<const byte *>(data()), size_bytes()}; } 54346035553Spatrick 54446035553Spatrick _LIBCPP_INLINE_VISIBILITY span<byte, dynamic_extent> __as_writable_bytes() const noexcept 54546035553Spatrick { return {reinterpret_cast<byte *>(data()), size_bytes()}; } 54646035553Spatrick 54746035553Spatrickprivate: 548*4bdff4beSrobert pointer __data_; 549*4bdff4beSrobert size_type __size_; 55046035553Spatrick}; 55146035553Spatrick 55276d0caaeSpatricktemplate <class _Tp, size_t _Extent> 55376d0caaeSpatrickinline constexpr bool ranges::enable_borrowed_range<span<_Tp, _Extent> > = true; 55476d0caaeSpatrick 55576d0caaeSpatricktemplate <class _ElementType, size_t _Extent> 55676d0caaeSpatrickinline constexpr bool ranges::enable_view<span<_ElementType, _Extent>> = true; 55776d0caaeSpatrick 55846035553Spatrick// as_bytes & as_writable_bytes 55946035553Spatricktemplate <class _Tp, size_t _Extent> 56046035553Spatrick_LIBCPP_INLINE_VISIBILITY 56146035553Spatrickauto as_bytes(span<_Tp, _Extent> __s) noexcept 56246035553Spatrick{ return __s.__as_bytes(); } 56346035553Spatrick 564*4bdff4beSroberttemplate <class _Tp, size_t _Extent> requires(!is_const_v<_Tp>) 56546035553Spatrick_LIBCPP_INLINE_VISIBILITY 56646035553Spatrickauto as_writable_bytes(span<_Tp, _Extent> __s) noexcept 56746035553Spatrick{ return __s.__as_writable_bytes(); } 56846035553Spatrick 569*4bdff4beSrobert#if _LIBCPP_STD_VER > 17 570*4bdff4beSroberttemplate<contiguous_iterator _It, class _EndOrSize> 571*4bdff4beSrobert span(_It, _EndOrSize) -> span<remove_reference_t<iter_reference_t<_It>>>; 572*4bdff4beSrobert#endif // _LIBCPP_STD_VER > 17 573*4bdff4beSrobert 57446035553Spatricktemplate<class _Tp, size_t _Sz> 57546035553Spatrick span(_Tp (&)[_Sz]) -> span<_Tp, _Sz>; 57646035553Spatrick 57746035553Spatricktemplate<class _Tp, size_t _Sz> 57846035553Spatrick span(array<_Tp, _Sz>&) -> span<_Tp, _Sz>; 57946035553Spatrick 58046035553Spatricktemplate<class _Tp, size_t _Sz> 58146035553Spatrick span(const array<_Tp, _Sz>&) -> span<const _Tp, _Sz>; 58246035553Spatrick 583*4bdff4beSroberttemplate<ranges::contiguous_range _Range> 584*4bdff4beSrobert span(_Range&&) -> span<remove_reference_t<ranges::range_reference_t<_Range>>>; 58546035553Spatrick 58646035553Spatrick#endif // _LIBCPP_STD_VER > 17 58746035553Spatrick 58846035553Spatrick_LIBCPP_END_NAMESPACE_STD 58946035553Spatrick 59076d0caaeSpatrick_LIBCPP_POP_MACROS 59176d0caaeSpatrick 592*4bdff4beSrobert#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 593*4bdff4beSrobert# include <concepts> 594*4bdff4beSrobert# include <functional> 595*4bdff4beSrobert# include <iterator> 596*4bdff4beSrobert#endif 597*4bdff4beSrobert 59846035553Spatrick#endif // _LIBCPP_SPAN 599