10b57cec5SDimitry Andric// -*- C++ -*- 20b57cec5SDimitry Andric//===------------------------------ span ---------------------------------===// 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 250b57cec5SDimitry Andric// [span.objectrep], views of object representation 260b57cec5SDimitry Andrictemplate <class ElementType, size_t Extent> 270b57cec5SDimitry Andric span<const byte, ((Extent == dynamic_extent) ? dynamic_extent : 280b57cec5SDimitry Andric (sizeof(ElementType) * Extent))> as_bytes(span<ElementType, Extent> s) noexcept; 290b57cec5SDimitry Andric 300b57cec5SDimitry Andrictemplate <class ElementType, size_t Extent> 310b57cec5SDimitry Andric span< byte, ((Extent == dynamic_extent) ? dynamic_extent : 320b57cec5SDimitry Andric (sizeof(ElementType) * Extent))> as_writable_bytes(span<ElementType, Extent> s) noexcept; 330b57cec5SDimitry Andric 340b57cec5SDimitry Andric 350b57cec5SDimitry Andricnamespace std { 360b57cec5SDimitry Andrictemplate <class ElementType, size_t Extent = dynamic_extent> 370b57cec5SDimitry Andricclass span { 380b57cec5SDimitry Andricpublic: 390b57cec5SDimitry Andric // constants and types 400b57cec5SDimitry Andric using element_type = ElementType; 410b57cec5SDimitry Andric using value_type = remove_cv_t<ElementType>; 42480093f4SDimitry Andric using size_type = size_t; 430b57cec5SDimitry Andric using difference_type = ptrdiff_t; 440b57cec5SDimitry Andric using pointer = element_type*; 450b57cec5SDimitry Andric using const_pointer = const element_type*; 460b57cec5SDimitry Andric using reference = element_type&; 470b57cec5SDimitry Andric using const_reference = const element_type&; 480b57cec5SDimitry Andric using iterator = implementation-defined; 490b57cec5SDimitry Andric using reverse_iterator = std::reverse_iterator<iterator>; 50480093f4SDimitry Andric static constexpr size_type extent = Extent; 510b57cec5SDimitry Andric 520b57cec5SDimitry Andric // [span.cons], span constructors, copy, assignment, and destructor 530b57cec5SDimitry Andric constexpr span() noexcept; 545ffd83dbSDimitry Andric constexpr explicit(Extent != dynamic_extent) span(pointer ptr, size_type count); 555ffd83dbSDimitry Andric constexpr explicit(Extent != dynamic_extent) span(pointer firstElem, pointer lastElem); 560b57cec5SDimitry Andric template <size_t N> 570b57cec5SDimitry Andric constexpr span(element_type (&arr)[N]) noexcept; 580b57cec5SDimitry Andric template <size_t N> 590b57cec5SDimitry Andric constexpr span(array<value_type, N>& arr) noexcept; 600b57cec5SDimitry Andric template <size_t N> 610b57cec5SDimitry Andric constexpr span(const array<value_type, N>& arr) noexcept; 620b57cec5SDimitry Andric template <class Container> 635ffd83dbSDimitry Andric constexpr explicit(Extent != dynamic_extent) span(Container& cont); 640b57cec5SDimitry Andric template <class Container> 655ffd83dbSDimitry Andric constexpr explicit(Extent != dynamic_extent) span(const Container& cont); 660b57cec5SDimitry Andric constexpr span(const span& other) noexcept = default; 670b57cec5SDimitry Andric template <class OtherElementType, size_t OtherExtent> 685ffd83dbSDimitry Andric constexpr explicit(Extent != dynamic_extent) span(const span<OtherElementType, OtherExtent>& s) noexcept; 690b57cec5SDimitry Andric ~span() noexcept = default; 700b57cec5SDimitry Andric constexpr span& operator=(const span& other) noexcept = default; 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric // [span.sub], span subviews 730b57cec5SDimitry Andric template <size_t Count> 740b57cec5SDimitry Andric constexpr span<element_type, Count> first() const; 750b57cec5SDimitry Andric template <size_t Count> 760b57cec5SDimitry Andric constexpr span<element_type, Count> last() const; 770b57cec5SDimitry Andric template <size_t Offset, size_t Count = dynamic_extent> 780b57cec5SDimitry Andric constexpr span<element_type, see below> subspan() const; 790b57cec5SDimitry Andric 80480093f4SDimitry Andric constexpr span<element_type, dynamic_extent> first(size_type count) const; 81480093f4SDimitry Andric constexpr span<element_type, dynamic_extent> last(size_type count) const; 82480093f4SDimitry Andric constexpr span<element_type, dynamic_extent> subspan(size_type offset, size_type count = dynamic_extent) const; 830b57cec5SDimitry Andric 840b57cec5SDimitry Andric // [span.obs], span observers 85480093f4SDimitry Andric constexpr size_type size() const noexcept; 86480093f4SDimitry Andric constexpr size_type size_bytes() const noexcept; 870b57cec5SDimitry Andric constexpr bool empty() const noexcept; 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric // [span.elem], span element access 90480093f4SDimitry Andric constexpr reference operator[](size_type idx) const; 910b57cec5SDimitry Andric constexpr reference front() const; 920b57cec5SDimitry Andric constexpr reference back() const; 930b57cec5SDimitry Andric constexpr pointer data() const noexcept; 940b57cec5SDimitry Andric 950b57cec5SDimitry Andric // [span.iterators], span iterator support 960b57cec5SDimitry Andric constexpr iterator begin() const noexcept; 970b57cec5SDimitry Andric constexpr iterator end() const noexcept; 980b57cec5SDimitry Andric constexpr reverse_iterator rbegin() const noexcept; 990b57cec5SDimitry Andric constexpr reverse_iterator rend() const noexcept; 1000b57cec5SDimitry Andric 1010b57cec5SDimitry Andricprivate: 1020b57cec5SDimitry Andric pointer data_; // exposition only 103480093f4SDimitry Andric size_type size_; // exposition only 1040b57cec5SDimitry Andric}; 1050b57cec5SDimitry Andric 1060b57cec5SDimitry Andrictemplate<class T, size_t N> 1070b57cec5SDimitry Andric span(T (&)[N]) -> span<T, N>; 1080b57cec5SDimitry Andric 1090b57cec5SDimitry Andrictemplate<class T, size_t N> 1100b57cec5SDimitry Andric span(array<T, N>&) -> span<T, N>; 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andrictemplate<class T, size_t N> 1130b57cec5SDimitry Andric span(const array<T, N>&) -> span<const T, N>; 1140b57cec5SDimitry Andric 1150b57cec5SDimitry Andrictemplate<class Container> 1160b57cec5SDimitry Andric span(Container&) -> span<typename Container::value_type>; 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andrictemplate<class Container> 1190b57cec5SDimitry Andric span(const Container&) -> span<const typename Container::value_type>; 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andric} // namespace std 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric*/ 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andric#include <__config> 1260b57cec5SDimitry Andric#include <array> // for array 1270b57cec5SDimitry Andric#include <cstddef> // for byte 1285ffd83dbSDimitry Andric#include <iterator> // for iterators 1295ffd83dbSDimitry Andric#include <type_traits> // for remove_cv, etc 1300b57cec5SDimitry Andric 1310b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 1320b57cec5SDimitry Andric#pragma GCC system_header 1330b57cec5SDimitry Andric#endif 1340b57cec5SDimitry Andric 135*e8d8bef9SDimitry Andric_LIBCPP_PUSH_MACROS 136*e8d8bef9SDimitry Andric#include <__undef_macros> 137*e8d8bef9SDimitry Andric 1380b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 1390b57cec5SDimitry Andric 1400b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 17 1410b57cec5SDimitry Andric 142*e8d8bef9SDimitry Andricinline constexpr size_t dynamic_extent = numeric_limits<size_t>::max(); 1430b57cec5SDimitry Andrictemplate <typename _Tp, size_t _Extent = dynamic_extent> class span; 1440b57cec5SDimitry Andric 1450b57cec5SDimitry Andric 1460b57cec5SDimitry Andrictemplate <class _Tp> 1470b57cec5SDimitry Andricstruct __is_span_impl : public false_type {}; 1480b57cec5SDimitry Andric 1490b57cec5SDimitry Andrictemplate <class _Tp, size_t _Extent> 1500b57cec5SDimitry Andricstruct __is_span_impl<span<_Tp, _Extent>> : public true_type {}; 1510b57cec5SDimitry Andric 1520b57cec5SDimitry Andrictemplate <class _Tp> 1530b57cec5SDimitry Andricstruct __is_span : public __is_span_impl<remove_cv_t<_Tp>> {}; 1540b57cec5SDimitry Andric 1550b57cec5SDimitry Andrictemplate <class _Tp> 1560b57cec5SDimitry Andricstruct __is_std_array_impl : public false_type {}; 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andrictemplate <class _Tp, size_t _Sz> 1590b57cec5SDimitry Andricstruct __is_std_array_impl<array<_Tp, _Sz>> : public true_type {}; 1600b57cec5SDimitry Andric 1610b57cec5SDimitry Andrictemplate <class _Tp> 1620b57cec5SDimitry Andricstruct __is_std_array : public __is_std_array_impl<remove_cv_t<_Tp>> {}; 1630b57cec5SDimitry Andric 1640b57cec5SDimitry Andrictemplate <class _Tp, class _ElementType, class = void> 1650b57cec5SDimitry Andricstruct __is_span_compatible_container : public false_type {}; 1660b57cec5SDimitry Andric 1670b57cec5SDimitry Andrictemplate <class _Tp, class _ElementType> 1680b57cec5SDimitry Andricstruct __is_span_compatible_container<_Tp, _ElementType, 1690b57cec5SDimitry Andric void_t< 1700b57cec5SDimitry Andric // is not a specialization of span 1710b57cec5SDimitry Andric typename enable_if<!__is_span<_Tp>::value, nullptr_t>::type, 1720b57cec5SDimitry Andric // is not a specialization of array 1730b57cec5SDimitry Andric typename enable_if<!__is_std_array<_Tp>::value, nullptr_t>::type, 1740b57cec5SDimitry Andric // is_array_v<Container> is false, 1750b57cec5SDimitry Andric typename enable_if<!is_array_v<_Tp>, nullptr_t>::type, 1760b57cec5SDimitry Andric // data(cont) and size(cont) are well formed 1770b57cec5SDimitry Andric decltype(data(declval<_Tp>())), 1780b57cec5SDimitry Andric decltype(size(declval<_Tp>())), 1790b57cec5SDimitry Andric // remove_pointer_t<decltype(data(cont))>(*)[] is convertible to ElementType(*)[] 1800b57cec5SDimitry Andric typename enable_if< 1810b57cec5SDimitry Andric is_convertible_v<remove_pointer_t<decltype(data(declval<_Tp &>()))>(*)[], 1820b57cec5SDimitry Andric _ElementType(*)[]>, 1830b57cec5SDimitry Andric nullptr_t>::type 1840b57cec5SDimitry Andric >> 1850b57cec5SDimitry Andric : public true_type {}; 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric 1880b57cec5SDimitry Andrictemplate <typename _Tp, size_t _Extent> 1890b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS span { 1900b57cec5SDimitry Andricpublic: 1910b57cec5SDimitry Andric// constants and types 1920b57cec5SDimitry Andric using element_type = _Tp; 1930b57cec5SDimitry Andric using value_type = remove_cv_t<_Tp>; 194480093f4SDimitry Andric using size_type = size_t; 1950b57cec5SDimitry Andric using difference_type = ptrdiff_t; 1960b57cec5SDimitry Andric using pointer = _Tp *; 1970b57cec5SDimitry Andric using const_pointer = const _Tp *; 1980b57cec5SDimitry Andric using reference = _Tp &; 1990b57cec5SDimitry Andric using const_reference = const _Tp &; 2000b57cec5SDimitry Andric using iterator = __wrap_iter<pointer>; 2010b57cec5SDimitry Andric using reverse_iterator = _VSTD::reverse_iterator<iterator>; 2020b57cec5SDimitry Andric 203480093f4SDimitry Andric static constexpr size_type extent = _Extent; 2040b57cec5SDimitry Andric 2050b57cec5SDimitry Andric// [span.cons], span constructors, copy, assignment, and destructor 2065ffd83dbSDimitry Andric template <size_t _Sz = _Extent, enable_if_t<_Sz == 0, nullptr_t> = nullptr> 2075ffd83dbSDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr} {} 2080b57cec5SDimitry Andric 2090b57cec5SDimitry Andric constexpr span (const span&) noexcept = default; 2100b57cec5SDimitry Andric constexpr span& operator=(const span&) noexcept = default; 2110b57cec5SDimitry Andric 2125ffd83dbSDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr explicit span(pointer __ptr, size_type __count) : __data{__ptr} 2130b57cec5SDimitry Andric { (void)__count; _LIBCPP_ASSERT(_Extent == __count, "size mismatch in span's constructor (ptr, len)"); } 2145ffd83dbSDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr explicit span(pointer __f, pointer __l) : __data{__f} 2150b57cec5SDimitry Andric { (void)__l; _LIBCPP_ASSERT(_Extent == distance(__f, __l), "size mismatch in span's constructor (ptr, ptr)"); } 2160b57cec5SDimitry Andric 2170b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr span(element_type (&__arr)[_Extent]) noexcept : __data{__arr} {} 2185ffd83dbSDimitry Andric 2195ffd83dbSDimitry Andric template <class _OtherElementType, 2205ffd83dbSDimitry Andric enable_if_t<is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, nullptr_t> = nullptr> 2215ffd83dbSDimitry Andric _LIBCPP_INLINE_VISIBILITY 2225ffd83dbSDimitry Andric constexpr span(array<_OtherElementType, _Extent>& __arr) noexcept : __data{__arr.data()} {} 2235ffd83dbSDimitry Andric 2245ffd83dbSDimitry Andric template <class _OtherElementType, 2255ffd83dbSDimitry Andric enable_if_t<is_convertible_v<const _OtherElementType(*)[], element_type (*)[]>, nullptr_t> = nullptr> 2265ffd83dbSDimitry Andric _LIBCPP_INLINE_VISIBILITY 2275ffd83dbSDimitry Andric constexpr span(const array<_OtherElementType, _Extent>& __arr) noexcept : __data{__arr.data()} {} 2285ffd83dbSDimitry Andric 2295ffd83dbSDimitry Andric template <class _Container> 2305ffd83dbSDimitry Andric _LIBCPP_INLINE_VISIBILITY 2315ffd83dbSDimitry Andric constexpr explicit span( _Container& __c, 2325ffd83dbSDimitry Andric enable_if_t<__is_span_compatible_container<_Container, _Tp>::value, nullptr_t> = nullptr) 2335ffd83dbSDimitry Andric : __data{_VSTD::data(__c)} { 2345ffd83dbSDimitry Andric _LIBCPP_ASSERT(_Extent == _VSTD::size(__c), "size mismatch in span's constructor (range)"); 2355ffd83dbSDimitry Andric } 2365ffd83dbSDimitry Andric 2375ffd83dbSDimitry Andric template <class _Container> 2385ffd83dbSDimitry Andric _LIBCPP_INLINE_VISIBILITY 2395ffd83dbSDimitry Andric constexpr explicit span(const _Container& __c, 2405ffd83dbSDimitry Andric enable_if_t<__is_span_compatible_container<const _Container, _Tp>::value, nullptr_t> = nullptr) 2415ffd83dbSDimitry Andric : __data{_VSTD::data(__c)} { 2425ffd83dbSDimitry Andric _LIBCPP_ASSERT(_Extent == _VSTD::size(__c), "size mismatch in span's constructor (range)"); 2435ffd83dbSDimitry Andric } 2440b57cec5SDimitry Andric 2450b57cec5SDimitry Andric template <class _OtherElementType> 2460b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2470b57cec5SDimitry Andric constexpr span(const span<_OtherElementType, _Extent>& __other, 2480b57cec5SDimitry Andric enable_if_t< 2490b57cec5SDimitry Andric is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, 2500b57cec5SDimitry Andric nullptr_t> = nullptr) 2510b57cec5SDimitry Andric : __data{__other.data()} {} 2520b57cec5SDimitry Andric 2530b57cec5SDimitry Andric template <class _OtherElementType> 2540b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2555ffd83dbSDimitry Andric constexpr explicit span(const span<_OtherElementType, dynamic_extent>& __other, 2560b57cec5SDimitry Andric enable_if_t< 2570b57cec5SDimitry Andric is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, 2580b57cec5SDimitry Andric nullptr_t> = nullptr) noexcept 2590b57cec5SDimitry Andric : __data{__other.data()} { _LIBCPP_ASSERT(_Extent == __other.size(), "size mismatch in span's constructor (other span)"); } 2600b57cec5SDimitry Andric 2610b57cec5SDimitry Andric 2620b57cec5SDimitry Andric// ~span() noexcept = default; 2630b57cec5SDimitry Andric 2640b57cec5SDimitry Andric template <size_t _Count> 2650b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2660b57cec5SDimitry Andric constexpr span<element_type, _Count> first() const noexcept 2670b57cec5SDimitry Andric { 2680b57cec5SDimitry Andric static_assert(_Count <= _Extent, "Count out of range in span::first()"); 2695ffd83dbSDimitry Andric return span<element_type, _Count>{data(), _Count}; 2700b57cec5SDimitry Andric } 2710b57cec5SDimitry Andric 2720b57cec5SDimitry Andric template <size_t _Count> 2730b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2740b57cec5SDimitry Andric constexpr span<element_type, _Count> last() const noexcept 2750b57cec5SDimitry Andric { 2760b57cec5SDimitry Andric static_assert(_Count <= _Extent, "Count out of range in span::last()"); 2775ffd83dbSDimitry Andric return span<element_type, _Count>{data() + size() - _Count, _Count}; 2780b57cec5SDimitry Andric } 2790b57cec5SDimitry Andric 2800b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 281480093f4SDimitry Andric constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept 2820b57cec5SDimitry Andric { 2830b57cec5SDimitry Andric _LIBCPP_ASSERT(__count <= size(), "Count out of range in span::first(count)"); 2840b57cec5SDimitry Andric return {data(), __count}; 2850b57cec5SDimitry Andric } 2860b57cec5SDimitry Andric 2870b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 288480093f4SDimitry Andric constexpr span<element_type, dynamic_extent> last(size_type __count) const noexcept 2890b57cec5SDimitry Andric { 2900b57cec5SDimitry Andric _LIBCPP_ASSERT(__count <= size(), "Count out of range in span::last(count)"); 2910b57cec5SDimitry Andric return {data() + size() - __count, __count}; 2920b57cec5SDimitry Andric } 2930b57cec5SDimitry Andric 2940b57cec5SDimitry Andric template <size_t _Offset, size_t _Count = dynamic_extent> 2950b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2960b57cec5SDimitry Andric constexpr auto subspan() const noexcept 2970b57cec5SDimitry Andric -> span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset> 2980b57cec5SDimitry Andric { 2990b57cec5SDimitry Andric static_assert(_Offset <= _Extent, "Offset out of range in span::subspan()"); 3005ffd83dbSDimitry Andric static_assert(_Count == dynamic_extent || _Count <= _Extent - _Offset, "Offset + count out of range in span::subspan()"); 3015ffd83dbSDimitry Andric 3025ffd83dbSDimitry Andric using _ReturnType = span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset>; 3035ffd83dbSDimitry Andric return _ReturnType{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; 3040b57cec5SDimitry Andric } 3050b57cec5SDimitry Andric 3060b57cec5SDimitry Andric 3070b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3080b57cec5SDimitry Andric constexpr span<element_type, dynamic_extent> 309480093f4SDimitry Andric subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept 3100b57cec5SDimitry Andric { 3110b57cec5SDimitry Andric _LIBCPP_ASSERT(__offset <= size(), "Offset out of range in span::subspan(offset, count)"); 3120b57cec5SDimitry Andric _LIBCPP_ASSERT(__count <= size() || __count == dynamic_extent, "Count out of range in span::subspan(offset, count)"); 3130b57cec5SDimitry Andric if (__count == dynamic_extent) 3140b57cec5SDimitry Andric return {data() + __offset, size() - __offset}; 3155ffd83dbSDimitry Andric _LIBCPP_ASSERT(__count <= size() - __offset, "Offset + count out of range in span::subspan(offset, count)"); 3160b57cec5SDimitry Andric return {data() + __offset, __count}; 3170b57cec5SDimitry Andric } 3180b57cec5SDimitry Andric 319480093f4SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr size_type size() const noexcept { return _Extent; } 320480093f4SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr size_type size_bytes() const noexcept { return _Extent * sizeof(element_type); } 3210b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr bool empty() const noexcept { return _Extent == 0; } 3220b57cec5SDimitry Andric 323480093f4SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr reference operator[](size_type __idx) const noexcept 3240b57cec5SDimitry Andric { 3255ffd83dbSDimitry Andric _LIBCPP_ASSERT(__idx < size(), "span<T,N>[] index out of bounds"); 3260b57cec5SDimitry Andric return __data[__idx]; 3270b57cec5SDimitry Andric } 3280b57cec5SDimitry Andric 3290b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr reference front() const noexcept 3300b57cec5SDimitry Andric { 3315ffd83dbSDimitry Andric _LIBCPP_ASSERT(!empty(), "span<T, N>::front() on empty span"); 3320b57cec5SDimitry Andric return __data[0]; 3330b57cec5SDimitry Andric } 3340b57cec5SDimitry Andric 3350b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr reference back() const noexcept 3360b57cec5SDimitry Andric { 3375ffd83dbSDimitry Andric _LIBCPP_ASSERT(!empty(), "span<T, N>::back() on empty span"); 3380b57cec5SDimitry Andric return __data[size()-1]; 3390b57cec5SDimitry Andric } 3400b57cec5SDimitry Andric 3410b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr pointer data() const noexcept { return __data; } 3420b57cec5SDimitry Andric 3430b57cec5SDimitry Andric// [span.iter], span iterator support 3440b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr iterator begin() const noexcept { return iterator(data()); } 3450b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr iterator end() const noexcept { return iterator(data() + size()); } 3460b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); } 3470b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); } 3480b57cec5SDimitry Andric 3490b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY span<const byte, _Extent * sizeof(element_type)> __as_bytes() const noexcept 3505ffd83dbSDimitry Andric { return span<const byte, _Extent * sizeof(element_type)>{reinterpret_cast<const byte *>(data()), size_bytes()}; } 3510b57cec5SDimitry Andric 3520b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY span<byte, _Extent * sizeof(element_type)> __as_writable_bytes() const noexcept 3535ffd83dbSDimitry Andric { return span<byte, _Extent * sizeof(element_type)>{reinterpret_cast<byte *>(data()), size_bytes()}; } 3540b57cec5SDimitry Andric 3550b57cec5SDimitry Andricprivate: 3560b57cec5SDimitry Andric pointer __data; 3570b57cec5SDimitry Andric 3580b57cec5SDimitry Andric}; 3590b57cec5SDimitry Andric 3600b57cec5SDimitry Andric 3610b57cec5SDimitry Andrictemplate <typename _Tp> 3620b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS span<_Tp, dynamic_extent> { 3630b57cec5SDimitry Andricprivate: 3640b57cec5SDimitry Andric 3650b57cec5SDimitry Andricpublic: 3660b57cec5SDimitry Andric// constants and types 3670b57cec5SDimitry Andric using element_type = _Tp; 3680b57cec5SDimitry Andric using value_type = remove_cv_t<_Tp>; 369480093f4SDimitry Andric using size_type = size_t; 3700b57cec5SDimitry Andric using difference_type = ptrdiff_t; 3710b57cec5SDimitry Andric using pointer = _Tp *; 3720b57cec5SDimitry Andric using const_pointer = const _Tp *; 3730b57cec5SDimitry Andric using reference = _Tp &; 3740b57cec5SDimitry Andric using const_reference = const _Tp &; 3750b57cec5SDimitry Andric using iterator = __wrap_iter<pointer>; 3760b57cec5SDimitry Andric using reverse_iterator = _VSTD::reverse_iterator<iterator>; 3770b57cec5SDimitry Andric 378480093f4SDimitry Andric static constexpr size_type extent = dynamic_extent; 3790b57cec5SDimitry Andric 3800b57cec5SDimitry Andric// [span.cons], span constructors, copy, assignment, and destructor 3810b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr}, __size{0} {} 3820b57cec5SDimitry Andric 3830b57cec5SDimitry Andric constexpr span (const span&) noexcept = default; 3840b57cec5SDimitry Andric constexpr span& operator=(const span&) noexcept = default; 3850b57cec5SDimitry Andric 386480093f4SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr span(pointer __ptr, size_type __count) : __data{__ptr}, __size{__count} {} 3870b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr span(pointer __f, pointer __l) : __data{__f}, __size{static_cast<size_t>(distance(__f, __l))} {} 3880b57cec5SDimitry Andric 3890b57cec5SDimitry Andric template <size_t _Sz> 3900b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3910b57cec5SDimitry Andric constexpr span(element_type (&__arr)[_Sz]) noexcept : __data{__arr}, __size{_Sz} {} 3920b57cec5SDimitry Andric 3935ffd83dbSDimitry Andric template <class _OtherElementType, size_t _Sz, 3945ffd83dbSDimitry Andric enable_if_t<is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, nullptr_t> = nullptr> 3950b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3965ffd83dbSDimitry Andric constexpr span(array<_OtherElementType, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {} 3970b57cec5SDimitry Andric 3985ffd83dbSDimitry Andric template <class _OtherElementType, size_t _Sz, 3995ffd83dbSDimitry Andric enable_if_t<is_convertible_v<const _OtherElementType(*)[], element_type (*)[]>, nullptr_t> = nullptr> 4000b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 4015ffd83dbSDimitry Andric constexpr span(const array<_OtherElementType, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {} 4020b57cec5SDimitry Andric 4030b57cec5SDimitry Andric template <class _Container> 4040b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 4050b57cec5SDimitry Andric constexpr span( _Container& __c, 4060b57cec5SDimitry Andric enable_if_t<__is_span_compatible_container<_Container, _Tp>::value, nullptr_t> = nullptr) 407480093f4SDimitry Andric : __data{_VSTD::data(__c)}, __size{(size_type) _VSTD::size(__c)} {} 4080b57cec5SDimitry Andric 4090b57cec5SDimitry Andric template <class _Container> 4100b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 4110b57cec5SDimitry Andric constexpr span(const _Container& __c, 4120b57cec5SDimitry Andric enable_if_t<__is_span_compatible_container<const _Container, _Tp>::value, nullptr_t> = nullptr) 413480093f4SDimitry Andric : __data{_VSTD::data(__c)}, __size{(size_type) _VSTD::size(__c)} {} 4140b57cec5SDimitry Andric 4150b57cec5SDimitry Andric 4160b57cec5SDimitry Andric template <class _OtherElementType, size_t _OtherExtent> 4170b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 4180b57cec5SDimitry Andric constexpr span(const span<_OtherElementType, _OtherExtent>& __other, 4190b57cec5SDimitry Andric enable_if_t< 4200b57cec5SDimitry Andric is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, 4210b57cec5SDimitry Andric nullptr_t> = nullptr) noexcept 4220b57cec5SDimitry Andric : __data{__other.data()}, __size{__other.size()} {} 4230b57cec5SDimitry Andric 4240b57cec5SDimitry Andric// ~span() noexcept = default; 4250b57cec5SDimitry Andric 4260b57cec5SDimitry Andric template <size_t _Count> 4270b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 4280b57cec5SDimitry Andric constexpr span<element_type, _Count> first() const noexcept 4290b57cec5SDimitry Andric { 4300b57cec5SDimitry Andric _LIBCPP_ASSERT(_Count <= size(), "Count out of range in span::first()"); 4315ffd83dbSDimitry Andric return span<element_type, _Count>{data(), _Count}; 4320b57cec5SDimitry Andric } 4330b57cec5SDimitry Andric 4340b57cec5SDimitry Andric template <size_t _Count> 4350b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 4360b57cec5SDimitry Andric constexpr span<element_type, _Count> last() const noexcept 4370b57cec5SDimitry Andric { 4380b57cec5SDimitry Andric _LIBCPP_ASSERT(_Count <= size(), "Count out of range in span::last()"); 4395ffd83dbSDimitry Andric return span<element_type, _Count>{data() + size() - _Count, _Count}; 4400b57cec5SDimitry Andric } 4410b57cec5SDimitry Andric 4420b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 443480093f4SDimitry Andric constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept 4440b57cec5SDimitry Andric { 4450b57cec5SDimitry Andric _LIBCPP_ASSERT(__count <= size(), "Count out of range in span::first(count)"); 4460b57cec5SDimitry Andric return {data(), __count}; 4470b57cec5SDimitry Andric } 4480b57cec5SDimitry Andric 4490b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 450480093f4SDimitry Andric constexpr span<element_type, dynamic_extent> last (size_type __count) const noexcept 4510b57cec5SDimitry Andric { 4520b57cec5SDimitry Andric _LIBCPP_ASSERT(__count <= size(), "Count out of range in span::last(count)"); 4530b57cec5SDimitry Andric return {data() + size() - __count, __count}; 4540b57cec5SDimitry Andric } 4550b57cec5SDimitry Andric 4560b57cec5SDimitry Andric template <size_t _Offset, size_t _Count = dynamic_extent> 4570b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 4585ffd83dbSDimitry Andric constexpr span<element_type, _Count> subspan() const noexcept 4590b57cec5SDimitry Andric { 4600b57cec5SDimitry Andric _LIBCPP_ASSERT(_Offset <= size(), "Offset out of range in span::subspan()"); 4615ffd83dbSDimitry Andric _LIBCPP_ASSERT(_Count == dynamic_extent || _Count <= size() - _Offset, "Offset + count out of range in span::subspan()"); 4625ffd83dbSDimitry Andric return span<element_type, _Count>{data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; 4630b57cec5SDimitry Andric } 4640b57cec5SDimitry Andric 4650b57cec5SDimitry Andric constexpr span<element_type, dynamic_extent> 4660b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 467480093f4SDimitry Andric subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept 4680b57cec5SDimitry Andric { 4690b57cec5SDimitry Andric _LIBCPP_ASSERT(__offset <= size(), "Offset out of range in span::subspan(offset, count)"); 4700b57cec5SDimitry Andric _LIBCPP_ASSERT(__count <= size() || __count == dynamic_extent, "count out of range in span::subspan(offset, count)"); 4710b57cec5SDimitry Andric if (__count == dynamic_extent) 4720b57cec5SDimitry Andric return {data() + __offset, size() - __offset}; 4735ffd83dbSDimitry Andric _LIBCPP_ASSERT(__count <= size() - __offset, "Offset + count out of range in span::subspan(offset, count)"); 4740b57cec5SDimitry Andric return {data() + __offset, __count}; 4750b57cec5SDimitry Andric } 4760b57cec5SDimitry Andric 477480093f4SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr size_type size() const noexcept { return __size; } 478480093f4SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr size_type size_bytes() const noexcept { return __size * sizeof(element_type); } 4790b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr bool empty() const noexcept { return __size == 0; } 4800b57cec5SDimitry Andric 481480093f4SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr reference operator[](size_type __idx) const noexcept 4820b57cec5SDimitry Andric { 4835ffd83dbSDimitry Andric _LIBCPP_ASSERT(__idx < size(), "span<T>[] index out of bounds"); 4840b57cec5SDimitry Andric return __data[__idx]; 4850b57cec5SDimitry Andric } 4860b57cec5SDimitry Andric 4870b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr reference front() const noexcept 4880b57cec5SDimitry Andric { 4890b57cec5SDimitry Andric _LIBCPP_ASSERT(!empty(), "span<T>[].front() on empty span"); 4900b57cec5SDimitry Andric return __data[0]; 4910b57cec5SDimitry Andric } 4920b57cec5SDimitry Andric 4930b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr reference back() const noexcept 4940b57cec5SDimitry Andric { 4950b57cec5SDimitry Andric _LIBCPP_ASSERT(!empty(), "span<T>[].back() on empty span"); 4960b57cec5SDimitry Andric return __data[size()-1]; 4970b57cec5SDimitry Andric } 4980b57cec5SDimitry Andric 4990b57cec5SDimitry Andric 5000b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr pointer data() const noexcept { return __data; } 5010b57cec5SDimitry Andric 5020b57cec5SDimitry Andric// [span.iter], span iterator support 5030b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr iterator begin() const noexcept { return iterator(data()); } 5040b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr iterator end() const noexcept { return iterator(data() + size()); } 5050b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); } 5060b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); } 5070b57cec5SDimitry Andric 5080b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY span<const byte, dynamic_extent> __as_bytes() const noexcept 5090b57cec5SDimitry Andric { return {reinterpret_cast<const byte *>(data()), size_bytes()}; } 5100b57cec5SDimitry Andric 5110b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY span<byte, dynamic_extent> __as_writable_bytes() const noexcept 5120b57cec5SDimitry Andric { return {reinterpret_cast<byte *>(data()), size_bytes()}; } 5130b57cec5SDimitry Andric 5140b57cec5SDimitry Andricprivate: 5150b57cec5SDimitry Andric pointer __data; 516480093f4SDimitry Andric size_type __size; 5170b57cec5SDimitry Andric}; 5180b57cec5SDimitry Andric 5190b57cec5SDimitry Andric// as_bytes & as_writable_bytes 5200b57cec5SDimitry Andrictemplate <class _Tp, size_t _Extent> 5210b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 5220b57cec5SDimitry Andricauto as_bytes(span<_Tp, _Extent> __s) noexcept 5230b57cec5SDimitry Andric-> decltype(__s.__as_bytes()) 5240b57cec5SDimitry Andric{ return __s.__as_bytes(); } 5250b57cec5SDimitry Andric 5260b57cec5SDimitry Andrictemplate <class _Tp, size_t _Extent> 5270b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 5280b57cec5SDimitry Andricauto as_writable_bytes(span<_Tp, _Extent> __s) noexcept 5290b57cec5SDimitry Andric-> enable_if_t<!is_const_v<_Tp>, decltype(__s.__as_writable_bytes())> 5300b57cec5SDimitry Andric{ return __s.__as_writable_bytes(); } 5310b57cec5SDimitry Andric 5320b57cec5SDimitry Andric// Deduction guides 5330b57cec5SDimitry Andrictemplate<class _Tp, size_t _Sz> 5340b57cec5SDimitry Andric span(_Tp (&)[_Sz]) -> span<_Tp, _Sz>; 5350b57cec5SDimitry Andric 5360b57cec5SDimitry Andrictemplate<class _Tp, size_t _Sz> 5370b57cec5SDimitry Andric span(array<_Tp, _Sz>&) -> span<_Tp, _Sz>; 5380b57cec5SDimitry Andric 5390b57cec5SDimitry Andrictemplate<class _Tp, size_t _Sz> 5400b57cec5SDimitry Andric span(const array<_Tp, _Sz>&) -> span<const _Tp, _Sz>; 5410b57cec5SDimitry Andric 5420b57cec5SDimitry Andrictemplate<class _Container> 5430b57cec5SDimitry Andric span(_Container&) -> span<typename _Container::value_type>; 5440b57cec5SDimitry Andric 5450b57cec5SDimitry Andrictemplate<class _Container> 5460b57cec5SDimitry Andric span(const _Container&) -> span<const typename _Container::value_type>; 5470b57cec5SDimitry Andric 5480b57cec5SDimitry Andric#endif // _LIBCPP_STD_VER > 17 5490b57cec5SDimitry Andric 5500b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 5510b57cec5SDimitry Andric 552*e8d8bef9SDimitry Andric_LIBCPP_POP_MACROS 553*e8d8bef9SDimitry Andric 5540b57cec5SDimitry Andric#endif // _LIBCPP_SPAN 555