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>; 42*480093f4SDimitry 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 const_iterator = implementation-defined; 500b57cec5SDimitry Andric using reverse_iterator = std::reverse_iterator<iterator>; 510b57cec5SDimitry Andric using const_reverse_iterator = std::reverse_iterator<const_iterator>; 52*480093f4SDimitry Andric static constexpr size_type extent = Extent; 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric // [span.cons], span constructors, copy, assignment, and destructor 550b57cec5SDimitry Andric constexpr span() noexcept; 56*480093f4SDimitry Andric constexpr span(pointer ptr, size_type count); 570b57cec5SDimitry Andric constexpr span(pointer firstElem, pointer lastElem); 580b57cec5SDimitry Andric template <size_t N> 590b57cec5SDimitry Andric constexpr span(element_type (&arr)[N]) noexcept; 600b57cec5SDimitry Andric template <size_t N> 610b57cec5SDimitry Andric constexpr span(array<value_type, N>& arr) noexcept; 620b57cec5SDimitry Andric template <size_t N> 630b57cec5SDimitry Andric constexpr span(const array<value_type, N>& arr) noexcept; 640b57cec5SDimitry Andric template <class Container> 650b57cec5SDimitry Andric constexpr span(Container& cont); 660b57cec5SDimitry Andric template <class Container> 670b57cec5SDimitry Andric constexpr span(const Container& cont); 680b57cec5SDimitry Andric constexpr span(const span& other) noexcept = default; 690b57cec5SDimitry Andric template <class OtherElementType, size_t OtherExtent> 700b57cec5SDimitry Andric constexpr span(const span<OtherElementType, OtherExtent>& s) noexcept; 710b57cec5SDimitry Andric ~span() noexcept = default; 720b57cec5SDimitry Andric constexpr span& operator=(const span& other) noexcept = default; 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric // [span.sub], span subviews 750b57cec5SDimitry Andric template <size_t Count> 760b57cec5SDimitry Andric constexpr span<element_type, Count> first() const; 770b57cec5SDimitry Andric template <size_t Count> 780b57cec5SDimitry Andric constexpr span<element_type, Count> last() const; 790b57cec5SDimitry Andric template <size_t Offset, size_t Count = dynamic_extent> 800b57cec5SDimitry Andric constexpr span<element_type, see below> subspan() const; 810b57cec5SDimitry Andric 82*480093f4SDimitry Andric constexpr span<element_type, dynamic_extent> first(size_type count) const; 83*480093f4SDimitry Andric constexpr span<element_type, dynamic_extent> last(size_type count) const; 84*480093f4SDimitry Andric constexpr span<element_type, dynamic_extent> subspan(size_type offset, size_type count = dynamic_extent) const; 850b57cec5SDimitry Andric 860b57cec5SDimitry Andric // [span.obs], span observers 87*480093f4SDimitry Andric constexpr size_type size() const noexcept; 88*480093f4SDimitry Andric constexpr size_type size_bytes() const noexcept; 890b57cec5SDimitry Andric constexpr bool empty() const noexcept; 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric // [span.elem], span element access 92*480093f4SDimitry Andric constexpr reference operator[](size_type idx) const; 930b57cec5SDimitry Andric constexpr reference front() const; 940b57cec5SDimitry Andric constexpr reference back() const; 950b57cec5SDimitry Andric constexpr pointer data() const noexcept; 960b57cec5SDimitry Andric 970b57cec5SDimitry Andric // [span.iterators], span iterator support 980b57cec5SDimitry Andric constexpr iterator begin() const noexcept; 990b57cec5SDimitry Andric constexpr iterator end() const noexcept; 1000b57cec5SDimitry Andric constexpr const_iterator cbegin() const noexcept; 1010b57cec5SDimitry Andric constexpr const_iterator cend() const noexcept; 1020b57cec5SDimitry Andric constexpr reverse_iterator rbegin() const noexcept; 1030b57cec5SDimitry Andric constexpr reverse_iterator rend() const noexcept; 1040b57cec5SDimitry Andric constexpr const_reverse_iterator crbegin() const noexcept; 1050b57cec5SDimitry Andric constexpr const_reverse_iterator crend() const noexcept; 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andricprivate: 1080b57cec5SDimitry Andric pointer data_; // exposition only 109*480093f4SDimitry Andric size_type size_; // exposition only 1100b57cec5SDimitry Andric}; 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andrictemplate<class T, size_t N> 1130b57cec5SDimitry Andric span(T (&)[N]) -> span<T, N>; 1140b57cec5SDimitry Andric 1150b57cec5SDimitry Andrictemplate<class T, size_t N> 1160b57cec5SDimitry Andric span(array<T, N>&) -> span<T, N>; 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andrictemplate<class T, size_t N> 1190b57cec5SDimitry Andric span(const array<T, N>&) -> span<const T, N>; 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andrictemplate<class Container> 1220b57cec5SDimitry Andric span(Container&) -> span<typename Container::value_type>; 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andrictemplate<class Container> 1250b57cec5SDimitry Andric span(const Container&) -> span<const typename Container::value_type>; 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric} // namespace std 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andric*/ 1300b57cec5SDimitry Andric 1310b57cec5SDimitry Andric#include <__config> 1320b57cec5SDimitry Andric#include <cstddef> // for ptrdiff_t 1330b57cec5SDimitry Andric#include <iterator> // for iterators 1340b57cec5SDimitry Andric#include <array> // for array 1350b57cec5SDimitry Andric#include <type_traits> // for remove_cv, etc 1360b57cec5SDimitry Andric#include <cstddef> // for byte 1370b57cec5SDimitry Andric 1380b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 1390b57cec5SDimitry Andric#pragma GCC system_header 1400b57cec5SDimitry Andric#endif 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andric#if _LIBCPP_STD_VER > 17 1450b57cec5SDimitry Andric 1460b57cec5SDimitry Andricinline constexpr size_t dynamic_extent = numeric_limits<size_t>::max(); 1470b57cec5SDimitry Andrictemplate <typename _Tp, size_t _Extent = dynamic_extent> class span; 1480b57cec5SDimitry Andric 1490b57cec5SDimitry Andric 1500b57cec5SDimitry Andrictemplate <class _Tp> 1510b57cec5SDimitry Andricstruct __is_span_impl : public false_type {}; 1520b57cec5SDimitry Andric 1530b57cec5SDimitry Andrictemplate <class _Tp, size_t _Extent> 1540b57cec5SDimitry Andricstruct __is_span_impl<span<_Tp, _Extent>> : public true_type {}; 1550b57cec5SDimitry Andric 1560b57cec5SDimitry Andrictemplate <class _Tp> 1570b57cec5SDimitry Andricstruct __is_span : public __is_span_impl<remove_cv_t<_Tp>> {}; 1580b57cec5SDimitry Andric 1590b57cec5SDimitry Andrictemplate <class _Tp> 1600b57cec5SDimitry Andricstruct __is_std_array_impl : public false_type {}; 1610b57cec5SDimitry Andric 1620b57cec5SDimitry Andrictemplate <class _Tp, size_t _Sz> 1630b57cec5SDimitry Andricstruct __is_std_array_impl<array<_Tp, _Sz>> : public true_type {}; 1640b57cec5SDimitry Andric 1650b57cec5SDimitry Andrictemplate <class _Tp> 1660b57cec5SDimitry Andricstruct __is_std_array : public __is_std_array_impl<remove_cv_t<_Tp>> {}; 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andrictemplate <class _Tp, class _ElementType, class = void> 1690b57cec5SDimitry Andricstruct __is_span_compatible_container : public false_type {}; 1700b57cec5SDimitry Andric 1710b57cec5SDimitry Andrictemplate <class _Tp, class _ElementType> 1720b57cec5SDimitry Andricstruct __is_span_compatible_container<_Tp, _ElementType, 1730b57cec5SDimitry Andric void_t< 1740b57cec5SDimitry Andric // is not a specialization of span 1750b57cec5SDimitry Andric typename enable_if<!__is_span<_Tp>::value, nullptr_t>::type, 1760b57cec5SDimitry Andric // is not a specialization of array 1770b57cec5SDimitry Andric typename enable_if<!__is_std_array<_Tp>::value, nullptr_t>::type, 1780b57cec5SDimitry Andric // is_array_v<Container> is false, 1790b57cec5SDimitry Andric typename enable_if<!is_array_v<_Tp>, nullptr_t>::type, 1800b57cec5SDimitry Andric // data(cont) and size(cont) are well formed 1810b57cec5SDimitry Andric decltype(data(declval<_Tp>())), 1820b57cec5SDimitry Andric decltype(size(declval<_Tp>())), 1830b57cec5SDimitry Andric // remove_pointer_t<decltype(data(cont))>(*)[] is convertible to ElementType(*)[] 1840b57cec5SDimitry Andric typename enable_if< 1850b57cec5SDimitry Andric is_convertible_v<remove_pointer_t<decltype(data(declval<_Tp &>()))>(*)[], 1860b57cec5SDimitry Andric _ElementType(*)[]>, 1870b57cec5SDimitry Andric nullptr_t>::type 1880b57cec5SDimitry Andric >> 1890b57cec5SDimitry Andric : public true_type {}; 1900b57cec5SDimitry Andric 1910b57cec5SDimitry Andric 1920b57cec5SDimitry Andrictemplate <typename _Tp, size_t _Extent> 1930b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS span { 1940b57cec5SDimitry Andricpublic: 1950b57cec5SDimitry Andric// constants and types 1960b57cec5SDimitry Andric using element_type = _Tp; 1970b57cec5SDimitry Andric using value_type = remove_cv_t<_Tp>; 198*480093f4SDimitry Andric using size_type = size_t; 1990b57cec5SDimitry Andric using difference_type = ptrdiff_t; 2000b57cec5SDimitry Andric using pointer = _Tp *; 2010b57cec5SDimitry Andric using const_pointer = const _Tp *; 2020b57cec5SDimitry Andric using reference = _Tp &; 2030b57cec5SDimitry Andric using const_reference = const _Tp &; 2040b57cec5SDimitry Andric using iterator = __wrap_iter<pointer>; 2050b57cec5SDimitry Andric using const_iterator = __wrap_iter<const_pointer>; 2060b57cec5SDimitry Andric using reverse_iterator = _VSTD::reverse_iterator<iterator>; 2070b57cec5SDimitry Andric using const_reverse_iterator = _VSTD::reverse_iterator<const_iterator>; 2080b57cec5SDimitry Andric 209*480093f4SDimitry Andric static constexpr size_type extent = _Extent; 2100b57cec5SDimitry Andric 2110b57cec5SDimitry Andric// [span.cons], span constructors, copy, assignment, and destructor 2120b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr} 2130b57cec5SDimitry Andric { static_assert(_Extent == 0, "Can't default construct a statically sized span with size > 0"); } 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric constexpr span (const span&) noexcept = default; 2160b57cec5SDimitry Andric constexpr span& operator=(const span&) noexcept = default; 2170b57cec5SDimitry Andric 218*480093f4SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr span(pointer __ptr, size_type __count) : __data{__ptr} 2190b57cec5SDimitry Andric { (void)__count; _LIBCPP_ASSERT(_Extent == __count, "size mismatch in span's constructor (ptr, len)"); } 2200b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr span(pointer __f, pointer __l) : __data{__f} 2210b57cec5SDimitry Andric { (void)__l; _LIBCPP_ASSERT(_Extent == distance(__f, __l), "size mismatch in span's constructor (ptr, ptr)"); } 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr span(element_type (&__arr)[_Extent]) noexcept : __data{__arr} {} 2240b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr span( array<value_type, _Extent>& __arr) noexcept : __data{__arr.data()} {} 2250b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr span(const array<value_type, _Extent>& __arr) noexcept : __data{__arr.data()} {} 2260b57cec5SDimitry Andric 2270b57cec5SDimitry Andric template <class _OtherElementType> 2280b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2290b57cec5SDimitry Andric constexpr span(const span<_OtherElementType, _Extent>& __other, 2300b57cec5SDimitry Andric enable_if_t< 2310b57cec5SDimitry Andric is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, 2320b57cec5SDimitry Andric nullptr_t> = nullptr) 2330b57cec5SDimitry Andric : __data{__other.data()} {} 2340b57cec5SDimitry Andric 2350b57cec5SDimitry Andric template <class _OtherElementType> 2360b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2370b57cec5SDimitry Andric constexpr span(const span<_OtherElementType, dynamic_extent>& __other, 2380b57cec5SDimitry Andric enable_if_t< 2390b57cec5SDimitry Andric is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, 2400b57cec5SDimitry Andric nullptr_t> = nullptr) noexcept 2410b57cec5SDimitry Andric : __data{__other.data()} { _LIBCPP_ASSERT(_Extent == __other.size(), "size mismatch in span's constructor (other span)"); } 2420b57cec5SDimitry Andric 2430b57cec5SDimitry Andric 2440b57cec5SDimitry Andric// ~span() noexcept = default; 2450b57cec5SDimitry Andric 2460b57cec5SDimitry Andric template <size_t _Count> 2470b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2480b57cec5SDimitry Andric constexpr span<element_type, _Count> first() const noexcept 2490b57cec5SDimitry Andric { 2500b57cec5SDimitry Andric static_assert(_Count <= _Extent, "Count out of range in span::first()"); 2510b57cec5SDimitry Andric return {data(), _Count}; 2520b57cec5SDimitry Andric } 2530b57cec5SDimitry Andric 2540b57cec5SDimitry Andric template <size_t _Count> 2550b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2560b57cec5SDimitry Andric constexpr span<element_type, _Count> last() const noexcept 2570b57cec5SDimitry Andric { 2580b57cec5SDimitry Andric static_assert(_Count <= _Extent, "Count out of range in span::last()"); 2590b57cec5SDimitry Andric return {data() + size() - _Count, _Count}; 2600b57cec5SDimitry Andric } 2610b57cec5SDimitry Andric 2620b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 263*480093f4SDimitry Andric constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept 2640b57cec5SDimitry Andric { 2650b57cec5SDimitry Andric _LIBCPP_ASSERT(__count <= size(), "Count out of range in span::first(count)"); 2660b57cec5SDimitry Andric return {data(), __count}; 2670b57cec5SDimitry Andric } 2680b57cec5SDimitry Andric 2690b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 270*480093f4SDimitry Andric constexpr span<element_type, dynamic_extent> last(size_type __count) const noexcept 2710b57cec5SDimitry Andric { 2720b57cec5SDimitry Andric _LIBCPP_ASSERT(__count <= size(), "Count out of range in span::last(count)"); 2730b57cec5SDimitry Andric return {data() + size() - __count, __count}; 2740b57cec5SDimitry Andric } 2750b57cec5SDimitry Andric 2760b57cec5SDimitry Andric template <size_t _Offset, size_t _Count = dynamic_extent> 2770b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2780b57cec5SDimitry Andric constexpr auto subspan() const noexcept 2790b57cec5SDimitry Andric -> span<element_type, _Count != dynamic_extent ? _Count : _Extent - _Offset> 2800b57cec5SDimitry Andric { 2810b57cec5SDimitry Andric static_assert(_Offset <= _Extent, "Offset out of range in span::subspan()"); 2820b57cec5SDimitry Andric return {data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; 2830b57cec5SDimitry Andric } 2840b57cec5SDimitry Andric 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 2870b57cec5SDimitry Andric constexpr span<element_type, dynamic_extent> 288*480093f4SDimitry Andric subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept 2890b57cec5SDimitry Andric { 2900b57cec5SDimitry Andric _LIBCPP_ASSERT(__offset <= size(), "Offset out of range in span::subspan(offset, count)"); 2910b57cec5SDimitry Andric _LIBCPP_ASSERT(__count <= size() || __count == dynamic_extent, "Count out of range in span::subspan(offset, count)"); 2920b57cec5SDimitry Andric if (__count == dynamic_extent) 2930b57cec5SDimitry Andric return {data() + __offset, size() - __offset}; 2940b57cec5SDimitry Andric _LIBCPP_ASSERT(__offset <= size() - __count, "count + offset out of range in span::subspan(offset, count)"); 2950b57cec5SDimitry Andric return {data() + __offset, __count}; 2960b57cec5SDimitry Andric } 2970b57cec5SDimitry Andric 298*480093f4SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr size_type size() const noexcept { return _Extent; } 299*480093f4SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr size_type size_bytes() const noexcept { return _Extent * sizeof(element_type); } 3000b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr bool empty() const noexcept { return _Extent == 0; } 3010b57cec5SDimitry Andric 302*480093f4SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr reference operator[](size_type __idx) const noexcept 3030b57cec5SDimitry Andric { 3040b57cec5SDimitry Andric _LIBCPP_ASSERT(__idx >= 0 && __idx < size(), "span<T,N>[] index out of bounds"); 3050b57cec5SDimitry Andric return __data[__idx]; 3060b57cec5SDimitry Andric } 3070b57cec5SDimitry Andric 3080b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr reference front() const noexcept 3090b57cec5SDimitry Andric { 3100b57cec5SDimitry Andric static_assert(_Extent > 0, "span<T,N>[].front() on empty span"); 3110b57cec5SDimitry Andric return __data[0]; 3120b57cec5SDimitry Andric } 3130b57cec5SDimitry Andric 3140b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr reference back() const noexcept 3150b57cec5SDimitry Andric { 3160b57cec5SDimitry Andric static_assert(_Extent > 0, "span<T,N>[].back() on empty span"); 3170b57cec5SDimitry Andric return __data[size()-1]; 3180b57cec5SDimitry Andric } 3190b57cec5SDimitry Andric 3200b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr pointer data() const noexcept { return __data; } 3210b57cec5SDimitry Andric 3220b57cec5SDimitry Andric// [span.iter], span iterator support 3230b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr iterator begin() const noexcept { return iterator(data()); } 3240b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr iterator end() const noexcept { return iterator(data() + size()); } 3250b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr const_iterator cbegin() const noexcept { return const_iterator(data()); } 3260b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr const_iterator cend() const noexcept { return const_iterator(data() + size()); } 3270b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); } 3280b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); } 3290b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(cend()); } 3300b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr const_reverse_iterator crend() const noexcept { return const_reverse_iterator(cbegin()); } 3310b57cec5SDimitry Andric 3320b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr void swap(span &__other) noexcept 3330b57cec5SDimitry Andric { 3340b57cec5SDimitry Andric pointer __p = __data; 3350b57cec5SDimitry Andric __data = __other.__data; 3360b57cec5SDimitry Andric __other.__data = __p; 3370b57cec5SDimitry Andric } 3380b57cec5SDimitry Andric 3390b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY span<const byte, _Extent * sizeof(element_type)> __as_bytes() const noexcept 3400b57cec5SDimitry Andric { return {reinterpret_cast<const byte *>(data()), size_bytes()}; } 3410b57cec5SDimitry Andric 3420b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY span<byte, _Extent * sizeof(element_type)> __as_writable_bytes() const noexcept 3430b57cec5SDimitry Andric { return {reinterpret_cast<byte *>(data()), size_bytes()}; } 3440b57cec5SDimitry Andric 3450b57cec5SDimitry Andricprivate: 3460b57cec5SDimitry Andric pointer __data; 3470b57cec5SDimitry Andric 3480b57cec5SDimitry Andric}; 3490b57cec5SDimitry Andric 3500b57cec5SDimitry Andric 3510b57cec5SDimitry Andrictemplate <typename _Tp> 3520b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS span<_Tp, dynamic_extent> { 3530b57cec5SDimitry Andricprivate: 3540b57cec5SDimitry Andric 3550b57cec5SDimitry Andricpublic: 3560b57cec5SDimitry Andric// constants and types 3570b57cec5SDimitry Andric using element_type = _Tp; 3580b57cec5SDimitry Andric using value_type = remove_cv_t<_Tp>; 359*480093f4SDimitry Andric using size_type = size_t; 3600b57cec5SDimitry Andric using difference_type = ptrdiff_t; 3610b57cec5SDimitry Andric using pointer = _Tp *; 3620b57cec5SDimitry Andric using const_pointer = const _Tp *; 3630b57cec5SDimitry Andric using reference = _Tp &; 3640b57cec5SDimitry Andric using const_reference = const _Tp &; 3650b57cec5SDimitry Andric using iterator = __wrap_iter<pointer>; 3660b57cec5SDimitry Andric using const_iterator = __wrap_iter<const_pointer>; 3670b57cec5SDimitry Andric using reverse_iterator = _VSTD::reverse_iterator<iterator>; 3680b57cec5SDimitry Andric using const_reverse_iterator = _VSTD::reverse_iterator<const_iterator>; 3690b57cec5SDimitry Andric 370*480093f4SDimitry Andric static constexpr size_type extent = dynamic_extent; 3710b57cec5SDimitry Andric 3720b57cec5SDimitry Andric// [span.cons], span constructors, copy, assignment, and destructor 3730b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr span() noexcept : __data{nullptr}, __size{0} {} 3740b57cec5SDimitry Andric 3750b57cec5SDimitry Andric constexpr span (const span&) noexcept = default; 3760b57cec5SDimitry Andric constexpr span& operator=(const span&) noexcept = default; 3770b57cec5SDimitry Andric 378*480093f4SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr span(pointer __ptr, size_type __count) : __data{__ptr}, __size{__count} {} 3790b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr span(pointer __f, pointer __l) : __data{__f}, __size{static_cast<size_t>(distance(__f, __l))} {} 3800b57cec5SDimitry Andric 3810b57cec5SDimitry Andric template <size_t _Sz> 3820b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3830b57cec5SDimitry Andric constexpr span(element_type (&__arr)[_Sz]) noexcept : __data{__arr}, __size{_Sz} {} 3840b57cec5SDimitry Andric 3850b57cec5SDimitry Andric template <size_t _Sz> 3860b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3870b57cec5SDimitry Andric constexpr span(array<value_type, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {} 3880b57cec5SDimitry Andric 3890b57cec5SDimitry Andric template <size_t _Sz> 3900b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3910b57cec5SDimitry Andric constexpr span(const array<value_type, _Sz>& __arr) noexcept : __data{__arr.data()}, __size{_Sz} {} 3920b57cec5SDimitry Andric 3930b57cec5SDimitry Andric template <class _Container> 3940b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 3950b57cec5SDimitry Andric constexpr span( _Container& __c, 3960b57cec5SDimitry Andric enable_if_t<__is_span_compatible_container<_Container, _Tp>::value, nullptr_t> = nullptr) 397*480093f4SDimitry Andric : __data{_VSTD::data(__c)}, __size{(size_type) _VSTD::size(__c)} {} 3980b57cec5SDimitry Andric 3990b57cec5SDimitry Andric template <class _Container> 4000b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 4010b57cec5SDimitry Andric constexpr span(const _Container& __c, 4020b57cec5SDimitry Andric enable_if_t<__is_span_compatible_container<const _Container, _Tp>::value, nullptr_t> = nullptr) 403*480093f4SDimitry Andric : __data{_VSTD::data(__c)}, __size{(size_type) _VSTD::size(__c)} {} 4040b57cec5SDimitry Andric 4050b57cec5SDimitry Andric 4060b57cec5SDimitry Andric template <class _OtherElementType, size_t _OtherExtent> 4070b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 4080b57cec5SDimitry Andric constexpr span(const span<_OtherElementType, _OtherExtent>& __other, 4090b57cec5SDimitry Andric enable_if_t< 4100b57cec5SDimitry Andric is_convertible_v<_OtherElementType(*)[], element_type (*)[]>, 4110b57cec5SDimitry Andric nullptr_t> = nullptr) noexcept 4120b57cec5SDimitry Andric : __data{__other.data()}, __size{__other.size()} {} 4130b57cec5SDimitry Andric 4140b57cec5SDimitry Andric// ~span() noexcept = default; 4150b57cec5SDimitry Andric 4160b57cec5SDimitry Andric template <size_t _Count> 4170b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 4180b57cec5SDimitry Andric constexpr span<element_type, _Count> first() const noexcept 4190b57cec5SDimitry Andric { 4200b57cec5SDimitry Andric _LIBCPP_ASSERT(_Count <= size(), "Count out of range in span::first()"); 4210b57cec5SDimitry Andric return {data(), _Count}; 4220b57cec5SDimitry Andric } 4230b57cec5SDimitry Andric 4240b57cec5SDimitry Andric template <size_t _Count> 4250b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 4260b57cec5SDimitry Andric constexpr span<element_type, _Count> last() const noexcept 4270b57cec5SDimitry Andric { 4280b57cec5SDimitry Andric _LIBCPP_ASSERT(_Count <= size(), "Count out of range in span::last()"); 4290b57cec5SDimitry Andric return {data() + size() - _Count, _Count}; 4300b57cec5SDimitry Andric } 4310b57cec5SDimitry Andric 4320b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 433*480093f4SDimitry Andric constexpr span<element_type, dynamic_extent> first(size_type __count) const noexcept 4340b57cec5SDimitry Andric { 4350b57cec5SDimitry Andric _LIBCPP_ASSERT(__count <= size(), "Count out of range in span::first(count)"); 4360b57cec5SDimitry Andric return {data(), __count}; 4370b57cec5SDimitry Andric } 4380b57cec5SDimitry Andric 4390b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 440*480093f4SDimitry Andric constexpr span<element_type, dynamic_extent> last (size_type __count) const noexcept 4410b57cec5SDimitry Andric { 4420b57cec5SDimitry Andric _LIBCPP_ASSERT(__count <= size(), "Count out of range in span::last(count)"); 4430b57cec5SDimitry Andric return {data() + size() - __count, __count}; 4440b57cec5SDimitry Andric } 4450b57cec5SDimitry Andric 4460b57cec5SDimitry Andric template <size_t _Offset, size_t _Count = dynamic_extent> 4470b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 4480b57cec5SDimitry Andric constexpr span<_Tp, dynamic_extent> subspan() const noexcept 4490b57cec5SDimitry Andric { 4500b57cec5SDimitry Andric _LIBCPP_ASSERT(_Offset <= size(), "Offset out of range in span::subspan()"); 4510b57cec5SDimitry Andric _LIBCPP_ASSERT(_Count == dynamic_extent || _Offset + _Count <= size(), "Count out of range in span::subspan()"); 4520b57cec5SDimitry Andric return {data() + _Offset, _Count == dynamic_extent ? size() - _Offset : _Count}; 4530b57cec5SDimitry Andric } 4540b57cec5SDimitry Andric 4550b57cec5SDimitry Andric constexpr span<element_type, dynamic_extent> 4560b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY 457*480093f4SDimitry Andric subspan(size_type __offset, size_type __count = dynamic_extent) const noexcept 4580b57cec5SDimitry Andric { 4590b57cec5SDimitry Andric _LIBCPP_ASSERT(__offset <= size(), "Offset out of range in span::subspan(offset, count)"); 4600b57cec5SDimitry Andric _LIBCPP_ASSERT(__count <= size() || __count == dynamic_extent, "count out of range in span::subspan(offset, count)"); 4610b57cec5SDimitry Andric if (__count == dynamic_extent) 4620b57cec5SDimitry Andric return {data() + __offset, size() - __offset}; 4630b57cec5SDimitry Andric _LIBCPP_ASSERT(__offset <= size() - __count, "Offset + count out of range in span::subspan(offset, count)"); 4640b57cec5SDimitry Andric return {data() + __offset, __count}; 4650b57cec5SDimitry Andric } 4660b57cec5SDimitry Andric 467*480093f4SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr size_type size() const noexcept { return __size; } 468*480093f4SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr size_type size_bytes() const noexcept { return __size * sizeof(element_type); } 4690b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr bool empty() const noexcept { return __size == 0; } 4700b57cec5SDimitry Andric 471*480093f4SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr reference operator[](size_type __idx) const noexcept 4720b57cec5SDimitry Andric { 4730b57cec5SDimitry Andric _LIBCPP_ASSERT(__idx >= 0 && __idx < size(), "span<T>[] index out of bounds"); 4740b57cec5SDimitry Andric return __data[__idx]; 4750b57cec5SDimitry Andric } 4760b57cec5SDimitry Andric 4770b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr reference front() const noexcept 4780b57cec5SDimitry Andric { 4790b57cec5SDimitry Andric _LIBCPP_ASSERT(!empty(), "span<T>[].front() on empty span"); 4800b57cec5SDimitry Andric return __data[0]; 4810b57cec5SDimitry Andric } 4820b57cec5SDimitry Andric 4830b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr reference back() const noexcept 4840b57cec5SDimitry Andric { 4850b57cec5SDimitry Andric _LIBCPP_ASSERT(!empty(), "span<T>[].back() on empty span"); 4860b57cec5SDimitry Andric return __data[size()-1]; 4870b57cec5SDimitry Andric } 4880b57cec5SDimitry Andric 4890b57cec5SDimitry Andric 4900b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr pointer data() const noexcept { return __data; } 4910b57cec5SDimitry Andric 4920b57cec5SDimitry Andric// [span.iter], span iterator support 4930b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr iterator begin() const noexcept { return iterator(data()); } 4940b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr iterator end() const noexcept { return iterator(data() + size()); } 4950b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr const_iterator cbegin() const noexcept { return const_iterator(data()); } 4960b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr const_iterator cend() const noexcept { return const_iterator(data() + size()); } 4970b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rbegin() const noexcept { return reverse_iterator(end()); } 4980b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr reverse_iterator rend() const noexcept { return reverse_iterator(begin()); } 4990b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr const_reverse_iterator crbegin() const noexcept { return const_reverse_iterator(cend()); } 5000b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr const_reverse_iterator crend() const noexcept { return const_reverse_iterator(cbegin()); } 5010b57cec5SDimitry Andric 5020b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY constexpr void swap(span &__other) noexcept 5030b57cec5SDimitry Andric { 5040b57cec5SDimitry Andric pointer __p = __data; 5050b57cec5SDimitry Andric __data = __other.__data; 5060b57cec5SDimitry Andric __other.__data = __p; 5070b57cec5SDimitry Andric 508*480093f4SDimitry Andric size_type __sz = __size; 5090b57cec5SDimitry Andric __size = __other.__size; 5100b57cec5SDimitry Andric __other.__size = __sz; 5110b57cec5SDimitry Andric } 5120b57cec5SDimitry Andric 5130b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY span<const byte, dynamic_extent> __as_bytes() const noexcept 5140b57cec5SDimitry Andric { return {reinterpret_cast<const byte *>(data()), size_bytes()}; } 5150b57cec5SDimitry Andric 5160b57cec5SDimitry Andric _LIBCPP_INLINE_VISIBILITY span<byte, dynamic_extent> __as_writable_bytes() const noexcept 5170b57cec5SDimitry Andric { return {reinterpret_cast<byte *>(data()), size_bytes()}; } 5180b57cec5SDimitry Andric 5190b57cec5SDimitry Andricprivate: 5200b57cec5SDimitry Andric pointer __data; 521*480093f4SDimitry Andric size_type __size; 5220b57cec5SDimitry Andric}; 5230b57cec5SDimitry Andric 5240b57cec5SDimitry Andric// tuple interface 5250b57cec5SDimitry Andrictemplate <class _Tp, size_t _Size> 5260b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS tuple_size<span<_Tp, _Size>> 5270b57cec5SDimitry Andric : public integral_constant<size_t, _Size> {}; 5280b57cec5SDimitry Andric 5290b57cec5SDimitry Andrictemplate <class _Tp> 5300b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS tuple_size<span<_Tp, dynamic_extent>>; // declared but not defined 5310b57cec5SDimitry Andric 5320b57cec5SDimitry Andric 5330b57cec5SDimitry Andrictemplate <size_t _Ip, class _Tp, size_t _Size> 5340b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, span<_Tp, _Size>> 5350b57cec5SDimitry Andric{ 5360b57cec5SDimitry Andric static_assert( dynamic_extent != _Size, "std::tuple_element<> not supported for std::span<T, dynamic_extent>"); 5370b57cec5SDimitry Andric static_assert(_Ip < _Size, "Index out of bounds in std::tuple_element<> (std::span)"); 5380b57cec5SDimitry Andric typedef _Tp type; 5390b57cec5SDimitry Andric}; 5400b57cec5SDimitry Andric 5410b57cec5SDimitry Andrictemplate <size_t _Ip, class _Tp, size_t _Size> 5420b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY constexpr 5430b57cec5SDimitry Andric_Tp& 5440b57cec5SDimitry Andricget(span<_Tp, _Size> __s) noexcept 5450b57cec5SDimitry Andric{ 5460b57cec5SDimitry Andric static_assert( dynamic_extent != _Size, "std::get<> not supported for std::span<T, dynamic_extent>"); 5470b57cec5SDimitry Andric static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::span)"); 5480b57cec5SDimitry Andric return __s[_Ip]; 5490b57cec5SDimitry Andric} 5500b57cec5SDimitry Andric 5510b57cec5SDimitry Andric 5520b57cec5SDimitry Andric// as_bytes & as_writable_bytes 5530b57cec5SDimitry Andrictemplate <class _Tp, size_t _Extent> 5540b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 5550b57cec5SDimitry Andricauto as_bytes(span<_Tp, _Extent> __s) noexcept 5560b57cec5SDimitry Andric-> decltype(__s.__as_bytes()) 5570b57cec5SDimitry Andric{ return __s.__as_bytes(); } 5580b57cec5SDimitry Andric 5590b57cec5SDimitry Andrictemplate <class _Tp, size_t _Extent> 5600b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 5610b57cec5SDimitry Andricauto as_writable_bytes(span<_Tp, _Extent> __s) noexcept 5620b57cec5SDimitry Andric-> enable_if_t<!is_const_v<_Tp>, decltype(__s.__as_writable_bytes())> 5630b57cec5SDimitry Andric{ return __s.__as_writable_bytes(); } 5640b57cec5SDimitry Andric 5650b57cec5SDimitry Andrictemplate <class _Tp, size_t _Extent> 5660b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY 5670b57cec5SDimitry Andricconstexpr void swap(span<_Tp, _Extent> &__lhs, span<_Tp, _Extent> &__rhs) noexcept 5680b57cec5SDimitry Andric{ __lhs.swap(__rhs); } 5690b57cec5SDimitry Andric 5700b57cec5SDimitry Andric 5710b57cec5SDimitry Andric// Deduction guides 5720b57cec5SDimitry Andrictemplate<class _Tp, size_t _Sz> 5730b57cec5SDimitry Andric span(_Tp (&)[_Sz]) -> span<_Tp, _Sz>; 5740b57cec5SDimitry Andric 5750b57cec5SDimitry Andrictemplate<class _Tp, size_t _Sz> 5760b57cec5SDimitry Andric span(array<_Tp, _Sz>&) -> span<_Tp, _Sz>; 5770b57cec5SDimitry Andric 5780b57cec5SDimitry Andrictemplate<class _Tp, size_t _Sz> 5790b57cec5SDimitry Andric span(const array<_Tp, _Sz>&) -> span<const _Tp, _Sz>; 5800b57cec5SDimitry Andric 5810b57cec5SDimitry Andrictemplate<class _Container> 5820b57cec5SDimitry Andric span(_Container&) -> span<typename _Container::value_type>; 5830b57cec5SDimitry Andric 5840b57cec5SDimitry Andrictemplate<class _Container> 5850b57cec5SDimitry Andric span(const _Container&) -> span<const typename _Container::value_type>; 5860b57cec5SDimitry Andric 5870b57cec5SDimitry Andric#endif // _LIBCPP_STD_VER > 17 5880b57cec5SDimitry Andric 5890b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD 5900b57cec5SDimitry Andric 5910b57cec5SDimitry Andric#endif // _LIBCPP_SPAN 592