10b57cec5SDimitry Andric// -*- C++ -*- 2349cc55cSDimitry Andric//===----------------------------------------------------------------------===// 30b57cec5SDimitry Andric// 40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information. 60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 70b57cec5SDimitry Andric// 80b57cec5SDimitry Andric//===---------------------------------------------------------------------===// 90b57cec5SDimitry Andric 100b57cec5SDimitry Andric#ifndef _LIBCPP_SPAN 110b57cec5SDimitry Andric#define _LIBCPP_SPAN 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric/* 140b57cec5SDimitry Andric span synopsis 150b57cec5SDimitry Andric 160b57cec5SDimitry Andricnamespace std { 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric// constants 190b57cec5SDimitry Andricinline constexpr size_t dynamic_extent = numeric_limits<size_t>::max(); 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric// [views.span], class template span 220b57cec5SDimitry Andrictemplate <class ElementType, size_t Extent = dynamic_extent> 230b57cec5SDimitry Andric class span; 240b57cec5SDimitry Andric 25fe6060f1SDimitry Andrictemplate<class ElementType, size_t Extent> 26fe6060f1SDimitry Andric inline constexpr bool ranges::enable_view<span<ElementType, Extent>> = true; 27fe6060f1SDimitry Andric 28fe6060f1SDimitry Andrictemplate<class ElementType, size_t Extent> 29fe6060f1SDimitry Andric inline constexpr bool ranges::enable_borrowed_range<span<ElementType, Extent>> = true; 30fe6060f1SDimitry Andric 310b57cec5SDimitry Andric// [span.objectrep], views of object representation 320b57cec5SDimitry Andrictemplate <class ElementType, size_t Extent> 330b57cec5SDimitry Andric span<const byte, ((Extent == dynamic_extent) ? dynamic_extent : 340b57cec5SDimitry Andric (sizeof(ElementType) * Extent))> as_bytes(span<ElementType, Extent> s) noexcept; 350b57cec5SDimitry Andric 360b57cec5SDimitry Andrictemplate <class ElementType, size_t Extent> 370b57cec5SDimitry Andric span< byte, ((Extent == dynamic_extent) ? dynamic_extent : 380b57cec5SDimitry Andric (sizeof(ElementType) * Extent))> as_writable_bytes(span<ElementType, Extent> s) noexcept; 390b57cec5SDimitry Andric 400b57cec5SDimitry Andric 410b57cec5SDimitry Andrictemplate <class ElementType, size_t Extent = dynamic_extent> 420b57cec5SDimitry Andricclass span { 430b57cec5SDimitry Andricpublic: 440b57cec5SDimitry Andric // constants and types 450b57cec5SDimitry Andric using element_type = ElementType; 460b57cec5SDimitry Andric using value_type = remove_cv_t<ElementType>; 47480093f4SDimitry Andric using size_type = size_t; 480b57cec5SDimitry Andric using difference_type = ptrdiff_t; 490b57cec5SDimitry Andric using pointer = element_type*; 500b57cec5SDimitry Andric using const_pointer = const element_type*; 510b57cec5SDimitry Andric using reference = element_type&; 520b57cec5SDimitry Andric using const_reference = const element_type&; 530b57cec5SDimitry Andric using iterator = implementation-defined; 540b57cec5SDimitry Andric using reverse_iterator = std::reverse_iterator<iterator>; 55480093f4SDimitry Andric static constexpr size_type extent = Extent; 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric // [span.cons], span constructors, copy, assignment, and destructor 580b57cec5SDimitry Andric constexpr span() noexcept; 59349cc55cSDimitry Andric template <class It> 60349cc55cSDimitry Andric constexpr explicit(Extent != dynamic_extent) span(It first, size_type count); 61349cc55cSDimitry Andric template <class It, class End> 62349cc55cSDimitry Andric constexpr explicit(Extent != dynamic_extent) span(It first, End last); 630b57cec5SDimitry Andric template <size_t N> 64349cc55cSDimitry Andric constexpr span(type_identity_t<element_type> (&arr)[N]) noexcept; 650b57cec5SDimitry Andric template <size_t N> 660b57cec5SDimitry Andric constexpr span(array<value_type, N>& arr) noexcept; 670b57cec5SDimitry Andric template <size_t N> 680b57cec5SDimitry Andric constexpr span(const array<value_type, N>& arr) noexcept; 69349cc55cSDimitry Andric template<class R> 70349cc55cSDimitry Andric constexpr explicit(Extent != dynamic_extent) span(R&& r); 710b57cec5SDimitry Andric constexpr span(const span& other) noexcept = default; 720b57cec5SDimitry Andric template <class OtherElementType, size_t OtherExtent> 735ffd83dbSDimitry Andric constexpr explicit(Extent != dynamic_extent) span(const span<OtherElementType, OtherExtent>& s) noexcept; 740b57cec5SDimitry Andric constexpr span& operator=(const span& other) noexcept = default; 750b57cec5SDimitry Andric 760b57cec5SDimitry Andric // [span.sub], span subviews 770b57cec5SDimitry Andric template <size_t Count> 780b57cec5SDimitry Andric constexpr span<element_type, Count> first() const; 790b57cec5SDimitry Andric template <size_t Count> 800b57cec5SDimitry Andric constexpr span<element_type, Count> last() const; 810b57cec5SDimitry Andric template <size_t Offset, size_t Count = dynamic_extent> 820b57cec5SDimitry Andric constexpr span<element_type, see below> subspan() const; 830b57cec5SDimitry Andric 84480093f4SDimitry Andric constexpr span<element_type, dynamic_extent> first(size_type count) const; 85480093f4SDimitry Andric constexpr span<element_type, dynamic_extent> last(size_type count) const; 86480093f4SDimitry Andric constexpr span<element_type, dynamic_extent> subspan(size_type offset, size_type count = dynamic_extent) const; 870b57cec5SDimitry Andric 880b57cec5SDimitry Andric // [span.obs], span observers 89480093f4SDimitry Andric constexpr size_type size() const noexcept; 90480093f4SDimitry Andric constexpr size_type size_bytes() const noexcept; 91349cc55cSDimitry Andric [[nodiscard]] constexpr bool empty() const noexcept; 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric // [span.elem], span element access 94480093f4SDimitry Andric constexpr reference operator[](size_type idx) const; 950b57cec5SDimitry Andric constexpr reference front() const; 960b57cec5SDimitry Andric constexpr reference back() const; 970b57cec5SDimitry Andric constexpr pointer data() const noexcept; 980b57cec5SDimitry Andric 990b57cec5SDimitry Andric // [span.iterators], span iterator support 1000b57cec5SDimitry Andric constexpr iterator begin() const noexcept; 1010b57cec5SDimitry Andric constexpr iterator end() const noexcept; 1020b57cec5SDimitry Andric constexpr reverse_iterator rbegin() const noexcept; 1030b57cec5SDimitry Andric constexpr reverse_iterator rend() const noexcept; 1040b57cec5SDimitry Andric 1050b57cec5SDimitry Andricprivate: 1060b57cec5SDimitry Andric pointer data_; // exposition only 107480093f4SDimitry Andric size_type size_; // exposition only 1080b57cec5SDimitry Andric}; 1090b57cec5SDimitry Andric 110349cc55cSDimitry Andrictemplate<class It, class EndOrSize> 111349cc55cSDimitry Andric span(It, EndOrSize) -> span<remove_reference_t<iter_reference_t<_It>>>; 112349cc55cSDimitry Andric 1130b57cec5SDimitry Andrictemplate<class T, size_t N> 1140b57cec5SDimitry Andric span(T (&)[N]) -> span<T, N>; 1150b57cec5SDimitry Andric 1160b57cec5SDimitry Andrictemplate<class T, size_t N> 1170b57cec5SDimitry Andric span(array<T, N>&) -> span<T, N>; 1180b57cec5SDimitry Andric 1190b57cec5SDimitry Andrictemplate<class T, size_t N> 1200b57cec5SDimitry Andric span(const array<T, N>&) -> span<const T, N>; 1210b57cec5SDimitry Andric 122349cc55cSDimitry Andrictemplate<class R> 123349cc55cSDimitry Andric span(R&&) -> span<remove_reference_t<ranges::range_reference_t<R>>>; 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andric} // namespace std 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric*/ 1280b57cec5SDimitry Andric 12981ad6265SDimitry Andric#include <__assert> // all public C++ headers provide the assertion handler 1300b57cec5SDimitry Andric#include <__config> 13181ad6265SDimitry Andric#include <__fwd/span.h> 13281ad6265SDimitry Andric#include <__iterator/bounded_iter.h> 133349cc55cSDimitry Andric#include <__iterator/concepts.h> 13481ad6265SDimitry Andric#include <__iterator/iterator_traits.h> 135fe6060f1SDimitry Andric#include <__iterator/wrap_iter.h> 13681ad6265SDimitry Andric#include <__memory/pointer_traits.h> 137349cc55cSDimitry Andric#include <__ranges/concepts.h> 138349cc55cSDimitry Andric#include <__ranges/data.h> 139fe6060f1SDimitry Andric#include <__ranges/enable_borrowed_range.h> 140fe6060f1SDimitry Andric#include <__ranges/enable_view.h> 141349cc55cSDimitry Andric#include <__ranges/size.h> 142*06c3fb27SDimitry Andric#include <__type_traits/is_convertible.h> 143*06c3fb27SDimitry Andric#include <__type_traits/remove_cvref.h> 144*06c3fb27SDimitry Andric#include <__type_traits/remove_reference.h> 145*06c3fb27SDimitry Andric#include <__type_traits/type_identity.h> 14681ad6265SDimitry Andric#include <__utility/forward.h> 1470b57cec5SDimitry Andric#include <array> // for array 1480b57cec5SDimitry Andric#include <cstddef> // for byte 149fe6060f1SDimitry Andric#include <limits> 150fe6060f1SDimitry Andric#include <version> 1510b57cec5SDimitry Andric 15281ad6265SDimitry Andric// standard-mandated includes 15381ad6265SDimitry Andric 15481ad6265SDimitry Andric// [iterator.range] 15581ad6265SDimitry Andric#include <__iterator/access.h> 15681ad6265SDimitry Andric#include <__iterator/data.h> 15781ad6265SDimitry Andric#include <__iterator/empty.h> 15881ad6265SDimitry Andric#include <__iterator/reverse_access.h> 15981ad6265SDimitry Andric#include <__iterator/size.h> 16081ad6265SDimitry Andric 1610b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 1620b57cec5SDimitry Andric# pragma GCC system_header 1630b57cec5SDimitry Andric#endif 1640b57cec5SDimitry Andric 165e8d8bef9SDimitry Andric_LIBCPP_PUSH_MACROS 166e8d8bef9SDimitry Andric#include <__undef_macros> 167e8d8bef9SDimitry Andric 1680b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 1690b57cec5SDimitry Andric 170*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 20 1710b57cec5SDimitry Andric 1720b57cec5SDimitry Andrictemplate <class _Tp> 173349cc55cSDimitry Andricstruct __is_std_array : false_type {}; 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andrictemplate <class _Tp, size_t _Sz> 176349cc55cSDimitry Andricstruct __is_std_array<array<_Tp, _Sz>> : true_type {}; 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andrictemplate <class _Tp> 179349cc55cSDimitry Andricstruct __is_std_span : false_type {}; 1800b57cec5SDimitry Andric 181349cc55cSDimitry Andrictemplate <class _Tp, size_t _Sz> 182349cc55cSDimitry Andricstruct __is_std_span<span<_Tp, _Sz>> : true_type {}; 1830b57cec5SDimitry Andric 184349cc55cSDimitry Andrictemplate <class _Range, class _ElementType> 185349cc55cSDimitry Andricconcept __span_compatible_range = 186349cc55cSDimitry Andric ranges::contiguous_range<_Range> && 187349cc55cSDimitry Andric ranges::sized_range<_Range> && 188349cc55cSDimitry Andric (ranges::borrowed_range<_Range> || is_const_v<_ElementType>) && 189349cc55cSDimitry Andric !__is_std_span<remove_cvref_t<_Range>>::value && 190349cc55cSDimitry Andric !__is_std_array<remove_cvref_t<_Range>>::value && 191349cc55cSDimitry Andric !is_array_v<remove_cvref_t<_Range>> && 192349cc55cSDimitry Andric is_convertible_v<remove_reference_t<ranges::range_reference_t<_Range>>(*)[], _ElementType(*)[]>; 19381ad6265SDimitry Andric 19481ad6265SDimitry Andrictemplate <class _From, class _To> 19581ad6265SDimitry Andricconcept __span_array_convertible = is_convertible_v<_From(*)[], _To(*)[]>; 19681ad6265SDimitry Andric 19781ad6265SDimitry Andrictemplate <class _It, class _Tp> 19881ad6265SDimitry Andricconcept __span_compatible_iterator = contiguous_iterator<_It> && __span_array_convertible<remove_reference_t<iter_reference_t<_It>>, _Tp>; 19981ad6265SDimitry Andric 20081ad6265SDimitry Andrictemplate <class _Sentinel, class _It> 20181ad6265SDimitry Andricconcept __span_compatible_sentinel_for = sized_sentinel_for<_Sentinel, _It> && !is_convertible_v<_Sentinel, size_t>; 2020b57cec5SDimitry Andric 2030b57cec5SDimitry Andrictemplate <typename _Tp, size_t _Extent> 2040b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS span { 2050b57cec5SDimitry Andricpublic: 2060b57cec5SDimitry Andric// constants and types 2070b57cec5SDimitry Andric using element_type = _Tp; 2080b57cec5SDimitry Andric using value_type = remove_cv_t<_Tp>; 209480093f4SDimitry Andric using size_type = size_t; 2100b57cec5SDimitry Andric using difference_type = ptrdiff_t; 2110b57cec5SDimitry Andric using pointer = _Tp *; 2120b57cec5SDimitry Andric using const_pointer = const _Tp *; 2130b57cec5SDimitry Andric using reference = _Tp &; 2140b57cec5SDimitry Andric using const_reference = const _Tp &; 215*06c3fb27SDimitry Andric#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS 21681ad6265SDimitry Andric using iterator = __bounded_iter<pointer>; 217fe6060f1SDimitry Andric#else 2180b57cec5SDimitry Andric using iterator = __wrap_iter<pointer>; 219fe6060f1SDimitry Andric#endif 2200b57cec5SDimitry Andric using reverse_iterator = _VSTD::reverse_iterator<iterator>; 2210b57cec5SDimitry Andric 222480093f4SDimitry Andric static constexpr size_type extent = _Extent; 2230b57cec5SDimitry Andric 2240b57cec5SDimitry Andric// [span.cons], span constructors, copy, assignment, and destructor 22581ad6265SDimitry Andric template <size_t _Sz = _Extent> requires(_Sz == 0) 226bdd1243dSDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data_{nullptr} {} 2270b57cec5SDimitry Andric 2280b57cec5SDimitry Andric constexpr span (const span&) noexcept = default; 2290b57cec5SDimitry Andric constexpr span& operator=(const span&) noexcept = default; 2300b57cec5SDimitry Andric 23181ad6265SDimitry Andric template <__span_compatible_iterator<element_type> _It> 232349cc55cSDimitry Andric _LIBCPP_INLINE_VISIBILITY 233349cc55cSDimitry Andric constexpr explicit span(_It __first, size_type __count) 234bdd1243dSDimitry Andric : __data_{_VSTD::to_address(__first)} { 235349cc55cSDimitry Andric (void)__count; 236*06c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Extent == __count, "size mismatch in span's constructor (iterator, len)"); 237349cc55cSDimitry Andric } 2380b57cec5SDimitry Andric 23981ad6265SDimitry Andric template <__span_compatible_iterator<element_type> _It, __span_compatible_sentinel_for<_It> _End> 240349cc55cSDimitry Andric _LIBCPP_INLINE_VISIBILITY 241bdd1243dSDimitry Andric constexpr explicit span(_It __first, _End __last) : __data_{_VSTD::to_address(__first)} { 242*06c3fb27SDimitry Andric // [span.cons]/10 243*06c3fb27SDimitry Andric // Throws: When and what last - first throws. 244*06c3fb27SDimitry Andric [[maybe_unused]] auto __dist = __last - __first; 245*06c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_INPUT_RANGE(__dist >= 0, "invalid range in span's constructor (iterator, sentinel)"); 246*06c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 247*06c3fb27SDimitry Andric __dist == _Extent, "invalid range in span's constructor (iterator, sentinel): last - first != extent"); 248349cc55cSDimitry Andric } 249349cc55cSDimitry Andric 250bdd1243dSDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr span(type_identity_t<element_type> (&__arr)[_Extent]) noexcept : __data_{__arr} {} 2515ffd83dbSDimitry Andric 25281ad6265SDimitry Andric template <__span_array_convertible<element_type> _OtherElementType> 2535ffd83dbSDimitry Andric _LIBCPP_INLINE_VISIBILITY 254bdd1243dSDimitry Andric constexpr span(array<_OtherElementType, _Extent>& __arr) noexcept : __data_{__arr.data()} {} 2555ffd83dbSDimitry Andric 25681ad6265SDimitry Andric template <class _OtherElementType> 25781ad6265SDimitry Andric requires __span_array_convertible<const _OtherElementType, element_type> 2585ffd83dbSDimitry Andric _LIBCPP_INLINE_VISIBILITY 259bdd1243dSDimitry Andric constexpr span(const array<_OtherElementType, _Extent>& __arr) noexcept : __data_{__arr.data()} {} 2605ffd83dbSDimitry Andric 261349cc55cSDimitry Andric template <__span_compatible_range<element_type> _Range> 2625ffd83dbSDimitry Andric _LIBCPP_INLINE_VISIBILITY 263bdd1243dSDimitry Andric constexpr explicit span(_Range&& __r) : __data_{ranges::data(__r)} { 264*06c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 265*06c3fb27SDimitry Andric ranges::size(__r) == _Extent, "size mismatch in span's constructor (range)"); 2665ffd83dbSDimitry Andric } 2670b57cec5SDimitry Andric 26881ad6265SDimitry Andric template <__span_array_convertible<element_type> _OtherElementType> 2690b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 27081ad6265SDimitry Andric constexpr span(const span<_OtherElementType, _Extent>& __other) 271bdd1243dSDimitry Andric : __data_{__other.data()} {} 2720b57cec5SDimitry Andric 27381ad6265SDimitry Andric template <__span_array_convertible<element_type> _OtherElementType> 2740b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 27581ad6265SDimitry Andric constexpr explicit span(const span<_OtherElementType, dynamic_extent>& __other) noexcept 276*06c3fb27SDimitry Andric : __data_{__other.data()} { 277*06c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 278*06c3fb27SDimitry Andric _Extent == __other.size(), "size mismatch in span's constructor (other span)"); 279*06c3fb27SDimitry Andric } 2800b57cec5SDimitry Andric 2810b57cec5SDimitry Andric template <size_t _Count> 2820b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2830b57cec5SDimitry Andric constexpr span<element_type, _Count> first() const noexcept 2840b57cec5SDimitry Andric { 28581ad6265SDimitry Andric static_assert(_Count <= _Extent, "span<T, N>::first<Count>(): Count out of range"); 2865ffd83dbSDimitry Andric return span<element_type, _Count>{data(), _Count}; 2870b57cec5SDimitry Andric } 2880b57cec5SDimitry Andric 2890b57cec5SDimitry Andric template <size_t _Count> 2900b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2910b57cec5SDimitry Andric constexpr span<element_type, _Count> last() const noexcept 2920b57cec5SDimitry Andric { 29381ad6265SDimitry Andric static_assert(_Count <= _Extent, "span<T, N>::last<Count>(): Count out of range"); 2945ffd83dbSDimitry Andric return span<element_type, _Count>{data() + size() - _Count, _Count}; 2950b57cec5SDimitry Andric } 2960b57cec5SDimitry Andric 2970b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 298480093f4SDimitry Andric constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept 2990b57cec5SDimitry Andric { 300*06c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T, N>::first(count): count out of range"); 3010b57cec5SDimitry Andric return {data(), __count}; 3020b57cec5SDimitry Andric } 3030b57cec5SDimitry Andric 3040b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 305480093f4SDimitry Andric constexpr span<element_type, dynamic_extent> last(size_type __count) const noexcept 3060b57cec5SDimitry Andric { 307*06c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T, N>::last(count): count out of range"); 3080b57cec5SDimitry Andric return {data() + size() - __count, __count}; 3090b57cec5SDimitry Andric } 3100b57cec5SDimitry Andric 3110b57cec5SDimitry Andric template <size_t _Offset, size_t _Count = dynamic_extent> 3120b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3130b57cec5SDimitry Andric constexpr auto subspan() const noexcept 3140b57cec5SDimitry Andric -> span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset> 3150b57cec5SDimitry Andric { 31681ad6265SDimitry Andric static_assert(_Offset <= _Extent, "span<T, N>::subspan<Offset, Count>(): Offset out of range"); 31781ad6265SDimitry Andric static_assert(_Count == dynamic_extent || _Count <= _Extent - _Offset, "span<T, N>::subspan<Offset, Count>(): Offset + Count out of range"); 3185ffd83dbSDimitry Andric 3195ffd83dbSDimitry Andric using _ReturnType = span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset>; 3205ffd83dbSDimitry Andric return _ReturnType{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; 3210b57cec5SDimitry Andric } 3220b57cec5SDimitry Andric 3230b57cec5SDimitry Andric 3240b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3250b57cec5SDimitry Andric constexpr span<element_type, dynamic_extent> 326480093f4SDimitry Andric subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept 3270b57cec5SDimitry Andric { 328*06c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 329*06c3fb27SDimitry Andric __offset <= size(), "span<T, N>::subspan(offset, count): offset out of range"); 3300b57cec5SDimitry Andric if (__count == dynamic_extent) 3310b57cec5SDimitry Andric return {data() + __offset, size() - __offset}; 332*06c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 333*06c3fb27SDimitry Andric __count <= size() - __offset, "span<T, N>::subspan(offset, count): offset + count out of range"); 3340b57cec5SDimitry Andric return {data() + __offset, __count}; 3350b57cec5SDimitry Andric } 3360b57cec5SDimitry Andric 337480093f4SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr size_type size() const noexcept { return _Extent; } 338480093f4SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr size_type size_bytes() const noexcept { return _Extent * sizeof(element_type); } 339349cc55cSDimitry Andric [[nodiscard]] _LIBCPP_INLINE_VISIBILITY constexpr bool empty() const noexcept { return _Extent == 0; } 3400b57cec5SDimitry Andric 341480093f4SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr reference operator[](size_type __idx) const noexcept 3420b57cec5SDimitry Andric { 343*06c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__idx < size(), "span<T, N>::operator[](index): index out of range"); 344bdd1243dSDimitry Andric return __data_[__idx]; 3450b57cec5SDimitry Andric } 3460b57cec5SDimitry Andric 3470b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr reference front() const noexcept 3480b57cec5SDimitry Andric { 349*06c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T, N>::front() on empty span"); 350bdd1243dSDimitry Andric return __data_[0]; 3510b57cec5SDimitry Andric } 3520b57cec5SDimitry Andric 3530b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr reference back() const noexcept 3540b57cec5SDimitry Andric { 355*06c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T, N>::back() on empty span"); 356bdd1243dSDimitry Andric return __data_[size()-1]; 3570b57cec5SDimitry Andric } 3580b57cec5SDimitry Andric 359bdd1243dSDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr pointer data() const noexcept { return __data_; } 3600b57cec5SDimitry Andric 3610b57cec5SDimitry Andric// [span.iter], span iterator support 36281ad6265SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr iterator begin() const noexcept { 363*06c3fb27SDimitry Andric#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS 36481ad6265SDimitry Andric return std::__make_bounded_iter(data(), data(), data() + size()); 36581ad6265SDimitry Andric#else 366*06c3fb27SDimitry Andric return iterator(data()); 36781ad6265SDimitry Andric#endif 36881ad6265SDimitry Andric } 36981ad6265SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr iterator end() const noexcept { 370*06c3fb27SDimitry Andric#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS 37181ad6265SDimitry Andric return std::__make_bounded_iter(data() + size(), data(), data() + size()); 37281ad6265SDimitry Andric#else 373*06c3fb27SDimitry Andric return iterator(data() + size()); 37481ad6265SDimitry Andric#endif 37581ad6265SDimitry Andric } 3760b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); } 3770b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); } 3780b57cec5SDimitry Andric 3790b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY span<const byte, _Extent * sizeof(element_type)> __as_bytes() const noexcept 3805ffd83dbSDimitry Andric { return span<const byte, _Extent * sizeof(element_type)>{reinterpret_cast<const byte *>(data()), size_bytes()}; } 3810b57cec5SDimitry Andric 3820b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY span<byte, _Extent * sizeof(element_type)> __as_writable_bytes() const noexcept 3835ffd83dbSDimitry Andric { return span<byte, _Extent * sizeof(element_type)>{reinterpret_cast<byte *>(data()), size_bytes()}; } 3840b57cec5SDimitry Andric 3850b57cec5SDimitry Andricprivate: 386bdd1243dSDimitry Andric pointer __data_; 3870b57cec5SDimitry Andric}; 3880b57cec5SDimitry Andric 3890b57cec5SDimitry Andric 3900b57cec5SDimitry Andrictemplate <typename _Tp> 3910b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS span<_Tp, dynamic_extent> { 3920b57cec5SDimitry Andricpublic: 3930b57cec5SDimitry Andric// constants and types 3940b57cec5SDimitry Andric using element_type = _Tp; 3950b57cec5SDimitry Andric using value_type = remove_cv_t<_Tp>; 396480093f4SDimitry Andric using size_type = size_t; 3970b57cec5SDimitry Andric using difference_type = ptrdiff_t; 3980b57cec5SDimitry Andric using pointer = _Tp *; 3990b57cec5SDimitry Andric using const_pointer = const _Tp *; 4000b57cec5SDimitry Andric using reference = _Tp &; 4010b57cec5SDimitry Andric using const_reference = const _Tp &; 402*06c3fb27SDimitry Andric#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS 40381ad6265SDimitry Andric using iterator = __bounded_iter<pointer>; 404fe6060f1SDimitry Andric#else 4050b57cec5SDimitry Andric using iterator = __wrap_iter<pointer>; 406fe6060f1SDimitry Andric#endif 4070b57cec5SDimitry Andric using reverse_iterator = _VSTD::reverse_iterator<iterator>; 4080b57cec5SDimitry Andric 409480093f4SDimitry Andric static constexpr size_type extent = dynamic_extent; 4100b57cec5SDimitry Andric 4110b57cec5SDimitry Andric// [span.cons], span constructors, copy, assignment, and destructor 412bdd1243dSDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data_{nullptr}, __size_{0} {} 4130b57cec5SDimitry Andric 4140b57cec5SDimitry Andric constexpr span (const span&) noexcept = default; 4150b57cec5SDimitry Andric constexpr span& operator=(const span&) noexcept = default; 4160b57cec5SDimitry Andric 41781ad6265SDimitry Andric template <__span_compatible_iterator<element_type> _It> 418349cc55cSDimitry Andric _LIBCPP_INLINE_VISIBILITY 419349cc55cSDimitry Andric constexpr span(_It __first, size_type __count) 420bdd1243dSDimitry Andric : __data_{_VSTD::to_address(__first)}, __size_{__count} {} 421349cc55cSDimitry Andric 42281ad6265SDimitry Andric template <__span_compatible_iterator<element_type> _It, __span_compatible_sentinel_for<_It> _End> 423a4a491e2SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr span(_It __first, _End __last) 424bdd1243dSDimitry Andric : __data_(_VSTD::to_address(__first)), __size_(__last - __first) { 425*06c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_INPUT_RANGE( 426*06c3fb27SDimitry Andric __last - __first >= 0, "invalid range in span's constructor (iterator, sentinel)"); 427a4a491e2SDimitry Andric } 4280b57cec5SDimitry Andric 4290b57cec5SDimitry Andric template <size_t _Sz> 4300b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 431bdd1243dSDimitry Andric constexpr span(type_identity_t<element_type> (&__arr)[_Sz]) noexcept : __data_{__arr}, __size_{_Sz} {} 4320b57cec5SDimitry Andric 43381ad6265SDimitry Andric template <__span_array_convertible<element_type> _OtherElementType, size_t _Sz> 4340b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 435bdd1243dSDimitry Andric constexpr span(array<_OtherElementType, _Sz>& __arr) noexcept : __data_{__arr.data()}, __size_{_Sz} {} 4360b57cec5SDimitry Andric 43781ad6265SDimitry Andric template <class _OtherElementType, size_t _Sz> 43881ad6265SDimitry Andric requires __span_array_convertible<const _OtherElementType, element_type> 4390b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 440bdd1243dSDimitry Andric constexpr span(const array<_OtherElementType, _Sz>& __arr) noexcept : __data_{__arr.data()}, __size_{_Sz} {} 4410b57cec5SDimitry Andric 442349cc55cSDimitry Andric template <__span_compatible_range<element_type> _Range> 4430b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 444bdd1243dSDimitry Andric constexpr span(_Range&& __r) : __data_(ranges::data(__r)), __size_{ranges::size(__r)} {} 4450b57cec5SDimitry Andric 44681ad6265SDimitry Andric template <__span_array_convertible<element_type> _OtherElementType, size_t _OtherExtent> 4470b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 44881ad6265SDimitry Andric constexpr span(const span<_OtherElementType, _OtherExtent>& __other) noexcept 449bdd1243dSDimitry Andric : __data_{__other.data()}, __size_{__other.size()} {} 4500b57cec5SDimitry Andric 4510b57cec5SDimitry Andric template <size_t _Count> 4520b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 4530b57cec5SDimitry Andric constexpr span<element_type, _Count> first() const noexcept 4540b57cec5SDimitry Andric { 455*06c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count <= size(), "span<T>::first<Count>(): Count out of range"); 4565ffd83dbSDimitry Andric return span<element_type, _Count>{data(), _Count}; 4570b57cec5SDimitry Andric } 4580b57cec5SDimitry Andric 4590b57cec5SDimitry Andric template <size_t _Count> 4600b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 4610b57cec5SDimitry Andric constexpr span<element_type, _Count> last() const noexcept 4620b57cec5SDimitry Andric { 463*06c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count <= size(), "span<T>::last<Count>(): Count out of range"); 4645ffd83dbSDimitry Andric return span<element_type, _Count>{data() + size() - _Count, _Count}; 4650b57cec5SDimitry Andric } 4660b57cec5SDimitry Andric 4670b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 468480093f4SDimitry Andric constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept 4690b57cec5SDimitry Andric { 470*06c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T>::first(count): count out of range"); 4710b57cec5SDimitry Andric return {data(), __count}; 4720b57cec5SDimitry Andric } 4730b57cec5SDimitry Andric 4740b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 475480093f4SDimitry Andric constexpr span<element_type, dynamic_extent> last (size_type __count) const noexcept 4760b57cec5SDimitry Andric { 477*06c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T>::last(count): count out of range"); 4780b57cec5SDimitry Andric return {data() + size() - __count, __count}; 4790b57cec5SDimitry Andric } 4800b57cec5SDimitry Andric 4810b57cec5SDimitry Andric template <size_t _Offset, size_t _Count = dynamic_extent> 4820b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 4835ffd83dbSDimitry Andric constexpr span<element_type, _Count> subspan() const noexcept 4840b57cec5SDimitry Andric { 485*06c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 486*06c3fb27SDimitry Andric _Offset <= size(), "span<T>::subspan<Offset, Count>(): Offset out of range"); 487*06c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count == dynamic_extent || _Count <= size() - _Offset, 488*06c3fb27SDimitry Andric "span<T>::subspan<Offset, Count>(): Offset + Count out of range"); 4895ffd83dbSDimitry Andric return span<element_type, _Count>{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; 4900b57cec5SDimitry Andric } 4910b57cec5SDimitry Andric 4920b57cec5SDimitry Andric constexpr span<element_type, dynamic_extent> 4930b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 494480093f4SDimitry Andric subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept 4950b57cec5SDimitry Andric { 496*06c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__offset <= size(), "span<T>::subspan(offset, count): offset out of range"); 4970b57cec5SDimitry Andric if (__count == dynamic_extent) 4980b57cec5SDimitry Andric return {data() + __offset, size() - __offset}; 499*06c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 500*06c3fb27SDimitry Andric __count <= size() - __offset, "span<T>::subspan(offset, count): offset + count out of range"); 5010b57cec5SDimitry Andric return {data() + __offset, __count}; 5020b57cec5SDimitry Andric } 5030b57cec5SDimitry Andric 504bdd1243dSDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr size_type size() const noexcept { return __size_; } 505bdd1243dSDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr size_type size_bytes() const noexcept { return __size_ * sizeof(element_type); } 506bdd1243dSDimitry Andric [[nodiscard]] _LIBCPP_INLINE_VISIBILITY constexpr bool empty() const noexcept { return __size_ == 0; } 5070b57cec5SDimitry Andric 508480093f4SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr reference operator[](size_type __idx) const noexcept 5090b57cec5SDimitry Andric { 510*06c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__idx < size(), "span<T>::operator[](index): index out of range"); 511bdd1243dSDimitry Andric return __data_[__idx]; 5120b57cec5SDimitry Andric } 5130b57cec5SDimitry Andric 5140b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr reference front() const noexcept 5150b57cec5SDimitry Andric { 516*06c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T>::front() on empty span"); 517bdd1243dSDimitry Andric return __data_[0]; 5180b57cec5SDimitry Andric } 5190b57cec5SDimitry Andric 5200b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr reference back() const noexcept 5210b57cec5SDimitry Andric { 522*06c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T>::back() on empty span"); 523bdd1243dSDimitry Andric return __data_[size()-1]; 5240b57cec5SDimitry Andric } 5250b57cec5SDimitry Andric 5260b57cec5SDimitry Andric 527bdd1243dSDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr pointer data() const noexcept { return __data_; } 5280b57cec5SDimitry Andric 5290b57cec5SDimitry Andric// [span.iter], span iterator support 53081ad6265SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr iterator begin() const noexcept { 531*06c3fb27SDimitry Andric#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS 53281ad6265SDimitry Andric return std::__make_bounded_iter(data(), data(), data() + size()); 53381ad6265SDimitry Andric#else 534*06c3fb27SDimitry Andric return iterator(data()); 53581ad6265SDimitry Andric#endif 53681ad6265SDimitry Andric } 53781ad6265SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr iterator end() const noexcept { 538*06c3fb27SDimitry Andric#ifdef _LIBCPP_ABI_BOUNDED_ITERATORS 53981ad6265SDimitry Andric return std::__make_bounded_iter(data() + size(), data(), data() + size()); 54081ad6265SDimitry Andric#else 541*06c3fb27SDimitry Andric return iterator(data() + size()); 54281ad6265SDimitry Andric#endif 54381ad6265SDimitry Andric } 5440b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); } 5450b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); } 5460b57cec5SDimitry Andric 5470b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY span<const byte, dynamic_extent> __as_bytes() const noexcept 5480b57cec5SDimitry Andric { return {reinterpret_cast<const byte *>(data()), size_bytes()}; } 5490b57cec5SDimitry Andric 5500b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY span<byte, dynamic_extent> __as_writable_bytes() const noexcept 5510b57cec5SDimitry Andric { return {reinterpret_cast<byte *>(data()), size_bytes()}; } 5520b57cec5SDimitry Andric 5530b57cec5SDimitry Andricprivate: 554bdd1243dSDimitry Andric pointer __data_; 555bdd1243dSDimitry Andric size_type __size_; 5560b57cec5SDimitry Andric}; 5570b57cec5SDimitry Andric 558fe6060f1SDimitry Andrictemplate <class _Tp, size_t _Extent> 559fe6060f1SDimitry Andricinline constexpr bool ranges::enable_borrowed_range<span<_Tp, _Extent> > = true; 560fe6060f1SDimitry Andric 561fe6060f1SDimitry Andrictemplate <class _ElementType, size_t _Extent> 562fe6060f1SDimitry Andricinline constexpr bool ranges::enable_view<span<_ElementType, _Extent>> = true; 563fe6060f1SDimitry Andric 5640b57cec5SDimitry Andric// as_bytes & as_writable_bytes 5650b57cec5SDimitry Andrictemplate <class _Tp, size_t _Extent> 5660b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 5670b57cec5SDimitry Andricauto as_bytes(span<_Tp, _Extent> __s) noexcept 5680b57cec5SDimitry Andric{ return __s.__as_bytes(); } 5690b57cec5SDimitry Andric 57081ad6265SDimitry Andrictemplate <class _Tp, size_t _Extent> requires(!is_const_v<_Tp>) 5710b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 5720b57cec5SDimitry Andricauto as_writable_bytes(span<_Tp, _Extent> __s) noexcept 5730b57cec5SDimitry Andric{ return __s.__as_writable_bytes(); } 5740b57cec5SDimitry Andric 575*06c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 20 576349cc55cSDimitry Andrictemplate<contiguous_iterator _It, class _EndOrSize> 577349cc55cSDimitry Andric span(_It, _EndOrSize) -> span<remove_reference_t<iter_reference_t<_It>>>; 578*06c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 20 579349cc55cSDimitry Andric 5800b57cec5SDimitry Andrictemplate<class _Tp, size_t _Sz> 5810b57cec5SDimitry Andric span(_Tp (&)[_Sz]) -> span<_Tp, _Sz>; 5820b57cec5SDimitry Andric 5830b57cec5SDimitry Andrictemplate<class _Tp, size_t _Sz> 5840b57cec5SDimitry Andric span(array<_Tp, _Sz>&) -> span<_Tp, _Sz>; 5850b57cec5SDimitry Andric 5860b57cec5SDimitry Andrictemplate<class _Tp, size_t _Sz> 5870b57cec5SDimitry Andric span(const array<_Tp, _Sz>&) -> span<const _Tp, _Sz>; 5880b57cec5SDimitry Andric 589349cc55cSDimitry Andrictemplate<ranges::contiguous_range _Range> 590349cc55cSDimitry Andric span(_Range&&) -> span<remove_reference_t<ranges::range_reference_t<_Range>>>; 5910b57cec5SDimitry Andric 592*06c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 20 5930b57cec5SDimitry Andric 5940b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 5950b57cec5SDimitry Andric 596e8d8bef9SDimitry Andric_LIBCPP_POP_MACROS 597e8d8bef9SDimitry Andric 598bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 599bdd1243dSDimitry Andric# include <concepts> 600bdd1243dSDimitry Andric# include <functional> 601bdd1243dSDimitry Andric# include <iterator> 602*06c3fb27SDimitry Andric# include <type_traits> 603bdd1243dSDimitry Andric#endif 604bdd1243dSDimitry Andric 6050b57cec5SDimitry Andric#endif // _LIBCPP_SPAN 606