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); 71*7a6dacacSDimitry Andric constexpr explicit(extent != dynamic_extent) span(std::initializer_list<value_type> il); // Since C++26 720b57cec5SDimitry Andric constexpr span(const span& other) noexcept = default; 730b57cec5SDimitry Andric template <class OtherElementType, size_t OtherExtent> 745ffd83dbSDimitry Andric constexpr explicit(Extent != dynamic_extent) span(const span<OtherElementType, OtherExtent>& s) noexcept; 750b57cec5SDimitry Andric constexpr span& operator=(const span& other) noexcept = default; 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric // [span.sub], span subviews 780b57cec5SDimitry Andric template <size_t Count> 790b57cec5SDimitry Andric constexpr span<element_type, Count> first() const; 800b57cec5SDimitry Andric template <size_t Count> 810b57cec5SDimitry Andric constexpr span<element_type, Count> last() const; 820b57cec5SDimitry Andric template <size_t Offset, size_t Count = dynamic_extent> 830b57cec5SDimitry Andric constexpr span<element_type, see below> subspan() const; 840b57cec5SDimitry Andric 85480093f4SDimitry Andric constexpr span<element_type, dynamic_extent> first(size_type count) const; 86480093f4SDimitry Andric constexpr span<element_type, dynamic_extent> last(size_type count) const; 87480093f4SDimitry Andric constexpr span<element_type, dynamic_extent> subspan(size_type offset, size_type count = dynamic_extent) const; 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric // [span.obs], span observers 90480093f4SDimitry Andric constexpr size_type size() const noexcept; 91480093f4SDimitry Andric constexpr size_type size_bytes() const noexcept; 92349cc55cSDimitry Andric [[nodiscard]] constexpr bool empty() const noexcept; 930b57cec5SDimitry Andric 940b57cec5SDimitry Andric // [span.elem], span element access 95480093f4SDimitry Andric constexpr reference operator[](size_type idx) const; 961db9f3b2SDimitry Andric constexpr reference at(size_type idx) const; // since C++26 970b57cec5SDimitry Andric constexpr reference front() const; 980b57cec5SDimitry Andric constexpr reference back() const; 990b57cec5SDimitry Andric constexpr pointer data() const noexcept; 1000b57cec5SDimitry Andric 1010b57cec5SDimitry Andric // [span.iterators], span iterator support 1020b57cec5SDimitry Andric constexpr iterator begin() const noexcept; 1030b57cec5SDimitry Andric constexpr iterator end() const noexcept; 1040b57cec5SDimitry Andric constexpr reverse_iterator rbegin() const noexcept; 1050b57cec5SDimitry Andric constexpr reverse_iterator rend() const noexcept; 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andricprivate: 1080b57cec5SDimitry Andric pointer data_; // exposition only 109480093f4SDimitry Andric size_type size_; // exposition only 1100b57cec5SDimitry Andric}; 1110b57cec5SDimitry Andric 112349cc55cSDimitry Andrictemplate<class It, class EndOrSize> 113349cc55cSDimitry Andric span(It, EndOrSize) -> span<remove_reference_t<iter_reference_t<_It>>>; 114349cc55cSDimitry Andric 1150b57cec5SDimitry Andrictemplate<class T, size_t N> 1160b57cec5SDimitry Andric span(T (&)[N]) -> span<T, N>; 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andrictemplate<class T, size_t N> 1190b57cec5SDimitry Andric span(array<T, N>&) -> span<T, N>; 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andrictemplate<class T, size_t N> 1220b57cec5SDimitry Andric span(const array<T, N>&) -> span<const T, N>; 1230b57cec5SDimitry Andric 124349cc55cSDimitry Andrictemplate<class R> 125349cc55cSDimitry Andric span(R&&) -> span<remove_reference_t<ranges::range_reference_t<R>>>; 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric} // namespace std 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andric*/ 1300b57cec5SDimitry Andric 13181ad6265SDimitry Andric#include <__assert> // all public C++ headers provide the assertion handler 1320b57cec5SDimitry Andric#include <__config> 13381ad6265SDimitry Andric#include <__fwd/span.h> 13481ad6265SDimitry Andric#include <__iterator/bounded_iter.h> 135349cc55cSDimitry Andric#include <__iterator/concepts.h> 13681ad6265SDimitry Andric#include <__iterator/iterator_traits.h> 137fe6060f1SDimitry Andric#include <__iterator/wrap_iter.h> 13881ad6265SDimitry Andric#include <__memory/pointer_traits.h> 139349cc55cSDimitry Andric#include <__ranges/concepts.h> 140349cc55cSDimitry Andric#include <__ranges/data.h> 141fe6060f1SDimitry Andric#include <__ranges/enable_borrowed_range.h> 142fe6060f1SDimitry Andric#include <__ranges/enable_view.h> 143349cc55cSDimitry Andric#include <__ranges/size.h> 14406c3fb27SDimitry Andric#include <__type_traits/is_convertible.h> 14506c3fb27SDimitry Andric#include <__type_traits/remove_cvref.h> 14606c3fb27SDimitry Andric#include <__type_traits/remove_reference.h> 14706c3fb27SDimitry Andric#include <__type_traits/type_identity.h> 14881ad6265SDimitry Andric#include <__utility/forward.h> 1490b57cec5SDimitry Andric#include <array> // for array 1500b57cec5SDimitry Andric#include <cstddef> // for byte 1511db9f3b2SDimitry Andric#include <stdexcept> 152fe6060f1SDimitry Andric#include <version> 1530b57cec5SDimitry Andric 15481ad6265SDimitry Andric// standard-mandated includes 15581ad6265SDimitry Andric 15681ad6265SDimitry Andric// [iterator.range] 15781ad6265SDimitry Andric#include <__iterator/access.h> 15881ad6265SDimitry Andric#include <__iterator/data.h> 15981ad6265SDimitry Andric#include <__iterator/empty.h> 16081ad6265SDimitry Andric#include <__iterator/reverse_access.h> 16181ad6265SDimitry Andric#include <__iterator/size.h> 16281ad6265SDimitry Andric 1630b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 1640b57cec5SDimitry Andric# pragma GCC system_header 1650b57cec5SDimitry Andric#endif 1660b57cec5SDimitry Andric 167e8d8bef9SDimitry Andric_LIBCPP_PUSH_MACROS 168e8d8bef9SDimitry Andric#include <__undef_macros> 169e8d8bef9SDimitry Andric 1700b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 1710b57cec5SDimitry Andric 17206c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 20 1730b57cec5SDimitry Andric 1740b57cec5SDimitry Andrictemplate <class _Tp> 175349cc55cSDimitry Andricstruct __is_std_array : false_type {}; 1760b57cec5SDimitry Andric 1770b57cec5SDimitry Andrictemplate <class _Tp, size_t _Sz> 178349cc55cSDimitry Andricstruct __is_std_array<array<_Tp, _Sz>> : true_type {}; 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andrictemplate <class _Tp> 181349cc55cSDimitry Andricstruct __is_std_span : false_type {}; 1820b57cec5SDimitry Andric 183349cc55cSDimitry Andrictemplate <class _Tp, size_t _Sz> 184349cc55cSDimitry Andricstruct __is_std_span<span<_Tp, _Sz>> : true_type {}; 1850b57cec5SDimitry Andric 186349cc55cSDimitry Andrictemplate <class _Range, class _ElementType> 187349cc55cSDimitry Andricconcept __span_compatible_range = 1885f757f3fSDimitry Andric ranges::contiguous_range<_Range> && // 1895f757f3fSDimitry Andric ranges::sized_range<_Range> && // 1905f757f3fSDimitry Andric (ranges::borrowed_range<_Range> || is_const_v<_ElementType>)&& // 1915f757f3fSDimitry Andric !__is_std_span<remove_cvref_t<_Range>>::value && // 1925f757f3fSDimitry Andric !__is_std_array<remove_cvref_t<_Range>>::value && // 1935f757f3fSDimitry Andric !is_array_v<remove_cvref_t<_Range>> && // 194349cc55cSDimitry Andric is_convertible_v<remove_reference_t<ranges::range_reference_t<_Range>> (*)[], _ElementType (*)[]>; 19581ad6265SDimitry Andric 19681ad6265SDimitry Andrictemplate <class _From, class _To> 19781ad6265SDimitry Andricconcept __span_array_convertible = is_convertible_v<_From (*)[], _To (*)[]>; 19881ad6265SDimitry Andric 19981ad6265SDimitry Andrictemplate <class _It, class _Tp> 200cb14a3feSDimitry Andricconcept __span_compatible_iterator = 201cb14a3feSDimitry Andric contiguous_iterator<_It> && __span_array_convertible<remove_reference_t<iter_reference_t<_It>>, _Tp>; 20281ad6265SDimitry Andric 20381ad6265SDimitry Andrictemplate <class _Sentinel, class _It> 20481ad6265SDimitry Andricconcept __span_compatible_sentinel_for = sized_sentinel_for<_Sentinel, _It> && !is_convertible_v<_Sentinel, size_t>; 2050b57cec5SDimitry Andric 2060b57cec5SDimitry Andrictemplate <typename _Tp, size_t _Extent> 2070b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS span { 2080b57cec5SDimitry Andricpublic: 2090b57cec5SDimitry Andric // constants and types 2100b57cec5SDimitry Andric using element_type = _Tp; 2110b57cec5SDimitry Andric using value_type = remove_cv_t<_Tp>; 212480093f4SDimitry Andric using size_type = size_t; 2130b57cec5SDimitry Andric using difference_type = ptrdiff_t; 2140b57cec5SDimitry Andric using pointer = _Tp*; 2150b57cec5SDimitry Andric using const_pointer = const _Tp*; 2160b57cec5SDimitry Andric using reference = _Tp&; 2170b57cec5SDimitry Andric using const_reference = const _Tp&; 21806c3fb27SDimitry Andric# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS 21981ad6265SDimitry Andric using iterator = __bounded_iter<pointer>; 220fe6060f1SDimitry Andric# else 2210b57cec5SDimitry Andric using iterator = __wrap_iter<pointer>; 222fe6060f1SDimitry Andric# endif 2235f757f3fSDimitry Andric using reverse_iterator = std::reverse_iterator<iterator>; 2240b57cec5SDimitry Andric 225480093f4SDimitry Andric static constexpr size_type extent = _Extent; 2260b57cec5SDimitry Andric 2270b57cec5SDimitry Andric // [span.cons], span constructors, copy, assignment, and destructor 228cb14a3feSDimitry Andric template <size_t _Sz = _Extent> 229cb14a3feSDimitry Andric requires(_Sz == 0) 2305f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span() noexcept : __data_{nullptr} {} 2310b57cec5SDimitry Andric 232*7a6dacacSDimitry Andric# if _LIBCPP_STD_VER >= 26 233*7a6dacacSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit span(std::initializer_list<value_type> __il) 234*7a6dacacSDimitry Andric requires is_const_v<element_type> 235*7a6dacacSDimitry Andric : __data_{__il.begin()} { 236*7a6dacacSDimitry Andric _LIBCPP_ASSERT_VALID_INPUT_RANGE( 237*7a6dacacSDimitry Andric _Extent == __il.size(), "Size mismatch in span's constructor _Extent != __il.size()."); 238*7a6dacacSDimitry Andric } 239*7a6dacacSDimitry Andric# endif 240*7a6dacacSDimitry Andric 2410b57cec5SDimitry Andric constexpr span(const span&) noexcept = default; 2420b57cec5SDimitry Andric constexpr span& operator=(const span&) noexcept = default; 2430b57cec5SDimitry Andric 24481ad6265SDimitry Andric template <__span_compatible_iterator<element_type> _It> 245cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit span(_It __first, size_type __count) : __data_{std::to_address(__first)} { 246349cc55cSDimitry Andric (void)__count; 24706c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Extent == __count, "size mismatch in span's constructor (iterator, len)"); 248349cc55cSDimitry Andric } 2490b57cec5SDimitry Andric 25081ad6265SDimitry Andric template <__span_compatible_iterator<element_type> _It, __span_compatible_sentinel_for<_It> _End> 251cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit span(_It __first, _End __last) : __data_{std::to_address(__first)} { 25206c3fb27SDimitry Andric // [span.cons]/10 25306c3fb27SDimitry Andric // Throws: When and what last - first throws. 25406c3fb27SDimitry Andric [[maybe_unused]] auto __dist = __last - __first; 25506c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_INPUT_RANGE(__dist >= 0, "invalid range in span's constructor (iterator, sentinel)"); 25606c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 25706c3fb27SDimitry Andric __dist == _Extent, "invalid range in span's constructor (iterator, sentinel): last - first != extent"); 258349cc55cSDimitry Andric } 259349cc55cSDimitry Andric 2605f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(type_identity_t<element_type> (&__arr)[_Extent]) noexcept : __data_{__arr} {} 2615ffd83dbSDimitry Andric 26281ad6265SDimitry Andric template <__span_array_convertible<element_type> _OtherElementType> 263cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(array<_OtherElementType, _Extent>& __arr) noexcept : __data_{__arr.data()} {} 2645ffd83dbSDimitry Andric 26581ad6265SDimitry Andric template <class _OtherElementType> 26681ad6265SDimitry Andric requires __span_array_convertible<const _OtherElementType, element_type> 267cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(const array<_OtherElementType, _Extent>& __arr) noexcept 268cb14a3feSDimitry Andric : __data_{__arr.data()} {} 2695ffd83dbSDimitry Andric 270349cc55cSDimitry Andric template <__span_compatible_range<element_type> _Range> 271cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit span(_Range&& __r) : __data_{ranges::data(__r)} { 272cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(ranges::size(__r) == _Extent, "size mismatch in span's constructor (range)"); 2735ffd83dbSDimitry Andric } 2740b57cec5SDimitry Andric 27581ad6265SDimitry Andric template <__span_array_convertible<element_type> _OtherElementType> 276cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(const span<_OtherElementType, _Extent>& __other) : __data_{__other.data()} {} 2770b57cec5SDimitry Andric 27881ad6265SDimitry Andric template <__span_array_convertible<element_type> _OtherElementType> 279cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit span(const span<_OtherElementType, dynamic_extent>& __other) noexcept 28006c3fb27SDimitry Andric : __data_{__other.data()} { 281cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Extent == __other.size(), "size mismatch in span's constructor (other span)"); 28206c3fb27SDimitry Andric } 2830b57cec5SDimitry Andric 2840b57cec5SDimitry Andric template <size_t _Count> 285cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> first() const noexcept { 28681ad6265SDimitry Andric static_assert(_Count <= _Extent, "span<T, N>::first<Count>(): Count out of range"); 2875ffd83dbSDimitry Andric return span<element_type, _Count>{data(), _Count}; 2880b57cec5SDimitry Andric } 2890b57cec5SDimitry Andric 2900b57cec5SDimitry Andric template <size_t _Count> 291cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> last() const noexcept { 29281ad6265SDimitry Andric static_assert(_Count <= _Extent, "span<T, N>::last<Count>(): Count out of range"); 2935ffd83dbSDimitry Andric return span<element_type, _Count>{data() + size() - _Count, _Count}; 2940b57cec5SDimitry Andric } 2950b57cec5SDimitry Andric 296cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept { 29706c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T, N>::first(count): count out of range"); 2980b57cec5SDimitry Andric return {data(), __count}; 2990b57cec5SDimitry Andric } 3000b57cec5SDimitry Andric 301cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> last(size_type __count) const noexcept { 30206c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T, N>::last(count): count out of range"); 3030b57cec5SDimitry Andric return {data() + size() - __count, __count}; 3040b57cec5SDimitry Andric } 3050b57cec5SDimitry Andric 3060b57cec5SDimitry Andric template <size_t _Offset, size_t _Count = dynamic_extent> 307cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto subspan() const noexcept 308cb14a3feSDimitry Andric -> span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset> { 30981ad6265SDimitry Andric static_assert(_Offset <= _Extent, "span<T, N>::subspan<Offset, Count>(): Offset out of range"); 310cb14a3feSDimitry Andric static_assert(_Count == dynamic_extent || _Count <= _Extent - _Offset, 311cb14a3feSDimitry Andric "span<T, N>::subspan<Offset, Count>(): Offset + Count out of range"); 3125ffd83dbSDimitry Andric 3135ffd83dbSDimitry Andric using _ReturnType = span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset>; 3145ffd83dbSDimitry Andric return _ReturnType{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; 3150b57cec5SDimitry Andric } 3160b57cec5SDimitry Andric 317cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> 318cb14a3feSDimitry Andric subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept { 319cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__offset <= size(), "span<T, N>::subspan(offset, count): offset out of range"); 3200b57cec5SDimitry Andric if (__count == dynamic_extent) 3210b57cec5SDimitry Andric return {data() + __offset, size() - __offset}; 32206c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 32306c3fb27SDimitry Andric __count <= size() - __offset, "span<T, N>::subspan(offset, count): offset + count out of range"); 3240b57cec5SDimitry Andric return {data() + __offset, __count}; 3250b57cec5SDimitry Andric } 3260b57cec5SDimitry Andric 3275f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr size_type size() const noexcept { return _Extent; } 3285f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr size_type size_bytes() const noexcept { return _Extent * sizeof(element_type); } 3295f757f3fSDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const noexcept { return _Extent == 0; } 3300b57cec5SDimitry Andric 331cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](size_type __idx) const noexcept { 33206c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__idx < size(), "span<T, N>::operator[](index): index out of range"); 333bdd1243dSDimitry Andric return __data_[__idx]; 3340b57cec5SDimitry Andric } 3350b57cec5SDimitry Andric 3361db9f3b2SDimitry Andric# if _LIBCPP_STD_VER >= 26 3371db9f3b2SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reference at(size_type __index) const { 3381db9f3b2SDimitry Andric if (__index >= size()) 3391db9f3b2SDimitry Andric std::__throw_out_of_range("span"); 3401db9f3b2SDimitry Andric return __data_[__index]; 3411db9f3b2SDimitry Andric } 3421db9f3b2SDimitry Andric# endif 3431db9f3b2SDimitry Andric 344cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reference front() const noexcept { 34506c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T, N>::front() on empty span"); 346bdd1243dSDimitry Andric return __data_[0]; 3470b57cec5SDimitry Andric } 3480b57cec5SDimitry Andric 349cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reference back() const noexcept { 35006c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T, N>::back() on empty span"); 351bdd1243dSDimitry Andric return __data_[size() - 1]; 3520b57cec5SDimitry Andric } 3530b57cec5SDimitry Andric 3545f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr pointer data() const noexcept { return __data_; } 3550b57cec5SDimitry Andric 3560b57cec5SDimitry Andric // [span.iter], span iterator support 3575f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() const noexcept { 35806c3fb27SDimitry Andric# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS 35981ad6265SDimitry Andric return std::__make_bounded_iter(data(), data(), data() + size()); 36081ad6265SDimitry Andric# else 36106c3fb27SDimitry Andric return iterator(data()); 36281ad6265SDimitry Andric# endif 36381ad6265SDimitry Andric } 3645f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr iterator end() const noexcept { 36506c3fb27SDimitry Andric# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS 36681ad6265SDimitry Andric return std::__make_bounded_iter(data() + size(), data(), data() + size()); 36781ad6265SDimitry Andric# else 36806c3fb27SDimitry Andric return iterator(data() + size()); 36981ad6265SDimitry Andric# endif 37081ad6265SDimitry Andric } 3715f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); } 3725f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); } 3730b57cec5SDimitry Andric 374cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI span<const byte, _Extent * sizeof(element_type)> __as_bytes() const noexcept { 375cb14a3feSDimitry Andric return span<const byte, _Extent * sizeof(element_type)>{reinterpret_cast<const byte*>(data()), size_bytes()}; 376cb14a3feSDimitry Andric } 3770b57cec5SDimitry Andric 378cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI span<byte, _Extent * sizeof(element_type)> __as_writable_bytes() const noexcept { 379cb14a3feSDimitry Andric return span<byte, _Extent * sizeof(element_type)>{reinterpret_cast<byte*>(data()), size_bytes()}; 380cb14a3feSDimitry Andric } 3810b57cec5SDimitry Andric 3820b57cec5SDimitry Andricprivate: 383bdd1243dSDimitry Andric pointer __data_; 3840b57cec5SDimitry Andric}; 3850b57cec5SDimitry Andric 3860b57cec5SDimitry Andrictemplate <typename _Tp> 3870b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS span<_Tp, dynamic_extent> { 3880b57cec5SDimitry Andricpublic: 3890b57cec5SDimitry Andric // constants and types 3900b57cec5SDimitry Andric using element_type = _Tp; 3910b57cec5SDimitry Andric using value_type = remove_cv_t<_Tp>; 392480093f4SDimitry Andric using size_type = size_t; 3930b57cec5SDimitry Andric using difference_type = ptrdiff_t; 3940b57cec5SDimitry Andric using pointer = _Tp*; 3950b57cec5SDimitry Andric using const_pointer = const _Tp*; 3960b57cec5SDimitry Andric using reference = _Tp&; 3970b57cec5SDimitry Andric using const_reference = const _Tp&; 39806c3fb27SDimitry Andric# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS 39981ad6265SDimitry Andric using iterator = __bounded_iter<pointer>; 400fe6060f1SDimitry Andric# else 4010b57cec5SDimitry Andric using iterator = __wrap_iter<pointer>; 402fe6060f1SDimitry Andric# endif 4035f757f3fSDimitry Andric using reverse_iterator = std::reverse_iterator<iterator>; 4040b57cec5SDimitry Andric 405480093f4SDimitry Andric static constexpr size_type extent = dynamic_extent; 4060b57cec5SDimitry Andric 4070b57cec5SDimitry Andric // [span.cons], span constructors, copy, assignment, and destructor 4085f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span() noexcept : __data_{nullptr}, __size_{0} {} 4090b57cec5SDimitry Andric 410*7a6dacacSDimitry Andric# if _LIBCPP_STD_VER >= 26 411*7a6dacacSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(std::initializer_list<value_type> __il) 412*7a6dacacSDimitry Andric requires is_const_v<element_type> 413*7a6dacacSDimitry Andric : __data_{__il.begin()}, __size_{__il.size()} {} 414*7a6dacacSDimitry Andric# endif 415*7a6dacacSDimitry Andric 4160b57cec5SDimitry Andric constexpr span(const span&) noexcept = default; 4170b57cec5SDimitry Andric constexpr span& operator=(const span&) noexcept = default; 4180b57cec5SDimitry Andric 41981ad6265SDimitry Andric template <__span_compatible_iterator<element_type> _It> 420cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(_It __first, size_type __count) 4215f757f3fSDimitry Andric : __data_{std::to_address(__first)}, __size_{__count} {} 422349cc55cSDimitry Andric 42381ad6265SDimitry Andric template <__span_compatible_iterator<element_type> _It, __span_compatible_sentinel_for<_It> _End> 4245f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(_It __first, _End __last) 4255f757f3fSDimitry Andric : __data_(std::to_address(__first)), __size_(__last - __first) { 426cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_INPUT_RANGE(__last - __first >= 0, "invalid range in span's constructor (iterator, sentinel)"); 427a4a491e2SDimitry Andric } 4280b57cec5SDimitry Andric 4290b57cec5SDimitry Andric template <size_t _Sz> 430cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(type_identity_t<element_type> (&__arr)[_Sz]) noexcept 431cb14a3feSDimitry Andric : __data_{__arr}, __size_{_Sz} {} 4320b57cec5SDimitry Andric 43381ad6265SDimitry Andric template <__span_array_convertible<element_type> _OtherElementType, size_t _Sz> 434cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(array<_OtherElementType, _Sz>& __arr) noexcept 435cb14a3feSDimitry Andric : __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> 439cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(const array<_OtherElementType, _Sz>& __arr) noexcept 440cb14a3feSDimitry Andric : __data_{__arr.data()}, __size_{_Sz} {} 4410b57cec5SDimitry Andric 442349cc55cSDimitry Andric template <__span_compatible_range<element_type> _Range> 443cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(_Range&& __r) : __data_(ranges::data(__r)), __size_{ranges::size(__r)} {} 4440b57cec5SDimitry Andric 44581ad6265SDimitry Andric template <__span_array_convertible<element_type> _OtherElementType, size_t _OtherExtent> 446cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(const span<_OtherElementType, _OtherExtent>& __other) noexcept 447bdd1243dSDimitry Andric : __data_{__other.data()}, __size_{__other.size()} {} 4480b57cec5SDimitry Andric 4490b57cec5SDimitry Andric template <size_t _Count> 450cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> first() const noexcept { 45106c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count <= size(), "span<T>::first<Count>(): Count out of range"); 4525ffd83dbSDimitry Andric return span<element_type, _Count>{data(), _Count}; 4530b57cec5SDimitry Andric } 4540b57cec5SDimitry Andric 4550b57cec5SDimitry Andric template <size_t _Count> 456cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> last() const noexcept { 45706c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count <= size(), "span<T>::last<Count>(): Count out of range"); 4585ffd83dbSDimitry Andric return span<element_type, _Count>{data() + size() - _Count, _Count}; 4590b57cec5SDimitry Andric } 4600b57cec5SDimitry Andric 461cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept { 46206c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T>::first(count): count out of range"); 4630b57cec5SDimitry Andric return {data(), __count}; 4640b57cec5SDimitry Andric } 4650b57cec5SDimitry Andric 466cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> last(size_type __count) const noexcept { 46706c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T>::last(count): count out of range"); 4680b57cec5SDimitry Andric return {data() + size() - __count, __count}; 4690b57cec5SDimitry Andric } 4700b57cec5SDimitry Andric 4710b57cec5SDimitry Andric template <size_t _Offset, size_t _Count = dynamic_extent> 472cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> subspan() const noexcept { 473cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Offset <= size(), "span<T>::subspan<Offset, Count>(): Offset out of range"); 47406c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count == dynamic_extent || _Count <= size() - _Offset, 47506c3fb27SDimitry Andric "span<T>::subspan<Offset, Count>(): Offset + Count out of range"); 4765ffd83dbSDimitry Andric return span<element_type, _Count>{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; 4770b57cec5SDimitry Andric } 4780b57cec5SDimitry Andric 479cb14a3feSDimitry Andric constexpr span<element_type, dynamic_extent> _LIBCPP_HIDE_FROM_ABI 480cb14a3feSDimitry Andric subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept { 48106c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__offset <= size(), "span<T>::subspan(offset, count): offset out of range"); 4820b57cec5SDimitry Andric if (__count == dynamic_extent) 4830b57cec5SDimitry Andric return {data() + __offset, size() - __offset}; 48406c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 48506c3fb27SDimitry Andric __count <= size() - __offset, "span<T>::subspan(offset, count): offset + count out of range"); 4860b57cec5SDimitry Andric return {data() + __offset, __count}; 4870b57cec5SDimitry Andric } 4880b57cec5SDimitry Andric 4895f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr size_type size() const noexcept { return __size_; } 4905f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr size_type size_bytes() const noexcept { return __size_ * sizeof(element_type); } 4915f757f3fSDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const noexcept { return __size_ == 0; } 4920b57cec5SDimitry Andric 493cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](size_type __idx) const noexcept { 49406c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__idx < size(), "span<T>::operator[](index): index out of range"); 495bdd1243dSDimitry Andric return __data_[__idx]; 4960b57cec5SDimitry Andric } 4970b57cec5SDimitry Andric 4981db9f3b2SDimitry Andric# if _LIBCPP_STD_VER >= 26 4991db9f3b2SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reference at(size_type __index) const { 5001db9f3b2SDimitry Andric if (__index >= size()) 5011db9f3b2SDimitry Andric std::__throw_out_of_range("span"); 5021db9f3b2SDimitry Andric return __data_[__index]; 5031db9f3b2SDimitry Andric } 5041db9f3b2SDimitry Andric# endif 5051db9f3b2SDimitry Andric 506cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reference front() const noexcept { 50706c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T>::front() on empty span"); 508bdd1243dSDimitry Andric return __data_[0]; 5090b57cec5SDimitry Andric } 5100b57cec5SDimitry Andric 511cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reference back() const noexcept { 51206c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T>::back() on empty span"); 513bdd1243dSDimitry Andric return __data_[size() - 1]; 5140b57cec5SDimitry Andric } 5150b57cec5SDimitry Andric 5165f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr pointer data() const noexcept { return __data_; } 5170b57cec5SDimitry Andric 5180b57cec5SDimitry Andric // [span.iter], span iterator support 5195f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() const noexcept { 52006c3fb27SDimitry Andric# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS 52181ad6265SDimitry Andric return std::__make_bounded_iter(data(), data(), data() + size()); 52281ad6265SDimitry Andric# else 52306c3fb27SDimitry Andric return iterator(data()); 52481ad6265SDimitry Andric# endif 52581ad6265SDimitry Andric } 5265f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr iterator end() const noexcept { 52706c3fb27SDimitry Andric# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS 52881ad6265SDimitry Andric return std::__make_bounded_iter(data() + size(), data(), data() + size()); 52981ad6265SDimitry Andric# else 53006c3fb27SDimitry Andric return iterator(data() + size()); 53181ad6265SDimitry Andric# endif 53281ad6265SDimitry Andric } 5335f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); } 5345f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); } 5350b57cec5SDimitry Andric 536cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI span<const byte, dynamic_extent> __as_bytes() const noexcept { 537cb14a3feSDimitry Andric return {reinterpret_cast<const byte*>(data()), size_bytes()}; 538cb14a3feSDimitry Andric } 5390b57cec5SDimitry Andric 540cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI span<byte, dynamic_extent> __as_writable_bytes() const noexcept { 541cb14a3feSDimitry Andric return {reinterpret_cast<byte*>(data()), size_bytes()}; 542cb14a3feSDimitry Andric } 5430b57cec5SDimitry Andric 5440b57cec5SDimitry Andricprivate: 545bdd1243dSDimitry Andric pointer __data_; 546bdd1243dSDimitry Andric size_type __size_; 5470b57cec5SDimitry Andric}; 5480b57cec5SDimitry Andric 549fe6060f1SDimitry Andrictemplate <class _Tp, size_t _Extent> 550fe6060f1SDimitry Andricinline constexpr bool ranges::enable_borrowed_range<span<_Tp, _Extent> > = true; 551fe6060f1SDimitry Andric 552fe6060f1SDimitry Andrictemplate <class _ElementType, size_t _Extent> 553fe6060f1SDimitry Andricinline constexpr bool ranges::enable_view<span<_ElementType, _Extent>> = true; 554fe6060f1SDimitry Andric 5550b57cec5SDimitry Andric// as_bytes & as_writable_bytes 5560b57cec5SDimitry Andrictemplate <class _Tp, size_t _Extent> 557cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI auto as_bytes(span<_Tp, _Extent> __s) noexcept { 558cb14a3feSDimitry Andric return __s.__as_bytes(); 559cb14a3feSDimitry Andric} 5600b57cec5SDimitry Andric 561cb14a3feSDimitry Andrictemplate <class _Tp, size_t _Extent> 562cb14a3feSDimitry Andric requires(!is_const_v<_Tp>) 563cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI auto as_writable_bytes(span<_Tp, _Extent> __s) noexcept { 564cb14a3feSDimitry Andric return __s.__as_writable_bytes(); 565cb14a3feSDimitry Andric} 5660b57cec5SDimitry Andric 56706c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 20 568349cc55cSDimitry Andrictemplate <contiguous_iterator _It, class _EndOrSize> 569349cc55cSDimitry Andricspan(_It, _EndOrSize) -> span<remove_reference_t<iter_reference_t<_It>>>; 57006c3fb27SDimitry Andric# endif // _LIBCPP_STD_VER >= 20 571349cc55cSDimitry Andric 5720b57cec5SDimitry Andrictemplate <class _Tp, size_t _Sz> 5730b57cec5SDimitry Andricspan(_Tp (&)[_Sz]) -> span<_Tp, _Sz>; 5740b57cec5SDimitry Andric 5750b57cec5SDimitry Andrictemplate <class _Tp, size_t _Sz> 5760b57cec5SDimitry Andricspan(array<_Tp, _Sz>&) -> span<_Tp, _Sz>; 5770b57cec5SDimitry Andric 5780b57cec5SDimitry Andrictemplate <class _Tp, size_t _Sz> 5790b57cec5SDimitry Andricspan(const array<_Tp, _Sz>&) -> span<const _Tp, _Sz>; 5800b57cec5SDimitry Andric 581349cc55cSDimitry Andrictemplate <ranges::contiguous_range _Range> 582349cc55cSDimitry Andricspan(_Range&&) -> span<remove_reference_t<ranges::range_reference_t<_Range>>>; 5830b57cec5SDimitry Andric 58406c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 20 5850b57cec5SDimitry Andric 5860b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 5870b57cec5SDimitry Andric 588e8d8bef9SDimitry Andric_LIBCPP_POP_MACROS 589e8d8bef9SDimitry Andric 590bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 591bdd1243dSDimitry Andric# include <concepts> 592bdd1243dSDimitry Andric# include <functional> 593bdd1243dSDimitry Andric# include <iterator> 59406c3fb27SDimitry Andric# include <type_traits> 595bdd1243dSDimitry Andric#endif 596bdd1243dSDimitry Andric 5970b57cec5SDimitry Andric#endif // _LIBCPP_SPAN 598