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; 95*1db9f3b2SDimitry Andric constexpr reference at(size_type idx) const; // since C++26 960b57cec5SDimitry Andric constexpr reference front() const; 970b57cec5SDimitry Andric constexpr reference back() const; 980b57cec5SDimitry Andric constexpr pointer data() const noexcept; 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric // [span.iterators], span iterator support 1010b57cec5SDimitry Andric constexpr iterator begin() const noexcept; 1020b57cec5SDimitry Andric constexpr iterator end() const noexcept; 1030b57cec5SDimitry Andric constexpr reverse_iterator rbegin() const noexcept; 1040b57cec5SDimitry Andric constexpr reverse_iterator rend() const noexcept; 1050b57cec5SDimitry Andric 1060b57cec5SDimitry Andricprivate: 1070b57cec5SDimitry Andric pointer data_; // exposition only 108480093f4SDimitry Andric size_type size_; // exposition only 1090b57cec5SDimitry Andric}; 1100b57cec5SDimitry Andric 111349cc55cSDimitry Andrictemplate<class It, class EndOrSize> 112349cc55cSDimitry Andric span(It, EndOrSize) -> span<remove_reference_t<iter_reference_t<_It>>>; 113349cc55cSDimitry Andric 1140b57cec5SDimitry Andrictemplate<class T, size_t N> 1150b57cec5SDimitry Andric span(T (&)[N]) -> span<T, N>; 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andrictemplate<class T, size_t N> 1180b57cec5SDimitry Andric span(array<T, N>&) -> span<T, N>; 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andrictemplate<class T, size_t N> 1210b57cec5SDimitry Andric span(const array<T, N>&) -> span<const T, N>; 1220b57cec5SDimitry Andric 123349cc55cSDimitry Andrictemplate<class R> 124349cc55cSDimitry Andric span(R&&) -> span<remove_reference_t<ranges::range_reference_t<R>>>; 1250b57cec5SDimitry Andric 1260b57cec5SDimitry Andric} // namespace std 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric*/ 1290b57cec5SDimitry Andric 13081ad6265SDimitry Andric#include <__assert> // all public C++ headers provide the assertion handler 1310b57cec5SDimitry Andric#include <__config> 13281ad6265SDimitry Andric#include <__fwd/span.h> 13381ad6265SDimitry Andric#include <__iterator/bounded_iter.h> 134349cc55cSDimitry Andric#include <__iterator/concepts.h> 13581ad6265SDimitry Andric#include <__iterator/iterator_traits.h> 136fe6060f1SDimitry Andric#include <__iterator/wrap_iter.h> 13781ad6265SDimitry Andric#include <__memory/pointer_traits.h> 138349cc55cSDimitry Andric#include <__ranges/concepts.h> 139349cc55cSDimitry Andric#include <__ranges/data.h> 140fe6060f1SDimitry Andric#include <__ranges/enable_borrowed_range.h> 141fe6060f1SDimitry Andric#include <__ranges/enable_view.h> 142349cc55cSDimitry Andric#include <__ranges/size.h> 14306c3fb27SDimitry Andric#include <__type_traits/is_convertible.h> 14406c3fb27SDimitry Andric#include <__type_traits/remove_cvref.h> 14506c3fb27SDimitry Andric#include <__type_traits/remove_reference.h> 14606c3fb27SDimitry Andric#include <__type_traits/type_identity.h> 14781ad6265SDimitry Andric#include <__utility/forward.h> 1480b57cec5SDimitry Andric#include <array> // for array 1490b57cec5SDimitry Andric#include <cstddef> // for byte 150*1db9f3b2SDimitry Andric#include <stdexcept> 151fe6060f1SDimitry Andric#include <version> 1520b57cec5SDimitry Andric 15381ad6265SDimitry Andric// standard-mandated includes 15481ad6265SDimitry Andric 15581ad6265SDimitry Andric// [iterator.range] 15681ad6265SDimitry Andric#include <__iterator/access.h> 15781ad6265SDimitry Andric#include <__iterator/data.h> 15881ad6265SDimitry Andric#include <__iterator/empty.h> 15981ad6265SDimitry Andric#include <__iterator/reverse_access.h> 16081ad6265SDimitry Andric#include <__iterator/size.h> 16181ad6265SDimitry Andric 1620b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 1630b57cec5SDimitry Andric# pragma GCC system_header 1640b57cec5SDimitry Andric#endif 1650b57cec5SDimitry Andric 166e8d8bef9SDimitry Andric_LIBCPP_PUSH_MACROS 167e8d8bef9SDimitry Andric#include <__undef_macros> 168e8d8bef9SDimitry Andric 1690b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 1700b57cec5SDimitry Andric 17106c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 20 1720b57cec5SDimitry Andric 1730b57cec5SDimitry Andrictemplate <class _Tp> 174349cc55cSDimitry Andricstruct __is_std_array : false_type {}; 1750b57cec5SDimitry Andric 1760b57cec5SDimitry Andrictemplate <class _Tp, size_t _Sz> 177349cc55cSDimitry Andricstruct __is_std_array<array<_Tp, _Sz>> : true_type {}; 1780b57cec5SDimitry Andric 1790b57cec5SDimitry Andrictemplate <class _Tp> 180349cc55cSDimitry Andricstruct __is_std_span : false_type {}; 1810b57cec5SDimitry Andric 182349cc55cSDimitry Andrictemplate <class _Tp, size_t _Sz> 183349cc55cSDimitry Andricstruct __is_std_span<span<_Tp, _Sz>> : true_type {}; 1840b57cec5SDimitry Andric 185349cc55cSDimitry Andrictemplate <class _Range, class _ElementType> 186349cc55cSDimitry Andricconcept __span_compatible_range = 1875f757f3fSDimitry Andric ranges::contiguous_range<_Range> && // 1885f757f3fSDimitry Andric ranges::sized_range<_Range> && // 1895f757f3fSDimitry Andric (ranges::borrowed_range<_Range> || is_const_v<_ElementType>)&& // 1905f757f3fSDimitry Andric !__is_std_span<remove_cvref_t<_Range>>::value && // 1915f757f3fSDimitry Andric !__is_std_array<remove_cvref_t<_Range>>::value && // 1925f757f3fSDimitry Andric !is_array_v<remove_cvref_t<_Range>> && // 193349cc55cSDimitry Andric is_convertible_v<remove_reference_t<ranges::range_reference_t<_Range>> (*)[], _ElementType (*)[]>; 19481ad6265SDimitry Andric 19581ad6265SDimitry Andrictemplate <class _From, class _To> 19681ad6265SDimitry Andricconcept __span_array_convertible = is_convertible_v<_From (*)[], _To (*)[]>; 19781ad6265SDimitry Andric 19881ad6265SDimitry Andrictemplate <class _It, class _Tp> 199cb14a3feSDimitry Andricconcept __span_compatible_iterator = 200cb14a3feSDimitry Andric contiguous_iterator<_It> && __span_array_convertible<remove_reference_t<iter_reference_t<_It>>, _Tp>; 20181ad6265SDimitry Andric 20281ad6265SDimitry Andrictemplate <class _Sentinel, class _It> 20381ad6265SDimitry Andricconcept __span_compatible_sentinel_for = sized_sentinel_for<_Sentinel, _It> && !is_convertible_v<_Sentinel, size_t>; 2040b57cec5SDimitry Andric 2050b57cec5SDimitry Andrictemplate <typename _Tp, size_t _Extent> 2060b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS span { 2070b57cec5SDimitry Andricpublic: 2080b57cec5SDimitry Andric // constants and types 2090b57cec5SDimitry Andric using element_type = _Tp; 2100b57cec5SDimitry Andric using value_type = remove_cv_t<_Tp>; 211480093f4SDimitry Andric using size_type = size_t; 2120b57cec5SDimitry Andric using difference_type = ptrdiff_t; 2130b57cec5SDimitry Andric using pointer = _Tp*; 2140b57cec5SDimitry Andric using const_pointer = const _Tp*; 2150b57cec5SDimitry Andric using reference = _Tp&; 2160b57cec5SDimitry Andric using const_reference = const _Tp&; 21706c3fb27SDimitry Andric# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS 21881ad6265SDimitry Andric using iterator = __bounded_iter<pointer>; 219fe6060f1SDimitry Andric# else 2200b57cec5SDimitry Andric using iterator = __wrap_iter<pointer>; 221fe6060f1SDimitry Andric# endif 2225f757f3fSDimitry Andric using reverse_iterator = std::reverse_iterator<iterator>; 2230b57cec5SDimitry Andric 224480093f4SDimitry Andric static constexpr size_type extent = _Extent; 2250b57cec5SDimitry Andric 2260b57cec5SDimitry Andric // [span.cons], span constructors, copy, assignment, and destructor 227cb14a3feSDimitry Andric template <size_t _Sz = _Extent> 228cb14a3feSDimitry Andric requires(_Sz == 0) 2295f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span() noexcept : __data_{nullptr} {} 2300b57cec5SDimitry Andric 2310b57cec5SDimitry Andric constexpr span(const span&) noexcept = default; 2320b57cec5SDimitry Andric constexpr span& operator=(const span&) noexcept = default; 2330b57cec5SDimitry Andric 23481ad6265SDimitry Andric template <__span_compatible_iterator<element_type> _It> 235cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit span(_It __first, size_type __count) : __data_{std::to_address(__first)} { 236349cc55cSDimitry Andric (void)__count; 23706c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Extent == __count, "size mismatch in span's constructor (iterator, len)"); 238349cc55cSDimitry Andric } 2390b57cec5SDimitry Andric 24081ad6265SDimitry Andric template <__span_compatible_iterator<element_type> _It, __span_compatible_sentinel_for<_It> _End> 241cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit span(_It __first, _End __last) : __data_{std::to_address(__first)} { 24206c3fb27SDimitry Andric // [span.cons]/10 24306c3fb27SDimitry Andric // Throws: When and what last - first throws. 24406c3fb27SDimitry Andric [[maybe_unused]] auto __dist = __last - __first; 24506c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_INPUT_RANGE(__dist >= 0, "invalid range in span's constructor (iterator, sentinel)"); 24606c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 24706c3fb27SDimitry Andric __dist == _Extent, "invalid range in span's constructor (iterator, sentinel): last - first != extent"); 248349cc55cSDimitry Andric } 249349cc55cSDimitry Andric 2505f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(type_identity_t<element_type> (&__arr)[_Extent]) noexcept : __data_{__arr} {} 2515ffd83dbSDimitry Andric 25281ad6265SDimitry Andric template <__span_array_convertible<element_type> _OtherElementType> 253cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(array<_OtherElementType, _Extent>& __arr) noexcept : __data_{__arr.data()} {} 2545ffd83dbSDimitry Andric 25581ad6265SDimitry Andric template <class _OtherElementType> 25681ad6265SDimitry Andric requires __span_array_convertible<const _OtherElementType, element_type> 257cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(const array<_OtherElementType, _Extent>& __arr) noexcept 258cb14a3feSDimitry Andric : __data_{__arr.data()} {} 2595ffd83dbSDimitry Andric 260349cc55cSDimitry Andric template <__span_compatible_range<element_type> _Range> 261cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit span(_Range&& __r) : __data_{ranges::data(__r)} { 262cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(ranges::size(__r) == _Extent, "size mismatch in span's constructor (range)"); 2635ffd83dbSDimitry Andric } 2640b57cec5SDimitry Andric 26581ad6265SDimitry Andric template <__span_array_convertible<element_type> _OtherElementType> 266cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(const span<_OtherElementType, _Extent>& __other) : __data_{__other.data()} {} 2670b57cec5SDimitry Andric 26881ad6265SDimitry Andric template <__span_array_convertible<element_type> _OtherElementType> 269cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit span(const span<_OtherElementType, dynamic_extent>& __other) noexcept 27006c3fb27SDimitry Andric : __data_{__other.data()} { 271cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Extent == __other.size(), "size mismatch in span's constructor (other span)"); 27206c3fb27SDimitry Andric } 2730b57cec5SDimitry Andric 2740b57cec5SDimitry Andric template <size_t _Count> 275cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> first() const noexcept { 27681ad6265SDimitry Andric static_assert(_Count <= _Extent, "span<T, N>::first<Count>(): Count out of range"); 2775ffd83dbSDimitry Andric return span<element_type, _Count>{data(), _Count}; 2780b57cec5SDimitry Andric } 2790b57cec5SDimitry Andric 2800b57cec5SDimitry Andric template <size_t _Count> 281cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> last() const noexcept { 28281ad6265SDimitry Andric static_assert(_Count <= _Extent, "span<T, N>::last<Count>(): Count out of range"); 2835ffd83dbSDimitry Andric return span<element_type, _Count>{data() + size() - _Count, _Count}; 2840b57cec5SDimitry Andric } 2850b57cec5SDimitry Andric 286cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept { 28706c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T, N>::first(count): count out of range"); 2880b57cec5SDimitry Andric return {data(), __count}; 2890b57cec5SDimitry Andric } 2900b57cec5SDimitry Andric 291cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> last(size_type __count) const noexcept { 29206c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T, N>::last(count): count out of range"); 2930b57cec5SDimitry Andric return {data() + size() - __count, __count}; 2940b57cec5SDimitry Andric } 2950b57cec5SDimitry Andric 2960b57cec5SDimitry Andric template <size_t _Offset, size_t _Count = dynamic_extent> 297cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto subspan() const noexcept 298cb14a3feSDimitry Andric -> span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset> { 29981ad6265SDimitry Andric static_assert(_Offset <= _Extent, "span<T, N>::subspan<Offset, Count>(): Offset out of range"); 300cb14a3feSDimitry Andric static_assert(_Count == dynamic_extent || _Count <= _Extent - _Offset, 301cb14a3feSDimitry Andric "span<T, N>::subspan<Offset, Count>(): Offset + Count out of range"); 3025ffd83dbSDimitry Andric 3035ffd83dbSDimitry Andric using _ReturnType = span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset>; 3045ffd83dbSDimitry Andric return _ReturnType{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; 3050b57cec5SDimitry Andric } 3060b57cec5SDimitry Andric 307cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> 308cb14a3feSDimitry Andric subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept { 309cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__offset <= size(), "span<T, N>::subspan(offset, count): offset out of range"); 3100b57cec5SDimitry Andric if (__count == dynamic_extent) 3110b57cec5SDimitry Andric return {data() + __offset, size() - __offset}; 31206c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 31306c3fb27SDimitry Andric __count <= size() - __offset, "span<T, N>::subspan(offset, count): offset + count out of range"); 3140b57cec5SDimitry Andric return {data() + __offset, __count}; 3150b57cec5SDimitry Andric } 3160b57cec5SDimitry Andric 3175f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr size_type size() const noexcept { return _Extent; } 3185f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr size_type size_bytes() const noexcept { return _Extent * sizeof(element_type); } 3195f757f3fSDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const noexcept { return _Extent == 0; } 3200b57cec5SDimitry Andric 321cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](size_type __idx) const noexcept { 32206c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__idx < size(), "span<T, N>::operator[](index): index out of range"); 323bdd1243dSDimitry Andric return __data_[__idx]; 3240b57cec5SDimitry Andric } 3250b57cec5SDimitry Andric 326*1db9f3b2SDimitry Andric# if _LIBCPP_STD_VER >= 26 327*1db9f3b2SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reference at(size_type __index) const { 328*1db9f3b2SDimitry Andric if (__index >= size()) 329*1db9f3b2SDimitry Andric std::__throw_out_of_range("span"); 330*1db9f3b2SDimitry Andric return __data_[__index]; 331*1db9f3b2SDimitry Andric } 332*1db9f3b2SDimitry Andric# endif 333*1db9f3b2SDimitry Andric 334cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reference front() const noexcept { 33506c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T, N>::front() on empty span"); 336bdd1243dSDimitry Andric return __data_[0]; 3370b57cec5SDimitry Andric } 3380b57cec5SDimitry Andric 339cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reference back() const noexcept { 34006c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T, N>::back() on empty span"); 341bdd1243dSDimitry Andric return __data_[size() - 1]; 3420b57cec5SDimitry Andric } 3430b57cec5SDimitry Andric 3445f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr pointer data() const noexcept { return __data_; } 3450b57cec5SDimitry Andric 3460b57cec5SDimitry Andric // [span.iter], span iterator support 3475f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() const noexcept { 34806c3fb27SDimitry Andric# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS 34981ad6265SDimitry Andric return std::__make_bounded_iter(data(), data(), data() + size()); 35081ad6265SDimitry Andric# else 35106c3fb27SDimitry Andric return iterator(data()); 35281ad6265SDimitry Andric# endif 35381ad6265SDimitry Andric } 3545f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr iterator end() const noexcept { 35506c3fb27SDimitry Andric# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS 35681ad6265SDimitry Andric return std::__make_bounded_iter(data() + size(), data(), data() + size()); 35781ad6265SDimitry Andric# else 35806c3fb27SDimitry Andric return iterator(data() + size()); 35981ad6265SDimitry Andric# endif 36081ad6265SDimitry Andric } 3615f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); } 3625f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); } 3630b57cec5SDimitry Andric 364cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI span<const byte, _Extent * sizeof(element_type)> __as_bytes() const noexcept { 365cb14a3feSDimitry Andric return span<const byte, _Extent * sizeof(element_type)>{reinterpret_cast<const byte*>(data()), size_bytes()}; 366cb14a3feSDimitry Andric } 3670b57cec5SDimitry Andric 368cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI span<byte, _Extent * sizeof(element_type)> __as_writable_bytes() const noexcept { 369cb14a3feSDimitry Andric return span<byte, _Extent * sizeof(element_type)>{reinterpret_cast<byte*>(data()), size_bytes()}; 370cb14a3feSDimitry Andric } 3710b57cec5SDimitry Andric 3720b57cec5SDimitry Andricprivate: 373bdd1243dSDimitry Andric pointer __data_; 3740b57cec5SDimitry Andric}; 3750b57cec5SDimitry Andric 3760b57cec5SDimitry Andrictemplate <typename _Tp> 3770b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS span<_Tp, dynamic_extent> { 3780b57cec5SDimitry Andricpublic: 3790b57cec5SDimitry Andric // constants and types 3800b57cec5SDimitry Andric using element_type = _Tp; 3810b57cec5SDimitry Andric using value_type = remove_cv_t<_Tp>; 382480093f4SDimitry Andric using size_type = size_t; 3830b57cec5SDimitry Andric using difference_type = ptrdiff_t; 3840b57cec5SDimitry Andric using pointer = _Tp*; 3850b57cec5SDimitry Andric using const_pointer = const _Tp*; 3860b57cec5SDimitry Andric using reference = _Tp&; 3870b57cec5SDimitry Andric using const_reference = const _Tp&; 38806c3fb27SDimitry Andric# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS 38981ad6265SDimitry Andric using iterator = __bounded_iter<pointer>; 390fe6060f1SDimitry Andric# else 3910b57cec5SDimitry Andric using iterator = __wrap_iter<pointer>; 392fe6060f1SDimitry Andric# endif 3935f757f3fSDimitry Andric using reverse_iterator = std::reverse_iterator<iterator>; 3940b57cec5SDimitry Andric 395480093f4SDimitry Andric static constexpr size_type extent = dynamic_extent; 3960b57cec5SDimitry Andric 3970b57cec5SDimitry Andric // [span.cons], span constructors, copy, assignment, and destructor 3985f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span() noexcept : __data_{nullptr}, __size_{0} {} 3990b57cec5SDimitry Andric 4000b57cec5SDimitry Andric constexpr span(const span&) noexcept = default; 4010b57cec5SDimitry Andric constexpr span& operator=(const span&) noexcept = default; 4020b57cec5SDimitry Andric 40381ad6265SDimitry Andric template <__span_compatible_iterator<element_type> _It> 404cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(_It __first, size_type __count) 4055f757f3fSDimitry Andric : __data_{std::to_address(__first)}, __size_{__count} {} 406349cc55cSDimitry Andric 40781ad6265SDimitry Andric template <__span_compatible_iterator<element_type> _It, __span_compatible_sentinel_for<_It> _End> 4085f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(_It __first, _End __last) 4095f757f3fSDimitry Andric : __data_(std::to_address(__first)), __size_(__last - __first) { 410cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_INPUT_RANGE(__last - __first >= 0, "invalid range in span's constructor (iterator, sentinel)"); 411a4a491e2SDimitry Andric } 4120b57cec5SDimitry Andric 4130b57cec5SDimitry Andric template <size_t _Sz> 414cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(type_identity_t<element_type> (&__arr)[_Sz]) noexcept 415cb14a3feSDimitry Andric : __data_{__arr}, __size_{_Sz} {} 4160b57cec5SDimitry Andric 41781ad6265SDimitry Andric template <__span_array_convertible<element_type> _OtherElementType, size_t _Sz> 418cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(array<_OtherElementType, _Sz>& __arr) noexcept 419cb14a3feSDimitry Andric : __data_{__arr.data()}, __size_{_Sz} {} 4200b57cec5SDimitry Andric 42181ad6265SDimitry Andric template <class _OtherElementType, size_t _Sz> 42281ad6265SDimitry Andric requires __span_array_convertible<const _OtherElementType, element_type> 423cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(const array<_OtherElementType, _Sz>& __arr) noexcept 424cb14a3feSDimitry Andric : __data_{__arr.data()}, __size_{_Sz} {} 4250b57cec5SDimitry Andric 426349cc55cSDimitry Andric template <__span_compatible_range<element_type> _Range> 427cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(_Range&& __r) : __data_(ranges::data(__r)), __size_{ranges::size(__r)} {} 4280b57cec5SDimitry Andric 42981ad6265SDimitry Andric template <__span_array_convertible<element_type> _OtherElementType, size_t _OtherExtent> 430cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(const span<_OtherElementType, _OtherExtent>& __other) noexcept 431bdd1243dSDimitry Andric : __data_{__other.data()}, __size_{__other.size()} {} 4320b57cec5SDimitry Andric 4330b57cec5SDimitry Andric template <size_t _Count> 434cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> first() const noexcept { 43506c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count <= size(), "span<T>::first<Count>(): Count out of range"); 4365ffd83dbSDimitry Andric return span<element_type, _Count>{data(), _Count}; 4370b57cec5SDimitry Andric } 4380b57cec5SDimitry Andric 4390b57cec5SDimitry Andric template <size_t _Count> 440cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> last() const noexcept { 44106c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count <= size(), "span<T>::last<Count>(): Count out of range"); 4425ffd83dbSDimitry Andric return span<element_type, _Count>{data() + size() - _Count, _Count}; 4430b57cec5SDimitry Andric } 4440b57cec5SDimitry Andric 445cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept { 44606c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T>::first(count): count out of range"); 4470b57cec5SDimitry Andric return {data(), __count}; 4480b57cec5SDimitry Andric } 4490b57cec5SDimitry Andric 450cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> last(size_type __count) const noexcept { 45106c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T>::last(count): count out of range"); 4520b57cec5SDimitry Andric return {data() + size() - __count, __count}; 4530b57cec5SDimitry Andric } 4540b57cec5SDimitry Andric 4550b57cec5SDimitry Andric template <size_t _Offset, size_t _Count = dynamic_extent> 456cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> subspan() const noexcept { 457cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Offset <= size(), "span<T>::subspan<Offset, Count>(): Offset out of range"); 45806c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count == dynamic_extent || _Count <= size() - _Offset, 45906c3fb27SDimitry Andric "span<T>::subspan<Offset, Count>(): Offset + Count out of range"); 4605ffd83dbSDimitry Andric return span<element_type, _Count>{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; 4610b57cec5SDimitry Andric } 4620b57cec5SDimitry Andric 463cb14a3feSDimitry Andric constexpr span<element_type, dynamic_extent> _LIBCPP_HIDE_FROM_ABI 464cb14a3feSDimitry Andric subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept { 46506c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__offset <= size(), "span<T>::subspan(offset, count): offset out of range"); 4660b57cec5SDimitry Andric if (__count == dynamic_extent) 4670b57cec5SDimitry Andric return {data() + __offset, size() - __offset}; 46806c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 46906c3fb27SDimitry Andric __count <= size() - __offset, "span<T>::subspan(offset, count): offset + count out of range"); 4700b57cec5SDimitry Andric return {data() + __offset, __count}; 4710b57cec5SDimitry Andric } 4720b57cec5SDimitry Andric 4735f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr size_type size() const noexcept { return __size_; } 4745f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr size_type size_bytes() const noexcept { return __size_ * sizeof(element_type); } 4755f757f3fSDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const noexcept { return __size_ == 0; } 4760b57cec5SDimitry Andric 477cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](size_type __idx) const noexcept { 47806c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__idx < size(), "span<T>::operator[](index): index out of range"); 479bdd1243dSDimitry Andric return __data_[__idx]; 4800b57cec5SDimitry Andric } 4810b57cec5SDimitry Andric 482*1db9f3b2SDimitry Andric# if _LIBCPP_STD_VER >= 26 483*1db9f3b2SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reference at(size_type __index) const { 484*1db9f3b2SDimitry Andric if (__index >= size()) 485*1db9f3b2SDimitry Andric std::__throw_out_of_range("span"); 486*1db9f3b2SDimitry Andric return __data_[__index]; 487*1db9f3b2SDimitry Andric } 488*1db9f3b2SDimitry Andric# endif 489*1db9f3b2SDimitry Andric 490cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reference front() const noexcept { 49106c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T>::front() on empty span"); 492bdd1243dSDimitry Andric return __data_[0]; 4930b57cec5SDimitry Andric } 4940b57cec5SDimitry Andric 495cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reference back() const noexcept { 49606c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T>::back() on empty span"); 497bdd1243dSDimitry Andric return __data_[size() - 1]; 4980b57cec5SDimitry Andric } 4990b57cec5SDimitry Andric 5005f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr pointer data() const noexcept { return __data_; } 5010b57cec5SDimitry Andric 5020b57cec5SDimitry Andric // [span.iter], span iterator support 5035f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() const noexcept { 50406c3fb27SDimitry Andric# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS 50581ad6265SDimitry Andric return std::__make_bounded_iter(data(), data(), data() + size()); 50681ad6265SDimitry Andric# else 50706c3fb27SDimitry Andric return iterator(data()); 50881ad6265SDimitry Andric# endif 50981ad6265SDimitry Andric } 5105f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr iterator end() const noexcept { 51106c3fb27SDimitry Andric# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS 51281ad6265SDimitry Andric return std::__make_bounded_iter(data() + size(), data(), data() + size()); 51381ad6265SDimitry Andric# else 51406c3fb27SDimitry Andric return iterator(data() + size()); 51581ad6265SDimitry Andric# endif 51681ad6265SDimitry Andric } 5175f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); } 5185f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); } 5190b57cec5SDimitry Andric 520cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI span<const byte, dynamic_extent> __as_bytes() const noexcept { 521cb14a3feSDimitry Andric return {reinterpret_cast<const byte*>(data()), size_bytes()}; 522cb14a3feSDimitry Andric } 5230b57cec5SDimitry Andric 524cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI span<byte, dynamic_extent> __as_writable_bytes() const noexcept { 525cb14a3feSDimitry Andric return {reinterpret_cast<byte*>(data()), size_bytes()}; 526cb14a3feSDimitry Andric } 5270b57cec5SDimitry Andric 5280b57cec5SDimitry Andricprivate: 529bdd1243dSDimitry Andric pointer __data_; 530bdd1243dSDimitry Andric size_type __size_; 5310b57cec5SDimitry Andric}; 5320b57cec5SDimitry Andric 533fe6060f1SDimitry Andrictemplate <class _Tp, size_t _Extent> 534fe6060f1SDimitry Andricinline constexpr bool ranges::enable_borrowed_range<span<_Tp, _Extent> > = true; 535fe6060f1SDimitry Andric 536fe6060f1SDimitry Andrictemplate <class _ElementType, size_t _Extent> 537fe6060f1SDimitry Andricinline constexpr bool ranges::enable_view<span<_ElementType, _Extent>> = true; 538fe6060f1SDimitry Andric 5390b57cec5SDimitry Andric// as_bytes & as_writable_bytes 5400b57cec5SDimitry Andrictemplate <class _Tp, size_t _Extent> 541cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI auto as_bytes(span<_Tp, _Extent> __s) noexcept { 542cb14a3feSDimitry Andric return __s.__as_bytes(); 543cb14a3feSDimitry Andric} 5440b57cec5SDimitry Andric 545cb14a3feSDimitry Andrictemplate <class _Tp, size_t _Extent> 546cb14a3feSDimitry Andric requires(!is_const_v<_Tp>) 547cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI auto as_writable_bytes(span<_Tp, _Extent> __s) noexcept { 548cb14a3feSDimitry Andric return __s.__as_writable_bytes(); 549cb14a3feSDimitry Andric} 5500b57cec5SDimitry Andric 55106c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 20 552349cc55cSDimitry Andrictemplate <contiguous_iterator _It, class _EndOrSize> 553349cc55cSDimitry Andricspan(_It, _EndOrSize) -> span<remove_reference_t<iter_reference_t<_It>>>; 55406c3fb27SDimitry Andric# endif // _LIBCPP_STD_VER >= 20 555349cc55cSDimitry Andric 5560b57cec5SDimitry Andrictemplate <class _Tp, size_t _Sz> 5570b57cec5SDimitry Andricspan(_Tp (&)[_Sz]) -> span<_Tp, _Sz>; 5580b57cec5SDimitry Andric 5590b57cec5SDimitry Andrictemplate <class _Tp, size_t _Sz> 5600b57cec5SDimitry Andricspan(array<_Tp, _Sz>&) -> span<_Tp, _Sz>; 5610b57cec5SDimitry Andric 5620b57cec5SDimitry Andrictemplate <class _Tp, size_t _Sz> 5630b57cec5SDimitry Andricspan(const array<_Tp, _Sz>&) -> span<const _Tp, _Sz>; 5640b57cec5SDimitry Andric 565349cc55cSDimitry Andrictemplate <ranges::contiguous_range _Range> 566349cc55cSDimitry Andricspan(_Range&&) -> span<remove_reference_t<ranges::range_reference_t<_Range>>>; 5670b57cec5SDimitry Andric 56806c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 20 5690b57cec5SDimitry Andric 5700b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 5710b57cec5SDimitry Andric 572e8d8bef9SDimitry Andric_LIBCPP_POP_MACROS 573e8d8bef9SDimitry Andric 574bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 575bdd1243dSDimitry Andric# include <concepts> 576bdd1243dSDimitry Andric# include <functional> 577bdd1243dSDimitry Andric# include <iterator> 57806c3fb27SDimitry Andric# include <type_traits> 579bdd1243dSDimitry Andric#endif 580bdd1243dSDimitry Andric 5810b57cec5SDimitry Andric#endif // _LIBCPP_SPAN 582