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 210fca6ea1SDimitry Andrictemplate<class T> 220fca6ea1SDimitry Andric concept integral-constant-like = // exposition only, since C++26 230fca6ea1SDimitry Andric is_integral_v<decltype(T::value)> && 240fca6ea1SDimitry Andric !is_same_v<bool, remove_const_t<decltype(T::value)>> && 250fca6ea1SDimitry Andric convertible_to<T, decltype(T::value)> && 260fca6ea1SDimitry Andric equality_comparable_with<T, decltype(T::value)> && 270fca6ea1SDimitry Andric bool_constant<T() == T::value>::value && 280fca6ea1SDimitry Andric bool_constant<static_cast<decltype(T::value)>(T()) == T::value>::value; 290fca6ea1SDimitry Andric 300fca6ea1SDimitry Andrictemplate<class T> 310fca6ea1SDimitry Andric constexpr size_t maybe-static-ext = dynamic_extent; // exposition only, since C++26 320fca6ea1SDimitry Andrictemplate<integral-constant-like T> 330fca6ea1SDimitry Andric constexpr size_t maybe-static-ext<T> = {T::value}; 340fca6ea1SDimitry Andric 350b57cec5SDimitry Andric// [views.span], class template span 360b57cec5SDimitry Andrictemplate <class ElementType, size_t Extent = dynamic_extent> 370b57cec5SDimitry Andric class span; 380b57cec5SDimitry Andric 39fe6060f1SDimitry Andrictemplate<class ElementType, size_t Extent> 40fe6060f1SDimitry Andric inline constexpr bool ranges::enable_view<span<ElementType, Extent>> = true; 41fe6060f1SDimitry Andric 42fe6060f1SDimitry Andrictemplate<class ElementType, size_t Extent> 43fe6060f1SDimitry Andric inline constexpr bool ranges::enable_borrowed_range<span<ElementType, Extent>> = true; 44fe6060f1SDimitry Andric 450b57cec5SDimitry Andric// [span.objectrep], views of object representation 460b57cec5SDimitry Andrictemplate <class ElementType, size_t Extent> 470b57cec5SDimitry Andric span<const byte, ((Extent == dynamic_extent) ? dynamic_extent : 480b57cec5SDimitry Andric (sizeof(ElementType) * Extent))> as_bytes(span<ElementType, Extent> s) noexcept; 490b57cec5SDimitry Andric 500b57cec5SDimitry Andrictemplate <class ElementType, size_t Extent> 510b57cec5SDimitry Andric span< byte, ((Extent == dynamic_extent) ? dynamic_extent : 520b57cec5SDimitry Andric (sizeof(ElementType) * Extent))> as_writable_bytes(span<ElementType, Extent> s) noexcept; 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric 550b57cec5SDimitry Andrictemplate <class ElementType, size_t Extent = dynamic_extent> 560b57cec5SDimitry Andricclass span { 570b57cec5SDimitry Andricpublic: 580b57cec5SDimitry Andric // constants and types 590b57cec5SDimitry Andric using element_type = ElementType; 600b57cec5SDimitry Andric using value_type = remove_cv_t<ElementType>; 61480093f4SDimitry Andric using size_type = size_t; 620b57cec5SDimitry Andric using difference_type = ptrdiff_t; 630b57cec5SDimitry Andric using pointer = element_type*; 640b57cec5SDimitry Andric using const_pointer = const element_type*; 650b57cec5SDimitry Andric using reference = element_type&; 660b57cec5SDimitry Andric using const_reference = const element_type&; 670b57cec5SDimitry Andric using iterator = implementation-defined; 680b57cec5SDimitry Andric using reverse_iterator = std::reverse_iterator<iterator>; 69480093f4SDimitry Andric static constexpr size_type extent = Extent; 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric // [span.cons], span constructors, copy, assignment, and destructor 720b57cec5SDimitry Andric constexpr span() noexcept; 73349cc55cSDimitry Andric template <class It> 74349cc55cSDimitry Andric constexpr explicit(Extent != dynamic_extent) span(It first, size_type count); 75349cc55cSDimitry Andric template <class It, class End> 76349cc55cSDimitry Andric constexpr explicit(Extent != dynamic_extent) span(It first, End last); 770b57cec5SDimitry Andric template <size_t N> 78349cc55cSDimitry Andric constexpr span(type_identity_t<element_type> (&arr)[N]) noexcept; 790b57cec5SDimitry Andric template <size_t N> 800b57cec5SDimitry Andric constexpr span(array<value_type, N>& arr) noexcept; 810b57cec5SDimitry Andric template <size_t N> 820b57cec5SDimitry Andric constexpr span(const array<value_type, N>& arr) noexcept; 83349cc55cSDimitry Andric template<class R> 84349cc55cSDimitry Andric constexpr explicit(Extent != dynamic_extent) span(R&& r); 857a6dacacSDimitry Andric constexpr explicit(extent != dynamic_extent) span(std::initializer_list<value_type> il); // Since C++26 860b57cec5SDimitry Andric constexpr span(const span& other) noexcept = default; 870b57cec5SDimitry Andric template <class OtherElementType, size_t OtherExtent> 885ffd83dbSDimitry Andric constexpr explicit(Extent != dynamic_extent) span(const span<OtherElementType, OtherExtent>& s) noexcept; 890b57cec5SDimitry Andric constexpr span& operator=(const span& other) noexcept = default; 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric // [span.sub], span subviews 920b57cec5SDimitry Andric template <size_t Count> 930b57cec5SDimitry Andric constexpr span<element_type, Count> first() const; 940b57cec5SDimitry Andric template <size_t Count> 950b57cec5SDimitry Andric constexpr span<element_type, Count> last() const; 960b57cec5SDimitry Andric template <size_t Offset, size_t Count = dynamic_extent> 970b57cec5SDimitry Andric constexpr span<element_type, see below> subspan() const; 980b57cec5SDimitry Andric 99480093f4SDimitry Andric constexpr span<element_type, dynamic_extent> first(size_type count) const; 100480093f4SDimitry Andric constexpr span<element_type, dynamic_extent> last(size_type count) const; 101480093f4SDimitry Andric constexpr span<element_type, dynamic_extent> subspan(size_type offset, size_type count = dynamic_extent) const; 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andric // [span.obs], span observers 104480093f4SDimitry Andric constexpr size_type size() const noexcept; 105480093f4SDimitry Andric constexpr size_type size_bytes() const noexcept; 106349cc55cSDimitry Andric [[nodiscard]] constexpr bool empty() const noexcept; 1070b57cec5SDimitry Andric 1080b57cec5SDimitry Andric // [span.elem], span element access 109480093f4SDimitry Andric constexpr reference operator[](size_type idx) const; 1101db9f3b2SDimitry Andric constexpr reference at(size_type idx) const; // since C++26 1110b57cec5SDimitry Andric constexpr reference front() const; 1120b57cec5SDimitry Andric constexpr reference back() const; 1130b57cec5SDimitry Andric constexpr pointer data() const noexcept; 1140b57cec5SDimitry Andric 1150b57cec5SDimitry Andric // [span.iterators], span iterator support 1160b57cec5SDimitry Andric constexpr iterator begin() const noexcept; 1170b57cec5SDimitry Andric constexpr iterator end() const noexcept; 1180b57cec5SDimitry Andric constexpr reverse_iterator rbegin() const noexcept; 1190b57cec5SDimitry Andric constexpr reverse_iterator rend() const noexcept; 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andricprivate: 1220b57cec5SDimitry Andric pointer data_; // exposition only 123480093f4SDimitry Andric size_type size_; // exposition only 1240b57cec5SDimitry Andric}; 1250b57cec5SDimitry Andric 126349cc55cSDimitry Andrictemplate<class It, class EndOrSize> 1270fca6ea1SDimitry Andric span(It, EndOrSize) -> span<remove_reference_t<iter_reference_t<_It>>>; // until C++26 1280fca6ea1SDimitry Andrictemplate<class It, class EndOrSize> 1290fca6ea1SDimitry Andric span(It, EndOrSize) -> span<remove_reference_t<iter_reference_t<It>>, maybe-static-ext<EndOrSize>>; // since C++26 130349cc55cSDimitry Andric 1310b57cec5SDimitry Andrictemplate<class T, size_t N> 1320b57cec5SDimitry Andric span(T (&)[N]) -> span<T, N>; 1330b57cec5SDimitry Andric 1340b57cec5SDimitry Andrictemplate<class T, size_t N> 1350b57cec5SDimitry Andric span(array<T, N>&) -> span<T, N>; 1360b57cec5SDimitry Andric 1370b57cec5SDimitry Andrictemplate<class T, size_t N> 1380b57cec5SDimitry Andric span(const array<T, N>&) -> span<const T, N>; 1390b57cec5SDimitry Andric 140349cc55cSDimitry Andrictemplate<class R> 141349cc55cSDimitry Andric span(R&&) -> span<remove_reference_t<ranges::range_reference_t<R>>>; 1420b57cec5SDimitry Andric 1430b57cec5SDimitry Andric} // namespace std 1440b57cec5SDimitry Andric 1450b57cec5SDimitry Andric*/ 1460b57cec5SDimitry Andric 1470fca6ea1SDimitry Andric#include <__assert> 1480fca6ea1SDimitry Andric#include <__concepts/convertible_to.h> 1490fca6ea1SDimitry Andric#include <__concepts/equality_comparable.h> 1500b57cec5SDimitry Andric#include <__config> 1510fca6ea1SDimitry Andric#include <__fwd/array.h> 15281ad6265SDimitry Andric#include <__fwd/span.h> 15381ad6265SDimitry Andric#include <__iterator/bounded_iter.h> 154349cc55cSDimitry Andric#include <__iterator/concepts.h> 15581ad6265SDimitry Andric#include <__iterator/iterator_traits.h> 1560fca6ea1SDimitry Andric#include <__iterator/reverse_iterator.h> 157fe6060f1SDimitry Andric#include <__iterator/wrap_iter.h> 15881ad6265SDimitry Andric#include <__memory/pointer_traits.h> 159349cc55cSDimitry Andric#include <__ranges/concepts.h> 160349cc55cSDimitry Andric#include <__ranges/data.h> 161fe6060f1SDimitry Andric#include <__ranges/enable_borrowed_range.h> 162fe6060f1SDimitry Andric#include <__ranges/enable_view.h> 163349cc55cSDimitry Andric#include <__ranges/size.h> 1640fca6ea1SDimitry Andric#include <__type_traits/integral_constant.h> 1650fca6ea1SDimitry Andric#include <__type_traits/is_array.h> 1660fca6ea1SDimitry Andric#include <__type_traits/is_const.h> 16706c3fb27SDimitry Andric#include <__type_traits/is_convertible.h> 1680fca6ea1SDimitry Andric#include <__type_traits/is_integral.h> 1690fca6ea1SDimitry Andric#include <__type_traits/is_same.h> 1700fca6ea1SDimitry Andric#include <__type_traits/remove_const.h> 1710fca6ea1SDimitry Andric#include <__type_traits/remove_cv.h> 17206c3fb27SDimitry Andric#include <__type_traits/remove_cvref.h> 17306c3fb27SDimitry Andric#include <__type_traits/remove_reference.h> 17406c3fb27SDimitry Andric#include <__type_traits/type_identity.h> 17581ad6265SDimitry Andric#include <__utility/forward.h> 1760b57cec5SDimitry Andric#include <cstddef> // for byte 1770fca6ea1SDimitry Andric#include <initializer_list> 1781db9f3b2SDimitry Andric#include <stdexcept> 179fe6060f1SDimitry Andric#include <version> 1800b57cec5SDimitry Andric 18181ad6265SDimitry Andric// standard-mandated includes 18281ad6265SDimitry Andric 18381ad6265SDimitry Andric// [iterator.range] 18481ad6265SDimitry Andric#include <__iterator/access.h> 18581ad6265SDimitry Andric#include <__iterator/data.h> 18681ad6265SDimitry Andric#include <__iterator/empty.h> 18781ad6265SDimitry Andric#include <__iterator/reverse_access.h> 18881ad6265SDimitry Andric#include <__iterator/size.h> 18981ad6265SDimitry Andric 1900b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 1910b57cec5SDimitry Andric# pragma GCC system_header 1920b57cec5SDimitry Andric#endif 1930b57cec5SDimitry Andric 194e8d8bef9SDimitry Andric_LIBCPP_PUSH_MACROS 195e8d8bef9SDimitry Andric#include <__undef_macros> 196e8d8bef9SDimitry Andric 1970b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 1980b57cec5SDimitry Andric 19906c3fb27SDimitry Andric#if _LIBCPP_STD_VER >= 20 2000b57cec5SDimitry Andric 2010b57cec5SDimitry Andrictemplate <class _Tp> 202349cc55cSDimitry Andricstruct __is_std_span : false_type {}; 2030b57cec5SDimitry Andric 204349cc55cSDimitry Andrictemplate <class _Tp, size_t _Sz> 205349cc55cSDimitry Andricstruct __is_std_span<span<_Tp, _Sz>> : true_type {}; 2060b57cec5SDimitry Andric 207349cc55cSDimitry Andrictemplate <class _Range, class _ElementType> 208349cc55cSDimitry Andricconcept __span_compatible_range = 209*62987288SDimitry Andric !__is_std_span<remove_cvref_t<_Range>>::value && // 2105f757f3fSDimitry Andric ranges::contiguous_range<_Range> && // 2115f757f3fSDimitry Andric ranges::sized_range<_Range> && // 2125f757f3fSDimitry Andric (ranges::borrowed_range<_Range> || is_const_v<_ElementType>) && // 2135f757f3fSDimitry Andric !__is_std_array<remove_cvref_t<_Range>>::value && // 2145f757f3fSDimitry Andric !is_array_v<remove_cvref_t<_Range>> && // 215349cc55cSDimitry Andric is_convertible_v<remove_reference_t<ranges::range_reference_t<_Range>> (*)[], _ElementType (*)[]>; 21681ad6265SDimitry Andric 21781ad6265SDimitry Andrictemplate <class _From, class _To> 21881ad6265SDimitry Andricconcept __span_array_convertible = is_convertible_v<_From (*)[], _To (*)[]>; 21981ad6265SDimitry Andric 22081ad6265SDimitry Andrictemplate <class _It, class _Tp> 221cb14a3feSDimitry Andricconcept __span_compatible_iterator = 222cb14a3feSDimitry Andric contiguous_iterator<_It> && __span_array_convertible<remove_reference_t<iter_reference_t<_It>>, _Tp>; 22381ad6265SDimitry Andric 22481ad6265SDimitry Andrictemplate <class _Sentinel, class _It> 22581ad6265SDimitry Andricconcept __span_compatible_sentinel_for = sized_sentinel_for<_Sentinel, _It> && !is_convertible_v<_Sentinel, size_t>; 2260b57cec5SDimitry Andric 2270b57cec5SDimitry Andrictemplate <typename _Tp, size_t _Extent> 2280b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS span { 2290b57cec5SDimitry Andricpublic: 2300b57cec5SDimitry Andric // constants and types 2310b57cec5SDimitry Andric using element_type = _Tp; 2320b57cec5SDimitry Andric using value_type = remove_cv_t<_Tp>; 233480093f4SDimitry Andric using size_type = size_t; 2340b57cec5SDimitry Andric using difference_type = ptrdiff_t; 2350b57cec5SDimitry Andric using pointer = _Tp*; 2360b57cec5SDimitry Andric using const_pointer = const _Tp*; 2370b57cec5SDimitry Andric using reference = _Tp&; 2380b57cec5SDimitry Andric using const_reference = const _Tp&; 23906c3fb27SDimitry Andric# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS 24081ad6265SDimitry Andric using iterator = __bounded_iter<pointer>; 241fe6060f1SDimitry Andric# else 2420b57cec5SDimitry Andric using iterator = __wrap_iter<pointer>; 243fe6060f1SDimitry Andric# endif 2445f757f3fSDimitry Andric using reverse_iterator = std::reverse_iterator<iterator>; 2450b57cec5SDimitry Andric 246480093f4SDimitry Andric static constexpr size_type extent = _Extent; 2470b57cec5SDimitry Andric 2480b57cec5SDimitry Andric // [span.cons], span constructors, copy, assignment, and destructor 249cb14a3feSDimitry Andric template <size_t _Sz = _Extent> 250cb14a3feSDimitry Andric requires(_Sz == 0) 2515f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span() noexcept : __data_{nullptr} {} 2520b57cec5SDimitry Andric 2537a6dacacSDimitry Andric# if _LIBCPP_STD_VER >= 26 2547a6dacacSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit span(std::initializer_list<value_type> __il) 2557a6dacacSDimitry Andric requires is_const_v<element_type> 2567a6dacacSDimitry Andric : __data_{__il.begin()} { 2577a6dacacSDimitry Andric _LIBCPP_ASSERT_VALID_INPUT_RANGE( 2587a6dacacSDimitry Andric _Extent == __il.size(), "Size mismatch in span's constructor _Extent != __il.size()."); 2597a6dacacSDimitry Andric } 2607a6dacacSDimitry Andric# endif 2617a6dacacSDimitry Andric 2620b57cec5SDimitry Andric constexpr span(const span&) noexcept = default; 2630b57cec5SDimitry Andric constexpr span& operator=(const span&) noexcept = default; 2640b57cec5SDimitry Andric 26581ad6265SDimitry Andric template <__span_compatible_iterator<element_type> _It> 266cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit span(_It __first, size_type __count) : __data_{std::to_address(__first)} { 267349cc55cSDimitry Andric (void)__count; 26806c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Extent == __count, "size mismatch in span's constructor (iterator, len)"); 269349cc55cSDimitry Andric } 2700b57cec5SDimitry Andric 27181ad6265SDimitry Andric template <__span_compatible_iterator<element_type> _It, __span_compatible_sentinel_for<_It> _End> 272cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit span(_It __first, _End __last) : __data_{std::to_address(__first)} { 27306c3fb27SDimitry Andric // [span.cons]/10 27406c3fb27SDimitry Andric // Throws: When and what last - first throws. 27506c3fb27SDimitry Andric [[maybe_unused]] auto __dist = __last - __first; 27606c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_INPUT_RANGE(__dist >= 0, "invalid range in span's constructor (iterator, sentinel)"); 27706c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 27806c3fb27SDimitry Andric __dist == _Extent, "invalid range in span's constructor (iterator, sentinel): last - first != extent"); 279349cc55cSDimitry Andric } 280349cc55cSDimitry Andric 2815f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(type_identity_t<element_type> (&__arr)[_Extent]) noexcept : __data_{__arr} {} 2825ffd83dbSDimitry Andric 28381ad6265SDimitry Andric template <__span_array_convertible<element_type> _OtherElementType> 284cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(array<_OtherElementType, _Extent>& __arr) noexcept : __data_{__arr.data()} {} 2855ffd83dbSDimitry Andric 28681ad6265SDimitry Andric template <class _OtherElementType> 28781ad6265SDimitry Andric requires __span_array_convertible<const _OtherElementType, element_type> 288cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(const array<_OtherElementType, _Extent>& __arr) noexcept 289cb14a3feSDimitry Andric : __data_{__arr.data()} {} 2905ffd83dbSDimitry Andric 291349cc55cSDimitry Andric template <__span_compatible_range<element_type> _Range> 292cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit span(_Range&& __r) : __data_{ranges::data(__r)} { 293cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(ranges::size(__r) == _Extent, "size mismatch in span's constructor (range)"); 2945ffd83dbSDimitry Andric } 2950b57cec5SDimitry Andric 29681ad6265SDimitry Andric template <__span_array_convertible<element_type> _OtherElementType> 2970fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(const span<_OtherElementType, _Extent>& __other) noexcept 2980fca6ea1SDimitry Andric : __data_{__other.data()} {} 2990b57cec5SDimitry Andric 30081ad6265SDimitry Andric template <__span_array_convertible<element_type> _OtherElementType> 301cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr explicit span(const span<_OtherElementType, dynamic_extent>& __other) noexcept 30206c3fb27SDimitry Andric : __data_{__other.data()} { 303cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Extent == __other.size(), "size mismatch in span's constructor (other span)"); 30406c3fb27SDimitry Andric } 3050b57cec5SDimitry Andric 3060b57cec5SDimitry Andric template <size_t _Count> 307cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> first() const noexcept { 30881ad6265SDimitry Andric static_assert(_Count <= _Extent, "span<T, N>::first<Count>(): Count out of range"); 3095ffd83dbSDimitry Andric return span<element_type, _Count>{data(), _Count}; 3100b57cec5SDimitry Andric } 3110b57cec5SDimitry Andric 3120b57cec5SDimitry Andric template <size_t _Count> 313cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> last() const noexcept { 31481ad6265SDimitry Andric static_assert(_Count <= _Extent, "span<T, N>::last<Count>(): Count out of range"); 3155ffd83dbSDimitry Andric return span<element_type, _Count>{data() + size() - _Count, _Count}; 3160b57cec5SDimitry Andric } 3170b57cec5SDimitry Andric 318cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept { 31906c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T, N>::first(count): count out of range"); 3200b57cec5SDimitry Andric return {data(), __count}; 3210b57cec5SDimitry Andric } 3220b57cec5SDimitry Andric 323cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> last(size_type __count) const noexcept { 32406c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T, N>::last(count): count out of range"); 3250b57cec5SDimitry Andric return {data() + size() - __count, __count}; 3260b57cec5SDimitry Andric } 3270b57cec5SDimitry Andric 3280b57cec5SDimitry Andric template <size_t _Offset, size_t _Count = dynamic_extent> 3290fca6ea1SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr auto 3300fca6ea1SDimitry Andric subspan() const noexcept -> span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset> { 33181ad6265SDimitry Andric static_assert(_Offset <= _Extent, "span<T, N>::subspan<Offset, Count>(): Offset out of range"); 332cb14a3feSDimitry Andric static_assert(_Count == dynamic_extent || _Count <= _Extent - _Offset, 333cb14a3feSDimitry Andric "span<T, N>::subspan<Offset, Count>(): Offset + Count out of range"); 3345ffd83dbSDimitry Andric 3355ffd83dbSDimitry Andric using _ReturnType = span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset>; 3365ffd83dbSDimitry Andric return _ReturnType{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; 3370b57cec5SDimitry Andric } 3380b57cec5SDimitry Andric 339cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> 340cb14a3feSDimitry Andric subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept { 341cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__offset <= size(), "span<T, N>::subspan(offset, count): offset out of range"); 3420b57cec5SDimitry Andric if (__count == dynamic_extent) 3430b57cec5SDimitry Andric return {data() + __offset, size() - __offset}; 34406c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 34506c3fb27SDimitry Andric __count <= size() - __offset, "span<T, N>::subspan(offset, count): offset + count out of range"); 3460b57cec5SDimitry Andric return {data() + __offset, __count}; 3470b57cec5SDimitry Andric } 3480b57cec5SDimitry Andric 3495f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr size_type size() const noexcept { return _Extent; } 3505f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr size_type size_bytes() const noexcept { return _Extent * sizeof(element_type); } 3515f757f3fSDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const noexcept { return _Extent == 0; } 3520b57cec5SDimitry Andric 353cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](size_type __idx) const noexcept { 35406c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__idx < size(), "span<T, N>::operator[](index): index out of range"); 355bdd1243dSDimitry Andric return __data_[__idx]; 3560b57cec5SDimitry Andric } 3570b57cec5SDimitry Andric 3581db9f3b2SDimitry Andric# if _LIBCPP_STD_VER >= 26 3591db9f3b2SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reference at(size_type __index) const { 3601db9f3b2SDimitry Andric if (__index >= size()) 3611db9f3b2SDimitry Andric std::__throw_out_of_range("span"); 3621db9f3b2SDimitry Andric return __data_[__index]; 3631db9f3b2SDimitry Andric } 3641db9f3b2SDimitry Andric# endif 3651db9f3b2SDimitry Andric 366cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reference front() const noexcept { 36706c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T, N>::front() on empty span"); 368bdd1243dSDimitry Andric return __data_[0]; 3690b57cec5SDimitry Andric } 3700b57cec5SDimitry Andric 371cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reference back() const noexcept { 37206c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T, N>::back() on empty span"); 373bdd1243dSDimitry Andric return __data_[size() - 1]; 3740b57cec5SDimitry Andric } 3750b57cec5SDimitry Andric 3765f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr pointer data() const noexcept { return __data_; } 3770b57cec5SDimitry Andric 3780b57cec5SDimitry Andric // [span.iter], span iterator support 3795f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() const noexcept { 38006c3fb27SDimitry Andric# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS 38181ad6265SDimitry Andric return std::__make_bounded_iter(data(), data(), data() + size()); 38281ad6265SDimitry Andric# else 38306c3fb27SDimitry Andric return iterator(data()); 38481ad6265SDimitry Andric# endif 38581ad6265SDimitry Andric } 3865f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr iterator end() const noexcept { 38706c3fb27SDimitry Andric# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS 38881ad6265SDimitry Andric return std::__make_bounded_iter(data() + size(), data(), data() + size()); 38981ad6265SDimitry Andric# else 39006c3fb27SDimitry Andric return iterator(data() + size()); 39181ad6265SDimitry Andric# endif 39281ad6265SDimitry Andric } 3935f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); } 3945f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); } 3950b57cec5SDimitry Andric 396cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI span<const byte, _Extent * sizeof(element_type)> __as_bytes() const noexcept { 397cb14a3feSDimitry Andric return span<const byte, _Extent * sizeof(element_type)>{reinterpret_cast<const byte*>(data()), size_bytes()}; 398cb14a3feSDimitry Andric } 3990b57cec5SDimitry Andric 400cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI span<byte, _Extent * sizeof(element_type)> __as_writable_bytes() const noexcept { 401cb14a3feSDimitry Andric return span<byte, _Extent * sizeof(element_type)>{reinterpret_cast<byte*>(data()), size_bytes()}; 402cb14a3feSDimitry Andric } 4030b57cec5SDimitry Andric 4040b57cec5SDimitry Andricprivate: 405bdd1243dSDimitry Andric pointer __data_; 4060b57cec5SDimitry Andric}; 4070b57cec5SDimitry Andric 4080b57cec5SDimitry Andrictemplate <typename _Tp> 4090b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS span<_Tp, dynamic_extent> { 4100b57cec5SDimitry Andricpublic: 4110b57cec5SDimitry Andric // constants and types 4120b57cec5SDimitry Andric using element_type = _Tp; 4130b57cec5SDimitry Andric using value_type = remove_cv_t<_Tp>; 414480093f4SDimitry Andric using size_type = size_t; 4150b57cec5SDimitry Andric using difference_type = ptrdiff_t; 4160b57cec5SDimitry Andric using pointer = _Tp*; 4170b57cec5SDimitry Andric using const_pointer = const _Tp*; 4180b57cec5SDimitry Andric using reference = _Tp&; 4190b57cec5SDimitry Andric using const_reference = const _Tp&; 42006c3fb27SDimitry Andric# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS 42181ad6265SDimitry Andric using iterator = __bounded_iter<pointer>; 422fe6060f1SDimitry Andric# else 4230b57cec5SDimitry Andric using iterator = __wrap_iter<pointer>; 424fe6060f1SDimitry Andric# endif 4255f757f3fSDimitry Andric using reverse_iterator = std::reverse_iterator<iterator>; 4260b57cec5SDimitry Andric 427480093f4SDimitry Andric static constexpr size_type extent = dynamic_extent; 4280b57cec5SDimitry Andric 4290b57cec5SDimitry Andric // [span.cons], span constructors, copy, assignment, and destructor 4305f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span() noexcept : __data_{nullptr}, __size_{0} {} 4310b57cec5SDimitry Andric 4327a6dacacSDimitry Andric# if _LIBCPP_STD_VER >= 26 4337a6dacacSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(std::initializer_list<value_type> __il) 4347a6dacacSDimitry Andric requires is_const_v<element_type> 4357a6dacacSDimitry Andric : __data_{__il.begin()}, __size_{__il.size()} {} 4367a6dacacSDimitry Andric# endif 4377a6dacacSDimitry Andric 4380b57cec5SDimitry Andric constexpr span(const span&) noexcept = default; 4390b57cec5SDimitry Andric constexpr span& operator=(const span&) noexcept = default; 4400b57cec5SDimitry Andric 44181ad6265SDimitry Andric template <__span_compatible_iterator<element_type> _It> 442cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(_It __first, size_type __count) 4435f757f3fSDimitry Andric : __data_{std::to_address(__first)}, __size_{__count} {} 444349cc55cSDimitry Andric 44581ad6265SDimitry Andric template <__span_compatible_iterator<element_type> _It, __span_compatible_sentinel_for<_It> _End> 4465f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(_It __first, _End __last) 4475f757f3fSDimitry Andric : __data_(std::to_address(__first)), __size_(__last - __first) { 448cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_INPUT_RANGE(__last - __first >= 0, "invalid range in span's constructor (iterator, sentinel)"); 449a4a491e2SDimitry Andric } 4500b57cec5SDimitry Andric 4510b57cec5SDimitry Andric template <size_t _Sz> 452cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(type_identity_t<element_type> (&__arr)[_Sz]) noexcept 453cb14a3feSDimitry Andric : __data_{__arr}, __size_{_Sz} {} 4540b57cec5SDimitry Andric 45581ad6265SDimitry Andric template <__span_array_convertible<element_type> _OtherElementType, size_t _Sz> 456cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(array<_OtherElementType, _Sz>& __arr) noexcept 457cb14a3feSDimitry Andric : __data_{__arr.data()}, __size_{_Sz} {} 4580b57cec5SDimitry Andric 45981ad6265SDimitry Andric template <class _OtherElementType, size_t _Sz> 46081ad6265SDimitry Andric requires __span_array_convertible<const _OtherElementType, element_type> 461cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(const array<_OtherElementType, _Sz>& __arr) noexcept 462cb14a3feSDimitry Andric : __data_{__arr.data()}, __size_{_Sz} {} 4630b57cec5SDimitry Andric 464349cc55cSDimitry Andric template <__span_compatible_range<element_type> _Range> 465cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(_Range&& __r) : __data_(ranges::data(__r)), __size_{ranges::size(__r)} {} 4660b57cec5SDimitry Andric 46781ad6265SDimitry Andric template <__span_array_convertible<element_type> _OtherElementType, size_t _OtherExtent> 468cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span(const span<_OtherElementType, _OtherExtent>& __other) noexcept 469bdd1243dSDimitry Andric : __data_{__other.data()}, __size_{__other.size()} {} 4700b57cec5SDimitry Andric 4710b57cec5SDimitry Andric template <size_t _Count> 472cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> first() const noexcept { 47306c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count <= size(), "span<T>::first<Count>(): Count out of range"); 4745ffd83dbSDimitry Andric return span<element_type, _Count>{data(), _Count}; 4750b57cec5SDimitry Andric } 4760b57cec5SDimitry Andric 4770b57cec5SDimitry Andric template <size_t _Count> 478cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> last() const noexcept { 47906c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count <= size(), "span<T>::last<Count>(): Count out of range"); 4805ffd83dbSDimitry Andric return span<element_type, _Count>{data() + size() - _Count, _Count}; 4810b57cec5SDimitry Andric } 4820b57cec5SDimitry Andric 483cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept { 48406c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T>::first(count): count out of range"); 4850b57cec5SDimitry Andric return {data(), __count}; 4860b57cec5SDimitry Andric } 4870b57cec5SDimitry Andric 488cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, dynamic_extent> last(size_type __count) const noexcept { 48906c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__count <= size(), "span<T>::last(count): count out of range"); 4900b57cec5SDimitry Andric return {data() + size() - __count, __count}; 4910b57cec5SDimitry Andric } 4920b57cec5SDimitry Andric 4930b57cec5SDimitry Andric template <size_t _Offset, size_t _Count = dynamic_extent> 494cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr span<element_type, _Count> subspan() const noexcept { 495cb14a3feSDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Offset <= size(), "span<T>::subspan<Offset, Count>(): Offset out of range"); 49606c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Count == dynamic_extent || _Count <= size() - _Offset, 49706c3fb27SDimitry Andric "span<T>::subspan<Offset, Count>(): Offset + Count out of range"); 4985ffd83dbSDimitry Andric return span<element_type, _Count>{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; 4990b57cec5SDimitry Andric } 5000b57cec5SDimitry Andric 501cb14a3feSDimitry Andric constexpr span<element_type, dynamic_extent> _LIBCPP_HIDE_FROM_ABI 502cb14a3feSDimitry Andric subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept { 50306c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__offset <= size(), "span<T>::subspan(offset, count): offset out of range"); 5040b57cec5SDimitry Andric if (__count == dynamic_extent) 5050b57cec5SDimitry Andric return {data() + __offset, size() - __offset}; 50606c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS( 50706c3fb27SDimitry Andric __count <= size() - __offset, "span<T>::subspan(offset, count): offset + count out of range"); 5080b57cec5SDimitry Andric return {data() + __offset, __count}; 5090b57cec5SDimitry Andric } 5100b57cec5SDimitry Andric 5115f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr size_type size() const noexcept { return __size_; } 5125f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr size_type size_bytes() const noexcept { return __size_ * sizeof(element_type); } 5135f757f3fSDimitry Andric [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr bool empty() const noexcept { return __size_ == 0; } 5140b57cec5SDimitry Andric 515cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reference operator[](size_type __idx) const noexcept { 51606c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__idx < size(), "span<T>::operator[](index): index out of range"); 517bdd1243dSDimitry Andric return __data_[__idx]; 5180b57cec5SDimitry Andric } 5190b57cec5SDimitry Andric 5201db9f3b2SDimitry Andric# if _LIBCPP_STD_VER >= 26 5211db9f3b2SDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reference at(size_type __index) const { 5221db9f3b2SDimitry Andric if (__index >= size()) 5231db9f3b2SDimitry Andric std::__throw_out_of_range("span"); 5241db9f3b2SDimitry Andric return __data_[__index]; 5251db9f3b2SDimitry Andric } 5261db9f3b2SDimitry Andric# endif 5271db9f3b2SDimitry Andric 528cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reference front() const noexcept { 52906c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T>::front() on empty span"); 530bdd1243dSDimitry Andric return __data_[0]; 5310b57cec5SDimitry Andric } 5320b57cec5SDimitry Andric 533cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reference back() const noexcept { 53406c3fb27SDimitry Andric _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span<T>::back() on empty span"); 535bdd1243dSDimitry Andric return __data_[size() - 1]; 5360b57cec5SDimitry Andric } 5370b57cec5SDimitry Andric 5385f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr pointer data() const noexcept { return __data_; } 5390b57cec5SDimitry Andric 5400b57cec5SDimitry Andric // [span.iter], span iterator support 5415f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr iterator begin() const noexcept { 54206c3fb27SDimitry Andric# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS 54381ad6265SDimitry Andric return std::__make_bounded_iter(data(), data(), data() + size()); 54481ad6265SDimitry Andric# else 54506c3fb27SDimitry Andric return iterator(data()); 54681ad6265SDimitry Andric# endif 54781ad6265SDimitry Andric } 5485f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr iterator end() const noexcept { 54906c3fb27SDimitry Andric# ifdef _LIBCPP_ABI_BOUNDED_ITERATORS 55081ad6265SDimitry Andric return std::__make_bounded_iter(data() + size(), data(), data() + size()); 55181ad6265SDimitry Andric# else 55206c3fb27SDimitry Andric return iterator(data() + size()); 55381ad6265SDimitry Andric# endif 55481ad6265SDimitry Andric } 5555f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); } 5565f757f3fSDimitry Andric _LIBCPP_HIDE_FROM_ABI constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); } 5570b57cec5SDimitry Andric 558cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI span<const byte, dynamic_extent> __as_bytes() const noexcept { 559cb14a3feSDimitry Andric return {reinterpret_cast<const byte*>(data()), size_bytes()}; 560cb14a3feSDimitry Andric } 5610b57cec5SDimitry Andric 562cb14a3feSDimitry Andric _LIBCPP_HIDE_FROM_ABI span<byte, dynamic_extent> __as_writable_bytes() const noexcept { 563cb14a3feSDimitry Andric return {reinterpret_cast<byte*>(data()), size_bytes()}; 564cb14a3feSDimitry Andric } 5650b57cec5SDimitry Andric 5660b57cec5SDimitry Andricprivate: 567bdd1243dSDimitry Andric pointer __data_; 568bdd1243dSDimitry Andric size_type __size_; 5690b57cec5SDimitry Andric}; 5700b57cec5SDimitry Andric 571fe6060f1SDimitry Andrictemplate <class _Tp, size_t _Extent> 572fe6060f1SDimitry Andricinline constexpr bool ranges::enable_borrowed_range<span<_Tp, _Extent> > = true; 573fe6060f1SDimitry Andric 574fe6060f1SDimitry Andrictemplate <class _ElementType, size_t _Extent> 575fe6060f1SDimitry Andricinline constexpr bool ranges::enable_view<span<_ElementType, _Extent>> = true; 576fe6060f1SDimitry Andric 5770b57cec5SDimitry Andric// as_bytes & as_writable_bytes 5780b57cec5SDimitry Andrictemplate <class _Tp, size_t _Extent> 579cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI auto as_bytes(span<_Tp, _Extent> __s) noexcept { 580cb14a3feSDimitry Andric return __s.__as_bytes(); 581cb14a3feSDimitry Andric} 5820b57cec5SDimitry Andric 583cb14a3feSDimitry Andrictemplate <class _Tp, size_t _Extent> 584cb14a3feSDimitry Andric requires(!is_const_v<_Tp>) 585cb14a3feSDimitry Andric_LIBCPP_HIDE_FROM_ABI auto as_writable_bytes(span<_Tp, _Extent> __s) noexcept { 586cb14a3feSDimitry Andric return __s.__as_writable_bytes(); 587cb14a3feSDimitry Andric} 5880b57cec5SDimitry Andric 5890fca6ea1SDimitry Andric# if _LIBCPP_STD_VER >= 26 5900fca6ea1SDimitry Andrictemplate <class _Tp> 5910fca6ea1SDimitry Andricconcept __integral_constant_like = 5920fca6ea1SDimitry Andric is_integral_v<decltype(_Tp::value)> && !is_same_v<bool, remove_const_t<decltype(_Tp::value)>> && 5930fca6ea1SDimitry Andric convertible_to<_Tp, decltype(_Tp::value)> && equality_comparable_with<_Tp, decltype(_Tp::value)> && 5940fca6ea1SDimitry Andric bool_constant<_Tp() == _Tp::value>::value && 5950fca6ea1SDimitry Andric bool_constant<static_cast<decltype(_Tp::value)>(_Tp()) == _Tp::value>::value; 5960fca6ea1SDimitry Andric 5970fca6ea1SDimitry Andrictemplate <class _Tp> 5980fca6ea1SDimitry Andricinline constexpr size_t __maybe_static_ext = dynamic_extent; 5990fca6ea1SDimitry Andric 6000fca6ea1SDimitry Andrictemplate <__integral_constant_like _Tp> 6010fca6ea1SDimitry Andricinline constexpr size_t __maybe_static_ext<_Tp> = {_Tp::value}; 6020fca6ea1SDimitry Andric 6030fca6ea1SDimitry Andrictemplate <contiguous_iterator _It, class _EndOrSize> 6040fca6ea1SDimitry Andricspan(_It, _EndOrSize) -> span<remove_reference_t<iter_reference_t<_It>>, __maybe_static_ext<_EndOrSize>>; 6050fca6ea1SDimitry Andric# else 606349cc55cSDimitry Andrictemplate <contiguous_iterator _It, class _EndOrSize> 607349cc55cSDimitry Andricspan(_It, _EndOrSize) -> span<remove_reference_t<iter_reference_t<_It>>>; 6080fca6ea1SDimitry Andric# endif 609349cc55cSDimitry Andric 6100b57cec5SDimitry Andrictemplate <class _Tp, size_t _Sz> 6110b57cec5SDimitry Andricspan(_Tp (&)[_Sz]) -> span<_Tp, _Sz>; 6120b57cec5SDimitry Andric 6130b57cec5SDimitry Andrictemplate <class _Tp, size_t _Sz> 6140b57cec5SDimitry Andricspan(array<_Tp, _Sz>&) -> span<_Tp, _Sz>; 6150b57cec5SDimitry Andric 6160b57cec5SDimitry Andrictemplate <class _Tp, size_t _Sz> 6170b57cec5SDimitry Andricspan(const array<_Tp, _Sz>&) -> span<const _Tp, _Sz>; 6180b57cec5SDimitry Andric 619349cc55cSDimitry Andrictemplate <ranges::contiguous_range _Range> 620349cc55cSDimitry Andricspan(_Range&&) -> span<remove_reference_t<ranges::range_reference_t<_Range>>>; 6210b57cec5SDimitry Andric 62206c3fb27SDimitry Andric#endif // _LIBCPP_STD_VER >= 20 6230b57cec5SDimitry Andric 6240b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 6250b57cec5SDimitry Andric 626e8d8bef9SDimitry Andric_LIBCPP_POP_MACROS 627e8d8bef9SDimitry Andric 628bdd1243dSDimitry Andric#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 6290fca6ea1SDimitry Andric# include <array> 630bdd1243dSDimitry Andric# include <concepts> 631bdd1243dSDimitry Andric# include <functional> 632bdd1243dSDimitry Andric# include <iterator> 63306c3fb27SDimitry Andric# include <type_traits> 634bdd1243dSDimitry Andric#endif 635bdd1243dSDimitry Andric 6360b57cec5SDimitry Andric#endif // _LIBCPP_SPAN 637