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> 14206c3fb27SDimitry Andric#include <__type_traits/is_convertible.h> 14306c3fb27SDimitry Andric#include <__type_traits/remove_cvref.h> 14406c3fb27SDimitry Andric#include <__type_traits/remove_reference.h> 14506c3fb27SDimitry 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 <version> 1500b57cec5SDimitry Andric 15181ad6265SDimitry Andric// standard-mandated includes 15281ad6265SDimitry Andric 15381ad6265SDimitry Andric// [iterator.range] 15481ad6265SDimitry Andric#include <__iterator/access.h> 15581ad6265SDimitry Andric#include <__iterator/data.h> 15681ad6265SDimitry Andric#include <__iterator/empty.h> 15781ad6265SDimitry Andric#include <__iterator/reverse_access.h> 15881ad6265SDimitry Andric#include <__iterator/size.h> 15981ad6265SDimitry Andric 1600b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 1610b57cec5SDimitry Andric# pragma GCC system_header 1620b57cec5SDimitry Andric#endif 1630b57cec5SDimitry Andric 164e8d8bef9SDimitry Andric_LIBCPP_PUSH_MACROS 165e8d8bef9SDimitry Andric#include <__undef_macros> 166e8d8bef9SDimitry Andric 1670b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 1680b57cec5SDimitry Andric 16906c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 20 1700b57cec5SDimitry Andric 1710b57cec5SDimitry Andrictemplate <class _Tp> 172349cc55cSDimitry Andricstruct __is_std_array : false_type {}; 1730b57cec5SDimitry Andric 1740b57cec5SDimitry Andrictemplate <class _Tp, size_t _Sz> 175349cc55cSDimitry Andricstruct __is_std_array<array<_Tp, _Sz>> : true_type {}; 1760b57cec5SDimitry Andric 1770b57cec5SDimitry Andrictemplate <class _Tp> 178349cc55cSDimitry Andricstruct __is_std_span : false_type {}; 1790b57cec5SDimitry Andric 180349cc55cSDimitry Andrictemplate <class _Tp, size_t _Sz> 181349cc55cSDimitry Andricstruct __is_std_span<span<_Tp, _Sz>> : true_type {}; 1820b57cec5SDimitry Andric 183349cc55cSDimitry Andrictemplate <class _Range, class _ElementType> 184349cc55cSDimitry Andricconcept __span_compatible_range = 1855f757f3fSDimitry Andric ranges::contiguous_range<_Range> && // 1865f757f3fSDimitry Andric ranges::sized_range<_Range> && // 1875f757f3fSDimitry Andric (ranges::borrowed_range<_Range> || is_const_v<_ElementType>)&& // 1885f757f3fSDimitry Andric !__is_std_span<remove_cvref_t<_Range>>::value && // 1895f757f3fSDimitry Andric !__is_std_array<remove_cvref_t<_Range>>::value && // 1905f757f3fSDimitry Andric !is_array_v<remove_cvref_t<_Range>> && // 191349cc55cSDimitry Andric is_convertible_v<remove_reference_t<ranges::range_reference_t<_Range>> (*)[], _ElementType (*)[]>; 19281ad6265SDimitry Andric 19381ad6265SDimitry Andrictemplate <class _From, class _To> 19481ad6265SDimitry Andricconcept __span_array_convertible = is_convertible_v<_From (*)[], _To (*)[]>; 19581ad6265SDimitry Andric 19681ad6265SDimitry Andrictemplate <class _It, class _Tp> 197*cb14a3feSDimitry Andricconcept __span_compatible_iterator = 198*cb14a3feSDimitry Andric 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&; 21506c3fb27SDimitry 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 2205f757f3fSDimitry Andric using reverse_iterator = std::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 225*cb14a3feSDimitry Andric template <size_t _Sz = _Extent> 226*cb14a3feSDimitry Andric requires(_Sz == 0) 2275f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span() noexcept : __data_{nullptr} {} 2280b57cec5SDimitry Andric 2290b57cec5SDimitry Andric constexpr span(const span&) noexcept = default; 2300b57cec5SDimitry Andric constexpr span& operator=(const span&) noexcept = default; 2310b57cec5SDimitry Andric 23281ad6265SDimitry Andric template <__span_compatible_iterator<element_type> _It> 233*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit span(_It __first, size_type __count) : __data_{std::to_address(__first)} { 234349cc55cSDimitry Andric (void)__count; 23506c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Extent == __count, "size mismatch in span's constructor (iterator, len)"); 236349cc55cSDimitry Andric } 2370b57cec5SDimitry Andric 23881ad6265SDimitry Andric template <__span_compatible_iterator<element_type> _It, __span_compatible_sentinel_for<_It> _End> 239*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit span(_It __first, _End __last) : __data_{std::to_address(__first)} { 24006c3fb27SDimitry Andric // [span.cons]/10 24106c3fb27SDimitry Andric // Throws: When and what last - first throws. 24206c3fb27SDimitry Andric [[maybe_unused]] auto __dist = __last - __first; 24306c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_INPUT_RANGE(__dist >= 0, "invalid range in span's constructor (iterator, sentinel)"); 24406c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 24506c3fb27SDimitry Andric __dist == _Extent, "invalid range in span's constructor (iterator, sentinel): last - first != extent"); 246349cc55cSDimitry Andric } 247349cc55cSDimitry Andric 2485f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(type_identity_t<element_type> (&__arr)[_Extent]) noexcept : __data_{__arr} {} 2495ffd83dbSDimitry Andric 25081ad6265SDimitry Andric template <__span_array_convertible<element_type> _OtherElementType> 251*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(array<_OtherElementType, _Extent>& __arr) noexcept : __data_{__arr.data()} {} 2525ffd83dbSDimitry Andric 25381ad6265SDimitry Andric template <class _OtherElementType> 25481ad6265SDimitry Andric requires __span_array_convertible<const _OtherElementType, element_type> 255*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(const array<_OtherElementType, _Extent>& __arr) noexcept 256*cb14a3feSDimitry Andric : __data_{__arr.data()} {} 2575ffd83dbSDimitry Andric 258349cc55cSDimitry Andric template <__span_compatible_range<element_type> _Range> 259*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit span(_Range&& __r) : __data_{ranges::data(__r)} { 260*cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(ranges::size(__r) == _Extent, "size mismatch in span's constructor (range)"); 2615ffd83dbSDimitry Andric } 2620b57cec5SDimitry Andric 26381ad6265SDimitry Andric template <__span_array_convertible<element_type> _OtherElementType> 264*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(const span<_OtherElementType, _Extent>& __other) : __data_{__other.data()} {} 2650b57cec5SDimitry Andric 26681ad6265SDimitry Andric template <__span_array_convertible<element_type> _OtherElementType> 267*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit span(const span<_OtherElementType, dynamic_extent>& __other) noexcept 26806c3fb27SDimitry Andric : __data_{__other.data()} { 269*cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Extent == __other.size(), "size mismatch in span's constructor (other span)"); 27006c3fb27SDimitry Andric } 2710b57cec5SDimitry Andric 2720b57cec5SDimitry Andric template <size_t _Count> 273*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> first() const noexcept { 27481ad6265SDimitry Andric static_assert(_Count <= _Extent, "span<T, N>::first<Count>(): Count out of range"); 2755ffd83dbSDimitry Andric return span<element_type, _Count>{data(), _Count}; 2760b57cec5SDimitry Andric } 2770b57cec5SDimitry Andric 2780b57cec5SDimitry Andric template <size_t _Count> 279*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> last() const noexcept { 28081ad6265SDimitry Andric static_assert(_Count <= _Extent, "span<T, N>::last<Count>(): Count out of range"); 2815ffd83dbSDimitry Andric return span<element_type, _Count>{data() + size() - _Count, _Count}; 2820b57cec5SDimitry Andric } 2830b57cec5SDimitry Andric 284*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept { 28506c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T, N>::first(count): count out of range"); 2860b57cec5SDimitry Andric return {data(), __count}; 2870b57cec5SDimitry Andric } 2880b57cec5SDimitry Andric 289*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> last(size_type __count) const noexcept { 29006c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T, N>::last(count): count out of range"); 2910b57cec5SDimitry Andric return {data() + size() - __count, __count}; 2920b57cec5SDimitry Andric } 2930b57cec5SDimitry Andric 2940b57cec5SDimitry Andric template <size_t _Offset, size_t _Count = dynamic_extent> 295*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto subspan() const noexcept 296*cb14a3feSDimitry Andric -> span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset> { 29781ad6265SDimitry Andric static_assert(_Offset <= _Extent, "span<T, N>::subspan<Offset, Count>(): Offset out of range"); 298*cb14a3feSDimitry Andric static_assert(_Count == dynamic_extent || _Count <= _Extent - _Offset, 299*cb14a3feSDimitry Andric "span<T, N>::subspan<Offset, Count>(): Offset + Count out of range"); 3005ffd83dbSDimitry Andric 3015ffd83dbSDimitry Andric using _ReturnType = span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset>; 3025ffd83dbSDimitry Andric return _ReturnType{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; 3030b57cec5SDimitry Andric } 3040b57cec5SDimitry Andric 305*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> 306*cb14a3feSDimitry Andric subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept { 307*cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__offset <= size(), "span<T, N>::subspan(offset, count): offset out of range"); 3080b57cec5SDimitry Andric if (__count == dynamic_extent) 3090b57cec5SDimitry Andric return {data() + __offset, size() - __offset}; 31006c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 31106c3fb27SDimitry Andric __count <= size() - __offset, "span<T, N>::subspan(offset, count): offset + count out of range"); 3120b57cec5SDimitry Andric return {data() + __offset, __count}; 3130b57cec5SDimitry Andric } 3140b57cec5SDimitry Andric 3155f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr size_type size() const noexcept { return _Extent; } 3165f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr size_type size_bytes() const noexcept { return _Extent * sizeof(element_type); } 3175f757f3fSDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const noexcept { return _Extent == 0; } 3180b57cec5SDimitry Andric 319*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](size_type __idx) const noexcept { 32006c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__idx < size(), "span<T, N>::operator[](index): index out of range"); 321bdd1243dSDimitry Andric return __data_[__idx]; 3220b57cec5SDimitry Andric } 3230b57cec5SDimitry Andric 324*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reference front() const noexcept { 32506c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T, N>::front() on empty span"); 326bdd1243dSDimitry Andric return __data_[0]; 3270b57cec5SDimitry Andric } 3280b57cec5SDimitry Andric 329*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reference back() const noexcept { 33006c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T, N>::back() on empty span"); 331bdd1243dSDimitry Andric return __data_[size() - 1]; 3320b57cec5SDimitry Andric } 3330b57cec5SDimitry Andric 3345f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr pointer data() const noexcept { return __data_; } 3350b57cec5SDimitry Andric 3360b57cec5SDimitry Andric // [span.iter], span iterator support 3375f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() const noexcept { 33806c3fb27SDimitry Andric# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS 33981ad6265SDimitry Andric return std::__make_bounded_iter(data(), data(), data() + size()); 34081ad6265SDimitry Andric# else 34106c3fb27SDimitry Andric return iterator(data()); 34281ad6265SDimitry Andric# endif 34381ad6265SDimitry Andric } 3445f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr iterator end() const noexcept { 34506c3fb27SDimitry Andric# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS 34681ad6265SDimitry Andric return std::__make_bounded_iter(data() + size(), data(), data() + size()); 34781ad6265SDimitry Andric# else 34806c3fb27SDimitry Andric return iterator(data() + size()); 34981ad6265SDimitry Andric# endif 35081ad6265SDimitry Andric } 3515f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); } 3525f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); } 3530b57cec5SDimitry Andric 354*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI span<const byte, _Extent * sizeof(element_type)> __as_bytes() const noexcept { 355*cb14a3feSDimitry Andric return span<const byte, _Extent * sizeof(element_type)>{reinterpret_cast<const byte*>(data()), size_bytes()}; 356*cb14a3feSDimitry Andric } 3570b57cec5SDimitry Andric 358*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI span<byte, _Extent * sizeof(element_type)> __as_writable_bytes() const noexcept { 359*cb14a3feSDimitry Andric return span<byte, _Extent * sizeof(element_type)>{reinterpret_cast<byte*>(data()), size_bytes()}; 360*cb14a3feSDimitry Andric } 3610b57cec5SDimitry Andric 3620b57cec5SDimitry Andricprivate: 363bdd1243dSDimitry Andric pointer __data_; 3640b57cec5SDimitry Andric}; 3650b57cec5SDimitry Andric 3660b57cec5SDimitry Andrictemplate <typename _Tp> 3670b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS span<_Tp, dynamic_extent> { 3680b57cec5SDimitry Andricpublic: 3690b57cec5SDimitry Andric // constants and types 3700b57cec5SDimitry Andric using element_type = _Tp; 3710b57cec5SDimitry Andric using value_type = remove_cv_t<_Tp>; 372480093f4SDimitry Andric using size_type = size_t; 3730b57cec5SDimitry Andric using difference_type = ptrdiff_t; 3740b57cec5SDimitry Andric using pointer = _Tp*; 3750b57cec5SDimitry Andric using const_pointer = const _Tp*; 3760b57cec5SDimitry Andric using reference = _Tp&; 3770b57cec5SDimitry Andric using const_reference = const _Tp&; 37806c3fb27SDimitry Andric# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS 37981ad6265SDimitry Andric using iterator = __bounded_iter<pointer>; 380fe6060f1SDimitry Andric# else 3810b57cec5SDimitry Andric using iterator = __wrap_iter<pointer>; 382fe6060f1SDimitry Andric# endif 3835f757f3fSDimitry Andric using reverse_iterator = std::reverse_iterator<iterator>; 3840b57cec5SDimitry Andric 385480093f4SDimitry Andric static constexpr size_type extent = dynamic_extent; 3860b57cec5SDimitry Andric 3870b57cec5SDimitry Andric // [span.cons], span constructors, copy, assignment, and destructor 3885f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span() noexcept : __data_{nullptr}, __size_{0} {} 3890b57cec5SDimitry Andric 3900b57cec5SDimitry Andric constexpr span(const span&) noexcept = default; 3910b57cec5SDimitry Andric constexpr span& operator=(const span&) noexcept = default; 3920b57cec5SDimitry Andric 39381ad6265SDimitry Andric template <__span_compatible_iterator<element_type> _It> 394*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(_It __first, size_type __count) 3955f757f3fSDimitry Andric : __data_{std::to_address(__first)}, __size_{__count} {} 396349cc55cSDimitry Andric 39781ad6265SDimitry Andric template <__span_compatible_iterator<element_type> _It, __span_compatible_sentinel_for<_It> _End> 3985f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(_It __first, _End __last) 3995f757f3fSDimitry Andric : __data_(std::to_address(__first)), __size_(__last - __first) { 400*cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_INPUT_RANGE(__last - __first >= 0, "invalid range in span's constructor (iterator, sentinel)"); 401a4a491e2SDimitry Andric } 4020b57cec5SDimitry Andric 4030b57cec5SDimitry Andric template <size_t _Sz> 404*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(type_identity_t<element_type> (&__arr)[_Sz]) noexcept 405*cb14a3feSDimitry Andric : __data_{__arr}, __size_{_Sz} {} 4060b57cec5SDimitry Andric 40781ad6265SDimitry Andric template <__span_array_convertible<element_type> _OtherElementType, size_t _Sz> 408*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(array<_OtherElementType, _Sz>& __arr) noexcept 409*cb14a3feSDimitry Andric : __data_{__arr.data()}, __size_{_Sz} {} 4100b57cec5SDimitry Andric 41181ad6265SDimitry Andric template <class _OtherElementType, size_t _Sz> 41281ad6265SDimitry Andric requires __span_array_convertible<const _OtherElementType, element_type> 413*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(const array<_OtherElementType, _Sz>& __arr) noexcept 414*cb14a3feSDimitry Andric : __data_{__arr.data()}, __size_{_Sz} {} 4150b57cec5SDimitry Andric 416349cc55cSDimitry Andric template <__span_compatible_range<element_type> _Range> 417*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(_Range&& __r) : __data_(ranges::data(__r)), __size_{ranges::size(__r)} {} 4180b57cec5SDimitry Andric 41981ad6265SDimitry Andric template <__span_array_convertible<element_type> _OtherElementType, size_t _OtherExtent> 420*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(const span<_OtherElementType, _OtherExtent>& __other) noexcept 421bdd1243dSDimitry Andric : __data_{__other.data()}, __size_{__other.size()} {} 4220b57cec5SDimitry Andric 4230b57cec5SDimitry Andric template <size_t _Count> 424*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> first() const noexcept { 42506c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count <= size(), "span<T>::first<Count>(): Count out of range"); 4265ffd83dbSDimitry Andric return span<element_type, _Count>{data(), _Count}; 4270b57cec5SDimitry Andric } 4280b57cec5SDimitry Andric 4290b57cec5SDimitry Andric template <size_t _Count> 430*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> last() const noexcept { 43106c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count <= size(), "span<T>::last<Count>(): Count out of range"); 4325ffd83dbSDimitry Andric return span<element_type, _Count>{data() + size() - _Count, _Count}; 4330b57cec5SDimitry Andric } 4340b57cec5SDimitry Andric 435*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept { 43606c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T>::first(count): count out of range"); 4370b57cec5SDimitry Andric return {data(), __count}; 4380b57cec5SDimitry Andric } 4390b57cec5SDimitry Andric 440*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> last(size_type __count) const noexcept { 44106c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T>::last(count): count out of range"); 4420b57cec5SDimitry Andric return {data() + size() - __count, __count}; 4430b57cec5SDimitry Andric } 4440b57cec5SDimitry Andric 4450b57cec5SDimitry Andric template <size_t _Offset, size_t _Count = dynamic_extent> 446*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> subspan() const noexcept { 447*cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Offset <= size(), "span<T>::subspan<Offset, Count>(): Offset out of range"); 44806c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count == dynamic_extent || _Count <= size() - _Offset, 44906c3fb27SDimitry Andric "span<T>::subspan<Offset, Count>(): Offset + Count out of range"); 4505ffd83dbSDimitry Andric return span<element_type, _Count>{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; 4510b57cec5SDimitry Andric } 4520b57cec5SDimitry Andric 453*cb14a3feSDimitry Andric constexpr span<element_type, dynamic_extent> _LIBCPP_HIDE_FROM_ABI 454*cb14a3feSDimitry Andric subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept { 45506c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__offset <= size(), "span<T>::subspan(offset, count): offset out of range"); 4560b57cec5SDimitry Andric if (__count == dynamic_extent) 4570b57cec5SDimitry Andric return {data() + __offset, size() - __offset}; 45806c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 45906c3fb27SDimitry Andric __count <= size() - __offset, "span<T>::subspan(offset, count): offset + count out of range"); 4600b57cec5SDimitry Andric return {data() + __offset, __count}; 4610b57cec5SDimitry Andric } 4620b57cec5SDimitry Andric 4635f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr size_type size() const noexcept { return __size_; } 4645f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr size_type size_bytes() const noexcept { return __size_ * sizeof(element_type); } 4655f757f3fSDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const noexcept { return __size_ == 0; } 4660b57cec5SDimitry Andric 467*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](size_type __idx) const noexcept { 46806c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__idx < size(), "span<T>::operator[](index): index out of range"); 469bdd1243dSDimitry Andric return __data_[__idx]; 4700b57cec5SDimitry Andric } 4710b57cec5SDimitry Andric 472*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reference front() const noexcept { 47306c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T>::front() on empty span"); 474bdd1243dSDimitry Andric return __data_[0]; 4750b57cec5SDimitry Andric } 4760b57cec5SDimitry Andric 477*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reference back() const noexcept { 47806c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T>::back() on empty span"); 479bdd1243dSDimitry Andric return __data_[size() - 1]; 4800b57cec5SDimitry Andric } 4810b57cec5SDimitry Andric 4825f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr pointer data() const noexcept { return __data_; } 4830b57cec5SDimitry Andric 4840b57cec5SDimitry Andric // [span.iter], span iterator support 4855f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() const noexcept { 48606c3fb27SDimitry Andric# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS 48781ad6265SDimitry Andric return std::__make_bounded_iter(data(), data(), data() + size()); 48881ad6265SDimitry Andric# else 48906c3fb27SDimitry Andric return iterator(data()); 49081ad6265SDimitry Andric# endif 49181ad6265SDimitry Andric } 4925f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr iterator end() const noexcept { 49306c3fb27SDimitry Andric# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS 49481ad6265SDimitry Andric return std::__make_bounded_iter(data() + size(), data(), data() + size()); 49581ad6265SDimitry Andric# else 49606c3fb27SDimitry Andric return iterator(data() + size()); 49781ad6265SDimitry Andric# endif 49881ad6265SDimitry Andric } 4995f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); } 5005f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); } 5010b57cec5SDimitry Andric 502*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI span<const byte, dynamic_extent> __as_bytes() const noexcept { 503*cb14a3feSDimitry Andric return {reinterpret_cast<const byte*>(data()), size_bytes()}; 504*cb14a3feSDimitry Andric } 5050b57cec5SDimitry Andric 506*cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI span<byte, dynamic_extent> __as_writable_bytes() const noexcept { 507*cb14a3feSDimitry Andric return {reinterpret_cast<byte*>(data()), size_bytes()}; 508*cb14a3feSDimitry Andric } 5090b57cec5SDimitry Andric 5100b57cec5SDimitry Andricprivate: 511bdd1243dSDimitry Andric pointer __data_; 512bdd1243dSDimitry Andric size_type __size_; 5130b57cec5SDimitry Andric}; 5140b57cec5SDimitry Andric 515fe6060f1SDimitry Andrictemplate <class _Tp, size_t _Extent> 516fe6060f1SDimitry Andricinline constexpr bool ranges::enable_borrowed_range<span<_Tp, _Extent> > = true; 517fe6060f1SDimitry Andric 518fe6060f1SDimitry Andrictemplate <class _ElementType, size_t _Extent> 519fe6060f1SDimitry Andricinline constexpr bool ranges::enable_view<span<_ElementType, _Extent>> = true; 520fe6060f1SDimitry Andric 5210b57cec5SDimitry Andric// as_bytes & as_writable_bytes 5220b57cec5SDimitry Andrictemplate <class _Tp, size_t _Extent> 523*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI auto as_bytes(span<_Tp, _Extent> __s) noexcept { 524*cb14a3feSDimitry Andric return __s.__as_bytes(); 525*cb14a3feSDimitry Andric} 5260b57cec5SDimitry Andric 527*cb14a3feSDimitry Andrictemplate <class _Tp, size_t _Extent> 528*cb14a3feSDimitry Andric requires(!is_const_v<_Tp>) 529*cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI auto as_writable_bytes(span<_Tp, _Extent> __s) noexcept { 530*cb14a3feSDimitry Andric return __s.__as_writable_bytes(); 531*cb14a3feSDimitry Andric} 5320b57cec5SDimitry Andric 53306c3fb27SDimitry Andric# if _LIBCPP_STD_VER >= 20 534349cc55cSDimitry Andrictemplate <contiguous_iterator _It, class _EndOrSize> 535349cc55cSDimitry Andricspan(_It, _EndOrSize) -> span<remove_reference_t<iter_reference_t<_It>>>; 53606c3fb27SDimitry Andric# endif // _LIBCPP_STD_VER >= 20 537349cc55cSDimitry Andric 5380b57cec5SDimitry Andrictemplate <class _Tp, size_t _Sz> 5390b57cec5SDimitry Andricspan(_Tp (&)[_Sz]) -> span<_Tp, _Sz>; 5400b57cec5SDimitry Andric 5410b57cec5SDimitry Andrictemplate <class _Tp, size_t _Sz> 5420b57cec5SDimitry Andricspan(array<_Tp, _Sz>&) -> span<_Tp, _Sz>; 5430b57cec5SDimitry Andric 5440b57cec5SDimitry Andrictemplate <class _Tp, size_t _Sz> 5450b57cec5SDimitry Andricspan(const array<_Tp, _Sz>&) -> span<const _Tp, _Sz>; 5460b57cec5SDimitry Andric 547349cc55cSDimitry Andrictemplate <ranges::contiguous_range _Range> 548349cc55cSDimitry Andricspan(_Range&&) -> span<remove_reference_t<ranges::range_reference_t<_Range>>>; 5490b57cec5SDimitry Andric 55006c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 20 5510b57cec5SDimitry Andric 5520b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 5530b57cec5SDimitry Andric 554e8d8bef9SDimitry Andric_LIBCPP_POP_MACROS 555e8d8bef9SDimitry Andric 556bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 557bdd1243dSDimitry Andric# include <concepts> 558bdd1243dSDimitry Andric# include <functional> 559bdd1243dSDimitry Andric# include <iterator> 56006c3fb27SDimitry Andric# include <type_traits> 561bdd1243dSDimitry Andric#endif 562bdd1243dSDimitry Andric 5630b57cec5SDimitry Andric#endif // _LIBCPP_SPAN 564