This commit is contained in:
2025-10-25 03:02:53 +03:00
commit 043225d523
3416 changed files with 681196 additions and 0 deletions

View File

@@ -0,0 +1,810 @@
[views.contiguous]
# 23 Containers library [[containers]](./#containers)
## 23.7 Views [[views]](views#contiguous)
### 23.7.2 Contiguous access [views.contiguous]
#### [23.7.2.1](#span.syn) Header <span> synopsis [[span.syn]](span.syn)
[🔗](#header:%3cspan%3e)
#include <initializer_list> // see [[initializer.list.syn]](initializer.list.syn "17.11.2Header <initializer_­list> synopsis")// mostly freestandingnamespace std {// constantsinline constexpr size_t [dynamic_extent](#lib:dynamic_extent "23.7.2.1Header <span> synopsis[span.syn]") = numeric_limits<size_t>::max(); template<class T>concept [*integral-constant-like*](#concept:integral-constant-like "23.7.2.1Header <span> synopsis[span.syn]") = // *exposition only* is_integral_v<remove_cvref_t<decltype(T::value)>> &&!is_same_v<bool, remove_const_t<decltype(T::value)>> &&[convertible_to](concept.convertible#concept:convertible_to "18.4.4Concept convertible_­to[concept.convertible]")<T, decltype(T::value)> &&[equality_comparable_with](concept.equalitycomparable#concept:equality_comparable_with "18.5.4Concept equality_­comparable[concept.equalitycomparable]")<T, decltype(T::value)> && bool_constant<T() == T::value>::value && bool_constant<static_cast<decltype(T::value)>(T()) == T::value>::value; template<class T>constexpr size_t [*maybe-static-ext*](#concept:maybe-static-ext "23.7.2.1Header <span> synopsis[span.syn]") = dynamic_extent; // *exposition only*template<[*integral-constant-like*](#concept:integral-constant-like "23.7.2.1Header <span> synopsis[span.syn]") T>constexpr size_t [*maybe-static-ext*](#concept:maybe-static-ext "23.7.2.1Header <span> synopsis[span.syn]")<T> = {T::value}; // [[views.span]](#views.span "23.7.2.2Class template span"), class template spantemplate<class ElementType, size_t Extent = dynamic_extent>class span; // partially freestandingtemplate<class ElementType, size_t Extent>constexpr bool ranges::enable_view<span<ElementType, Extent>> = true; template<class ElementType, size_t Extent>constexpr bool ranges::enable_borrowed_range<span<ElementType, Extent>> = true; // [[span.objectrep]](#span.objectrep "23.7.2.3Views of object representation"), views of object representationtemplate<class ElementType, size_t Extent> span<const byte, Extent == dynamic_extent ? dynamic_extent : sizeof(ElementType) * Extent> as_bytes(span<ElementType, Extent> s) noexcept; template<class ElementType, size_t Extent> span<byte, Extent == dynamic_extent ? dynamic_extent : sizeof(ElementType) * Extent> as_writable_bytes(span<ElementType, Extent> s) noexcept;}
#### [23.7.2.2](#views.span) Class template span [[views.span]](views.span)
#### [23.7.2.2.1](#span.overview) Overview [[span.overview]](span.overview)
[1](#span.overview-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20218)
A span is a view over a contiguous sequence of objects,
the storage of which is owned by some other object[.](#span.overview-1.sentence-1)
[2](#span.overview-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20223)
All member functions of span have constant time complexity[.](#span.overview-2.sentence-1)
[🔗](#lib:span_)
namespace std {template<class ElementType, size_t Extent = dynamic_extent>class span {public:// constants and typesusing element_type = ElementType; using value_type = remove_cv_t<ElementType>; using size_type = size_t; using difference_type = ptrdiff_t; using pointer = element_type*; using const_pointer = const element_type*; using reference = element_type&; using const_reference = const element_type&; using iterator = *implementation-defined*; // see [[span.iterators]](#span.iterators "23.7.2.2.7Iterator support")using const_iterator = std::const_iterator<iterator>; using reverse_iterator = std::reverse_iterator<iterator>; using const_reverse_iterator = std::const_iterator<reverse_iterator>; static constexpr size_type extent = Extent; // [[span.cons]](#span.cons "23.7.2.2.2Constructors, copy, and assignment"), constructors, copy, and assignmentconstexpr span() noexcept; template<class It>constexpr explicit(extent != dynamic_extent) span(It first, size_type count); template<class It, class End>constexpr explicit(extent != dynamic_extent) span(It first, End last); template<size_t N>constexpr span(type_identity_t<element_type> (&arr)[N]) noexcept; template<class T, size_t N>constexpr span(array<T, N>& arr) noexcept; template<class T, size_t N>constexpr span(const array<T, N>& arr) noexcept; template<class R>constexpr explicit(extent != dynamic_extent) span(R&& r); constexpr explicit(extent != dynamic_extent) span(std::initializer_list<value_type> il); constexpr span(const span& other) noexcept = default; template<class OtherElementType, size_t OtherExtent>constexpr explicit(*see below*) span(const span<OtherElementType, OtherExtent>& s) noexcept; constexpr span& operator=(const span& other) noexcept = default; // [[span.sub]](#span.sub "23.7.2.2.4Subviews"), subviewstemplate<size_t Count>constexpr span<element_type, Count> first() const; template<size_t Count>constexpr span<element_type, Count> last() const; template<size_t Offset, size_t Count = dynamic_extent>constexpr span<element_type, *see below*> subspan() const; constexpr span<element_type, dynamic_extent> first(size_type count) const; constexpr span<element_type, dynamic_extent> last(size_type count) const; constexpr span<element_type, dynamic_extent> subspan( size_type offset, size_type count = dynamic_extent) const; // [[span.obs]](#span.obs "23.7.2.2.5Observers"), observersconstexpr size_type size() const noexcept; constexpr size_type size_bytes() const noexcept; constexpr bool empty() const noexcept; // [[span.elem]](#span.elem "23.7.2.2.6Element access"), element accessconstexpr reference operator[](size_type idx) const; constexpr reference at(size_type idx) const; // freestanding-deletedconstexpr reference front() const; constexpr reference back() const; constexpr pointer data() const noexcept; // [[span.iterators]](#span.iterators "23.7.2.2.7Iterator support"), iterator supportconstexpr iterator begin() const noexcept; constexpr iterator end() const noexcept; constexpr const_iterator cbegin() const noexcept { return begin(); }constexpr const_iterator cend() const noexcept { return end(); }constexpr reverse_iterator rbegin() const noexcept; constexpr reverse_iterator rend() const noexcept; constexpr const_reverse_iterator crbegin() const noexcept { return rbegin(); }constexpr const_reverse_iterator crend() const noexcept { return rend(); }private: pointer *data_*; // *exposition only* size_type *size_*; // *exposition only*}; template<class It, class EndOrSize> span(It, EndOrSize) -> span<remove_reference_t<iter_reference_t<It>>, [*maybe-static-ext*](#concept:maybe-static-ext "23.7.2.1Header <span> synopsis[span.syn]")<EndOrSize>>; template<class T, size_t N> span(T (&)[N]) -> span<T, N>; template<class T, size_t N> span(array<T, N>&) -> span<T, N>; template<class T, size_t N> span(const array<T, N>&) -> span<const T, N>; template<class R> span(R&&) -> span<remove_reference_t<ranges::range_reference_t<R>>>;}
[3](#span.overview-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20322)
span<ElementType, Extent> is
a trivially copyable type ([[basic.types.general]](basic.types.general#term.trivially.copyable.type "6.9.1General"))[.](#span.overview-3.sentence-1)
[4](#span.overview-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20326)
ElementType is required to be
a complete object type that is not an abstract class type[.](#span.overview-4.sentence-1)
[5](#span.overview-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20330)
For a span s,
any operation that invalidates a pointer in
the range [s.data(), s.data() + s.size())
invalidates pointers, iterators, and references to elements of s[.](#span.overview-5.sentence-1)
#### [23.7.2.2.2](#span.cons) Constructors, copy, and assignment [[span.cons]](span.cons)
[🔗](#lib:span,constructor)
`constexpr span() noexcept;
`
[1](#span.cons-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20344)
*Constraints*: Extent == dynamic_extent || Extent == 0 is true[.](#span.cons-1.sentence-1)
[2](#span.cons-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20348)
*Postconditions*: size() == 0 && data() == nullptr[.](#span.cons-2.sentence-1)
[🔗](#lib:span,constructor_)
`template<class It>
constexpr explicit(extent != dynamic_extent) span(It first, size_type count);
`
[3](#span.cons-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20361)
*Constraints*: Let U be remove_reference_t<iter_reference_t<It>>[.](#span.cons-3.sentence-1)
- [(3.1)](#span.cons-3.1)
It satisfies [contiguous_iterator](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]")[.](#span.cons-3.1.sentence-1)
- [(3.2)](#span.cons-3.2)
is_convertible_v<U(*)[], element_type(*)[]> is true[.](#span.cons-3.2.sentence-1)
[*Note [1](#span.cons-note-1)*:
The intent is to allow only qualification conversions
of the iterator reference type to element_type[.](#span.cons-3.2.sentence-2)
— *end note*]
[4](#span.cons-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20374)
*Preconditions*:
- [(4.1)](#span.cons-4.1)
[first, first + count) is a valid range[.](#span.cons-4.1.sentence-1)
- [(4.2)](#span.cons-4.2)
It models [contiguous_iterator](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]")[.](#span.cons-4.2.sentence-1)
[5](#span.cons-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20381)
*Hardened preconditions*: If extent is not equal to dynamic_extent,
then count == extent is true[.](#span.cons-5.sentence-1)
[6](#span.cons-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20386)
*Effects*: Initializes *data_* with to_address(first) and*size_* with count[.](#span.cons-6.sentence-1)
[7](#span.cons-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20391)
*Throws*: Nothing[.](#span.cons-7.sentence-1)
[🔗](#lib:span,constructor__)
`template<class It, class End>
constexpr explicit(extent != dynamic_extent) span(It first, End last);
`
[8](#span.cons-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20403)
*Constraints*: Let U be remove_reference_t<iter_reference_t<It>>[.](#span.cons-8.sentence-1)
- [(8.1)](#span.cons-8.1)
is_convertible_v<U(*)[], element_type(*)[]> is true[.](#span.cons-8.1.sentence-1)
[*Note [2](#span.cons-note-2)*:
The intent is to allow only qualification conversions
of the iterator reference type to element_type[.](#span.cons-8.1.sentence-2)
— *end note*]
- [(8.2)](#span.cons-8.2)
It satisfies [contiguous_iterator](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]")[.](#span.cons-8.2.sentence-1)
- [(8.3)](#span.cons-8.3)
End satisfies [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<It>[.](#span.cons-8.3.sentence-1)
- [(8.4)](#span.cons-8.4)
is_convertible_v<End, size_t> is false[.](#span.cons-8.4.sentence-1)
[9](#span.cons-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20418)
*Preconditions*:
- [(9.1)](#span.cons-9.1)
[first, last) is a valid range[.](#span.cons-9.1.sentence-1)
- [(9.2)](#span.cons-9.2)
It models [contiguous_iterator](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]")[.](#span.cons-9.2.sentence-1)
- [(9.3)](#span.cons-9.3)
End models [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<It>[.](#span.cons-9.3.sentence-1)
[10](#span.cons-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20426)
*Hardened preconditions*: If extent is not equal to dynamic_extent,
then (last - first) == extent is true[.](#span.cons-10.sentence-1)
[11](#span.cons-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20431)
*Effects*: Initializes *data_* with to_address(first) and*size_* with last - first[.](#span.cons-11.sentence-1)
[12](#span.cons-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20436)
*Throws*: When and what last - first throws[.](#span.cons-12.sentence-1)
[🔗](#lib:span,constructor___)
`template<size_t N> constexpr span(type_identity_t<element_type> (&arr)[N]) noexcept;
template<class T, size_t N> constexpr span(array<T, N>& arr) noexcept;
template<class T, size_t N> constexpr span(const array<T, N>& arr) noexcept;
`
[13](#span.cons-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20449)
*Constraints*: Let U be remove_pointer_t<decltype(std::data(arr))>[.](#span.cons-13.sentence-1)
- [(13.1)](#span.cons-13.1)
extent == dynamic_extent || N == extent is true, and
- [(13.2)](#span.cons-13.2)
is_convertible_v<U(*)[], element_type(*)[]> is true. [*Note [3](#span.cons-note-3)*:
The intent is to allow only qualification conversions
of the array element type to element_type[.](#span.cons-13.2.sentence-2)
— *end note*]
[14](#span.cons-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20461)
*Effects*: Constructs a span that is a view over the supplied array[.](#span.cons-14.sentence-1)
[*Note [4](#span.cons-note-4)*:
type_identity_t affects class template argument deduction[.](#span.cons-14.sentence-2)
— *end note*]
[15](#span.cons-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20468)
*Postconditions*: size() == N && data() == std::data(arr) is true[.](#span.cons-15.sentence-1)
[🔗](#lib:span,constructor____)
`template<class R> constexpr explicit(extent != dynamic_extent) span(R&& r);
`
[16](#span.cons-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20479)
*Constraints*: Let U be remove_reference_t<ranges::range_reference_t<R>>[.](#span.cons-16.sentence-1)
- [(16.1)](#span.cons-16.1)
R satisfies ranges::[contiguous_range](range.refinements#concept:contiguous_range "25.4.6Other range refinements[range.refinements]") and ranges::[sized_range](range.sized#concept:sized_range "25.4.4Sized ranges[range.sized]")[.](#span.cons-16.1.sentence-1)
- [(16.2)](#span.cons-16.2)
Either R satisfies ranges::[borrowed_range](range.range#concept:borrowed_range "25.4.2Ranges[range.range]") oris_const_v<element_type> is true[.](#span.cons-16.2.sentence-1)
- [(16.3)](#span.cons-16.3)
remove_cvref_t<R> is not a specialization of span[.](#span.cons-16.3.sentence-1)
- [(16.4)](#span.cons-16.4)
remove_cvref_t<R> is not a specialization of array[.](#span.cons-16.4.sentence-1)
- [(16.5)](#span.cons-16.5)
is_array_v<remove_cvref_t<R>> is false[.](#span.cons-16.5.sentence-1)
- [(16.6)](#span.cons-16.6)
is_convertible_v<U(*)[], element_type(*)[]> is true[.](#span.cons-16.6.sentence-1)
[*Note [5](#span.cons-note-5)*:
The intent is to allow only qualification conversions
of the range reference type to element_type[.](#span.cons-16.6.sentence-2)
— *end note*]
[17](#span.cons-17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20498)
*Preconditions*:
- [(17.1)](#span.cons-17.1)
R models ranges::[contiguous_range](range.refinements#concept:contiguous_range "25.4.6Other range refinements[range.refinements]") andranges::[sized_range](range.sized#concept:sized_range "25.4.4Sized ranges[range.sized]")[.](#span.cons-17.1.sentence-1)
- [(17.2)](#span.cons-17.2)
If is_const_v<element_type> is false,R models ranges::[borrowed_range](range.range#concept:borrowed_range "25.4.2Ranges[range.range]")[.](#span.cons-17.2.sentence-1)
[18](#span.cons-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20507)
*Hardened preconditions*: If extent is not equal to dynamic_extent,
then ranges::size(r) == extent is true[.](#span.cons-18.sentence-1)
[19](#span.cons-19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20512)
*Effects*: Initializes *data_* with ranges::data(r) and*size_* with ranges::size(r)[.](#span.cons-19.sentence-1)
[20](#span.cons-20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20517)
*Throws*: What and when ranges::data(r) and ranges::size(r) throw[.](#span.cons-20.sentence-1)
[🔗](#lib:span,constructor_____)
`constexpr explicit(extent != dynamic_extent) span(std::initializer_list<value_type> il);
`
[21](#span.cons-21)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20528)
*Constraints*: is_const_v<element_type> is true[.](#span.cons-21.sentence-1)
[22](#span.cons-22)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20532)
*Hardened preconditions*: If extent is not equal to dynamic_extent,
then il.size() == extent is true[.](#span.cons-22.sentence-1)
[23](#span.cons-23)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20537)
*Effects*: Initializes *data_* with il.begin() and*size_* with il.size()[.](#span.cons-23.sentence-1)
[🔗](#lib:span,constructor______)
`constexpr span(const span& other) noexcept = default;
`
[24](#span.cons-24)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20549)
*Postconditions*: other.size() == size() && other.data() == data()[.](#span.cons-24.sentence-1)
[🔗](#lib:span,constructor_______)
`template<class OtherElementType, size_t OtherExtent>
constexpr explicit(see below) span(const span<OtherElementType, OtherExtent>& s) noexcept;
`
[25](#span.cons-25)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20561)
*Constraints*:
- [(25.1)](#span.cons-25.1)
extent == dynamic_extent || OtherExtent == dynamic_extent || extent == OtherExtent is true, and
- [(25.2)](#span.cons-25.2)
is_convertible_v<OtherElementType(*)[], element_type(*)[]> is true[.](#span.cons-25.sentence-1)
[*Note [6](#span.cons-note-6)*:
The intent is to allow only qualification conversions
of the OtherElementType to element_type[.](#span.cons-25.2.sentence-2)
— *end note*]
[26](#span.cons-26)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20572)
*Hardened preconditions*: If extent is not equal to dynamic_extent,
then s.size() == extent is true[.](#span.cons-26.sentence-1)
[27](#span.cons-27)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20577)
*Effects*: Constructs a span that is a view over the range
[s.data(), s.data() + s.size())[.](#span.cons-27.sentence-1)
[28](#span.cons-28)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20582)
*Postconditions*: size() == s.size() && data() == s.data()[.](#span.cons-28.sentence-1)
[29](#span.cons-29)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20586)
*Remarks*: The expression inside explicit is equivalent to:extent != dynamic_extent && OtherExtent == dynamic_extent
[🔗](#lib:operator=,span)
`constexpr span& operator=(const span& other) noexcept = default;
`
[30](#span.cons-30)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20600)
*Postconditions*: size() == other.size() && data() == other.data()[.](#span.cons-30.sentence-1)
#### [23.7.2.2.3](#span.deduct) Deduction guides [[span.deduct]](span.deduct)
[🔗](#lib:span,deduction_guide)
`template<class It, class EndOrSize>
span(It, EndOrSize) -> span<remove_reference_t<iter_reference_t<It>>,
[maybe-static-ext](#concept:maybe-static-ext "23.7.2.1Header <span> synopsis[span.syn]")<EndOrSize>>;
`
[1](#span.deduct-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20615)
*Constraints*: It satisfies [contiguous_iterator](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]")[.](#span.deduct-1.sentence-1)
[🔗](#lib:span,deduction_guide_)
`template<class R>
span(R&&) -> span<remove_reference_t<ranges::range_reference_t<R>>>;
`
[2](#span.deduct-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20627)
*Constraints*: R satisfies ranges::[contiguous_range](range.refinements#concept:contiguous_range "25.4.6Other range refinements[range.refinements]")[.](#span.deduct-2.sentence-1)
#### [23.7.2.2.4](#span.sub) Subviews [[span.sub]](span.sub)
[🔗](#lib:span,first)
`template<size_t Count> constexpr span<element_type, Count> first() const;
`
[1](#span.sub-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20640)
*Mandates*: Count <= Extent is true[.](#span.sub-1.sentence-1)
[2](#span.sub-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20644)
*Hardened preconditions*: Count <= size() is true[.](#span.sub-2.sentence-1)
[3](#span.sub-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20648)
*Effects*: Equivalent to: return R{data(), Count}; where R is the return type[.](#span.sub-3.sentence-1)
[🔗](#lib:span,last)
`template<size_t Count> constexpr span<element_type, Count> last() const;
`
[4](#span.sub-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20660)
*Mandates*: Count <= Extent is true[.](#span.sub-4.sentence-1)
[5](#span.sub-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20664)
*Hardened preconditions*: Count <= size() is true[.](#span.sub-5.sentence-1)
[6](#span.sub-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20668)
*Effects*: Equivalent to: return R{data() + (size() - Count), Count}; where R is the return type[.](#span.sub-6.sentence-1)
[🔗](#lib:span,subspan)
`template<size_t Offset, size_t Count = dynamic_extent>
constexpr span<element_type, see below> subspan() const;
`
[7](#span.sub-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20681)
*Mandates*: Offset <= Extent && (Count == dynamic_extent || Count <= Extent - Offset) is true[.](#span.sub-7.sentence-1)
[8](#span.sub-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20688)
*Hardened preconditions*: Offset <= size() && (Count == dynamic_extent || Count <= size() - Offset) is true[.](#span.sub-8.sentence-1)
[9](#span.sub-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20695)
*Effects*: Equivalent to:return span<ElementType, *see below*>( data() + Offset, Count != dynamic_extent ? Count : size() - Offset);
[10](#span.sub-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20703)
*Remarks*: The second template argument of the returned span type is:Count != dynamic_extent ? Count : (Extent != dynamic_extent ? Extent - Offset : dynamic_extent)
[🔗](#lib:span,first_)
`constexpr span<element_type, dynamic_extent> first(size_type count) const;
`
[11](#span.sub-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20719)
*Hardened preconditions*: count <= size() is true[.](#span.sub-11.sentence-1)
[12](#span.sub-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20723)
*Effects*: Equivalent to: return {data(), count};
[🔗](#lib:span,last_)
`constexpr span<element_type, dynamic_extent> last(size_type count) const;
`
[13](#span.sub-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20734)
*Hardened preconditions*: count <= size() is true[.](#span.sub-13.sentence-1)
[14](#span.sub-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20738)
*Effects*: Equivalent to: return {data() + (size() - count), count};
[🔗](#lib:span,subspan_)
`constexpr span<element_type, dynamic_extent> subspan(
size_type offset, size_type count = dynamic_extent) const;
`
[15](#span.sub-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20750)
*Hardened preconditions*: offset <= size() && (count == dynamic_extent || count <= size() - offset) is true[.](#span.sub-15.sentence-1)
[16](#span.sub-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20757)
*Effects*: Equivalent to:return {data() + offset, count == dynamic_extent ? size() - offset : count};
#### [23.7.2.2.5](#span.obs) Observers [[span.obs]](span.obs)
[🔗](#lib:span,size)
`constexpr size_type size() const noexcept;
`
[1](#span.obs-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20773)
*Effects*: Equivalent to: return *size_*;
[🔗](#lib:span,size_bytes)
`constexpr size_type size_bytes() const noexcept;
`
[2](#span.obs-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20784)
*Effects*: Equivalent to: return size() * sizeof(element_type);
[🔗](#lib:span,empty)
`constexpr bool empty() const noexcept;
`
[3](#span.obs-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20795)
*Effects*: Equivalent to: return size() == 0;
#### [23.7.2.2.6](#span.elem) Element access [[span.elem]](span.elem)
[🔗](#lib:operator%5b%5d,span)
`constexpr reference operator[](size_type idx) const;
`
[1](#span.elem-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20808)
*Hardened preconditions*: idx < size() is true[.](#span.elem-1.sentence-1)
[2](#span.elem-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20812)
*Returns*: *(data() + idx)[.](#span.elem-2.sentence-1)
[3](#span.elem-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20816)
*Throws*: Nothing[.](#span.elem-3.sentence-1)
[🔗](#lib:span,at)
`constexpr reference at(size_type idx) const;
`
[4](#span.elem-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20827)
*Returns*: *(data() + idx)[.](#span.elem-4.sentence-1)
[5](#span.elem-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20831)
*Throws*: out_of_range if idx >= size() is true[.](#span.elem-5.sentence-1)
[🔗](#lib:span,front)
`constexpr reference front() const;
`
[6](#span.elem-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20842)
*Hardened preconditions*: empty() is false[.](#span.elem-6.sentence-1)
[7](#span.elem-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20846)
*Returns*: *data()[.](#span.elem-7.sentence-1)
[8](#span.elem-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20850)
*Throws*: Nothing[.](#span.elem-8.sentence-1)
[🔗](#lib:span,back)
`constexpr reference back() const;
`
[9](#span.elem-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20861)
*Hardened preconditions*: empty() is false[.](#span.elem-9.sentence-1)
[10](#span.elem-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20865)
*Returns*: *(data() + (size() - 1))[.](#span.elem-10.sentence-1)
[11](#span.elem-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20869)
*Throws*: Nothing[.](#span.elem-11.sentence-1)
[🔗](#lib:span,data)
`constexpr pointer data() const noexcept;
`
[12](#span.elem-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20880)
*Returns*: *data_*[.](#span.elem-12.sentence-1)
#### [23.7.2.2.7](#span.iterators) Iterator support [[span.iterators]](span.iterators)
[🔗](#lib:iterator,span)
`using iterator = implementation-defined;
`
[1](#span.iterators-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20893)
The type
models [contiguous_iterator](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]") ([[iterator.concept.contiguous]](iterator.concept.contiguous "24.3.4.14Concept contiguous_­iterator")),
meets the *Cpp17RandomAccessIterator* requirements ([[random.access.iterators]](random.access.iterators "24.3.5.7Random access iterators")),
and
meets the requirements for
constexpr iterators ([[iterator.requirements.general]](iterator.requirements.general "24.3.1General")),
whose value type is value_type and
whose reference type is reference[.](#span.iterators-1.sentence-1)
[2](#span.iterators-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20904)
All requirements on container iterators ([[container.reqmts]](container.reqmts "23.2.2.2Container requirements")) apply tospan::iterator as well[.](#span.iterators-2.sentence-1)
[🔗](#lib:span,begin)
`constexpr iterator begin() const noexcept;
`
[3](#span.iterators-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20915)
*Returns*: An iterator referring to the first element in the span[.](#span.iterators-3.sentence-1)
If empty() is true, then it returns the
same value as end()[.](#span.iterators-3.sentence-2)
[🔗](#lib:span,end)
`constexpr iterator end() const noexcept;
`
[4](#span.iterators-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20928)
*Returns*: An iterator which is the past-the-end value[.](#span.iterators-4.sentence-1)
[🔗](#lib:span,rbegin)
`constexpr reverse_iterator rbegin() const noexcept;
`
[5](#span.iterators-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20939)
*Effects*: Equivalent to: return reverse_iterator(end());
[🔗](#lib:span,rend)
`constexpr reverse_iterator rend() const noexcept;
`
[6](#span.iterators-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20950)
*Effects*: Equivalent to: return reverse_iterator(begin());
#### [23.7.2.3](#span.objectrep) Views of object representation [[span.objectrep]](span.objectrep)
[🔗](#lib:as_bytes)
`template<class ElementType, size_t Extent>
span<const byte, Extent == dynamic_extent ? dynamic_extent : sizeof(ElementType) * Extent>
as_bytes(span<ElementType, Extent> s) noexcept;
`
[1](#span.objectrep-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20965)
*Effects*: Equivalent to: return R{reinterpret_cast<const byte*>(s.data()), s.size_bytes()}; where R is the return type[.](#span.objectrep-1.sentence-1)
[🔗](#lib:as_writable_bytes)
`template<class ElementType, size_t Extent>
span<byte, Extent == dynamic_extent ? dynamic_extent : sizeof(ElementType) * Extent>
as_writable_bytes(span<ElementType, Extent> s) noexcept;
`
[2](#span.objectrep-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20979)
*Constraints*: is_const_v<ElementType> is false[.](#span.objectrep-2.sentence-1)
[3](#span.objectrep-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20983)
*Effects*: Equivalent to: return R{reinterpret_cast<byte*>(s.data()), s.size_bytes()}; where R is the return type[.](#span.objectrep-3.sentence-1)

16
cppdraft/views/general.md Normal file
View File

@@ -0,0 +1,16 @@
[views.general]
# 23 Containers library [[containers]](./#containers)
## 23.7 Views [[views]](views#general)
### 23.7.1 General [views.general]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20162)
The header [<span>](span.syn#header:%3cspan%3e "23.7.2.1Header <span> synopsis[span.syn]") defines the view span[.](#1.sentence-1)
The header [<mdspan>](mdspan.syn#header:%3cmdspan%3e "23.7.3.2Header <mdspan> synopsis[mdspan.syn]") defines the class template mdspan and
other facilities for interacting with these multidimensional views[.](#1.sentence-2)

5222
cppdraft/views/multidim.md Normal file

File diff suppressed because it is too large Load Diff

770
cppdraft/views/span.md Normal file
View File

@@ -0,0 +1,770 @@
[views.span]
# 23 Containers library [[containers]](./#containers)
## 23.7 Views [[views]](views#span)
### 23.7.2 Contiguous access [[views.contiguous]](views.contiguous#views.span)
#### 23.7.2.2 Class template span [views.span]
#### [23.7.2.2.1](#span.overview) Overview [[span.overview]](span.overview)
[1](#span.overview-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20218)
A span is a view over a contiguous sequence of objects,
the storage of which is owned by some other object[.](#span.overview-1.sentence-1)
[2](#span.overview-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20223)
All member functions of span have constant time complexity[.](#span.overview-2.sentence-1)
[🔗](#lib:span_)
namespace std {template<class ElementType, size_t Extent = dynamic_extent>class span {public:// constants and typesusing element_type = ElementType; using value_type = remove_cv_t<ElementType>; using size_type = size_t; using difference_type = ptrdiff_t; using pointer = element_type*; using const_pointer = const element_type*; using reference = element_type&; using const_reference = const element_type&; using iterator = *implementation-defined*; // see [[span.iterators]](#span.iterators "23.7.2.2.7Iterator support")using const_iterator = std::const_iterator<iterator>; using reverse_iterator = std::reverse_iterator<iterator>; using const_reverse_iterator = std::const_iterator<reverse_iterator>; static constexpr size_type extent = Extent; // [[span.cons]](#span.cons "23.7.2.2.2Constructors, copy, and assignment"), constructors, copy, and assignmentconstexpr span() noexcept; template<class It>constexpr explicit(extent != dynamic_extent) span(It first, size_type count); template<class It, class End>constexpr explicit(extent != dynamic_extent) span(It first, End last); template<size_t N>constexpr span(type_identity_t<element_type> (&arr)[N]) noexcept; template<class T, size_t N>constexpr span(array<T, N>& arr) noexcept; template<class T, size_t N>constexpr span(const array<T, N>& arr) noexcept; template<class R>constexpr explicit(extent != dynamic_extent) span(R&& r); constexpr explicit(extent != dynamic_extent) span(std::initializer_list<value_type> il); constexpr span(const span& other) noexcept = default; template<class OtherElementType, size_t OtherExtent>constexpr explicit(*see below*) span(const span<OtherElementType, OtherExtent>& s) noexcept; constexpr span& operator=(const span& other) noexcept = default; // [[span.sub]](#span.sub "23.7.2.2.4Subviews"), subviewstemplate<size_t Count>constexpr span<element_type, Count> first() const; template<size_t Count>constexpr span<element_type, Count> last() const; template<size_t Offset, size_t Count = dynamic_extent>constexpr span<element_type, *see below*> subspan() const; constexpr span<element_type, dynamic_extent> first(size_type count) const; constexpr span<element_type, dynamic_extent> last(size_type count) const; constexpr span<element_type, dynamic_extent> subspan( size_type offset, size_type count = dynamic_extent) const; // [[span.obs]](#span.obs "23.7.2.2.5Observers"), observersconstexpr size_type size() const noexcept; constexpr size_type size_bytes() const noexcept; constexpr bool empty() const noexcept; // [[span.elem]](#span.elem "23.7.2.2.6Element access"), element accessconstexpr reference operator[](size_type idx) const; constexpr reference at(size_type idx) const; // freestanding-deletedconstexpr reference front() const; constexpr reference back() const; constexpr pointer data() const noexcept; // [[span.iterators]](#span.iterators "23.7.2.2.7Iterator support"), iterator supportconstexpr iterator begin() const noexcept; constexpr iterator end() const noexcept; constexpr const_iterator cbegin() const noexcept { return begin(); }constexpr const_iterator cend() const noexcept { return end(); }constexpr reverse_iterator rbegin() const noexcept; constexpr reverse_iterator rend() const noexcept; constexpr const_reverse_iterator crbegin() const noexcept { return rbegin(); }constexpr const_reverse_iterator crend() const noexcept { return rend(); }private: pointer *data_*; // *exposition only* size_type *size_*; // *exposition only*}; template<class It, class EndOrSize> span(It, EndOrSize) -> span<remove_reference_t<iter_reference_t<It>>, [*maybe-static-ext*](span.syn#concept:maybe-static-ext "23.7.2.1Header <span> synopsis[span.syn]")<EndOrSize>>; template<class T, size_t N> span(T (&)[N]) -> span<T, N>; template<class T, size_t N> span(array<T, N>&) -> span<T, N>; template<class T, size_t N> span(const array<T, N>&) -> span<const T, N>; template<class R> span(R&&) -> span<remove_reference_t<ranges::range_reference_t<R>>>;}
[3](#span.overview-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20322)
span<ElementType, Extent> is
a trivially copyable type ([[basic.types.general]](basic.types.general#term.trivially.copyable.type "6.9.1General"))[.](#span.overview-3.sentence-1)
[4](#span.overview-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20326)
ElementType is required to be
a complete object type that is not an abstract class type[.](#span.overview-4.sentence-1)
[5](#span.overview-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20330)
For a span s,
any operation that invalidates a pointer in
the range [s.data(), s.data() + s.size())
invalidates pointers, iterators, and references to elements of s[.](#span.overview-5.sentence-1)
#### [23.7.2.2.2](#span.cons) Constructors, copy, and assignment [[span.cons]](span.cons)
[🔗](#lib:span,constructor)
`constexpr span() noexcept;
`
[1](#span.cons-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20344)
*Constraints*: Extent == dynamic_extent || Extent == 0 is true[.](#span.cons-1.sentence-1)
[2](#span.cons-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20348)
*Postconditions*: size() == 0 && data() == nullptr[.](#span.cons-2.sentence-1)
[🔗](#lib:span,constructor_)
`template<class It>
constexpr explicit(extent != dynamic_extent) span(It first, size_type count);
`
[3](#span.cons-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20361)
*Constraints*: Let U be remove_reference_t<iter_reference_t<It>>[.](#span.cons-3.sentence-1)
- [(3.1)](#span.cons-3.1)
It satisfies [contiguous_iterator](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]")[.](#span.cons-3.1.sentence-1)
- [(3.2)](#span.cons-3.2)
is_convertible_v<U(*)[], element_type(*)[]> is true[.](#span.cons-3.2.sentence-1)
[*Note [1](#span.cons-note-1)*:
The intent is to allow only qualification conversions
of the iterator reference type to element_type[.](#span.cons-3.2.sentence-2)
— *end note*]
[4](#span.cons-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20374)
*Preconditions*:
- [(4.1)](#span.cons-4.1)
[first, first + count) is a valid range[.](#span.cons-4.1.sentence-1)
- [(4.2)](#span.cons-4.2)
It models [contiguous_iterator](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]")[.](#span.cons-4.2.sentence-1)
[5](#span.cons-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20381)
*Hardened preconditions*: If extent is not equal to dynamic_extent,
then count == extent is true[.](#span.cons-5.sentence-1)
[6](#span.cons-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20386)
*Effects*: Initializes *data_* with to_address(first) and*size_* with count[.](#span.cons-6.sentence-1)
[7](#span.cons-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20391)
*Throws*: Nothing[.](#span.cons-7.sentence-1)
[🔗](#lib:span,constructor__)
`template<class It, class End>
constexpr explicit(extent != dynamic_extent) span(It first, End last);
`
[8](#span.cons-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20403)
*Constraints*: Let U be remove_reference_t<iter_reference_t<It>>[.](#span.cons-8.sentence-1)
- [(8.1)](#span.cons-8.1)
is_convertible_v<U(*)[], element_type(*)[]> is true[.](#span.cons-8.1.sentence-1)
[*Note [2](#span.cons-note-2)*:
The intent is to allow only qualification conversions
of the iterator reference type to element_type[.](#span.cons-8.1.sentence-2)
— *end note*]
- [(8.2)](#span.cons-8.2)
It satisfies [contiguous_iterator](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]")[.](#span.cons-8.2.sentence-1)
- [(8.3)](#span.cons-8.3)
End satisfies [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<It>[.](#span.cons-8.3.sentence-1)
- [(8.4)](#span.cons-8.4)
is_convertible_v<End, size_t> is false[.](#span.cons-8.4.sentence-1)
[9](#span.cons-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20418)
*Preconditions*:
- [(9.1)](#span.cons-9.1)
[first, last) is a valid range[.](#span.cons-9.1.sentence-1)
- [(9.2)](#span.cons-9.2)
It models [contiguous_iterator](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]")[.](#span.cons-9.2.sentence-1)
- [(9.3)](#span.cons-9.3)
End models [sized_sentinel_for](iterator.concept.sizedsentinel#concept:sized_sentinel_for "24.3.4.8Concept sized_­sentinel_­for[iterator.concept.sizedsentinel]")<It>[.](#span.cons-9.3.sentence-1)
[10](#span.cons-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20426)
*Hardened preconditions*: If extent is not equal to dynamic_extent,
then (last - first) == extent is true[.](#span.cons-10.sentence-1)
[11](#span.cons-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20431)
*Effects*: Initializes *data_* with to_address(first) and*size_* with last - first[.](#span.cons-11.sentence-1)
[12](#span.cons-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20436)
*Throws*: When and what last - first throws[.](#span.cons-12.sentence-1)
[🔗](#lib:span,constructor___)
`template<size_t N> constexpr span(type_identity_t<element_type> (&arr)[N]) noexcept;
template<class T, size_t N> constexpr span(array<T, N>& arr) noexcept;
template<class T, size_t N> constexpr span(const array<T, N>& arr) noexcept;
`
[13](#span.cons-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20449)
*Constraints*: Let U be remove_pointer_t<decltype(std::data(arr))>[.](#span.cons-13.sentence-1)
- [(13.1)](#span.cons-13.1)
extent == dynamic_extent || N == extent is true, and
- [(13.2)](#span.cons-13.2)
is_convertible_v<U(*)[], element_type(*)[]> is true. [*Note [3](#span.cons-note-3)*:
The intent is to allow only qualification conversions
of the array element type to element_type[.](#span.cons-13.2.sentence-2)
— *end note*]
[14](#span.cons-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20461)
*Effects*: Constructs a span that is a view over the supplied array[.](#span.cons-14.sentence-1)
[*Note [4](#span.cons-note-4)*:
type_identity_t affects class template argument deduction[.](#span.cons-14.sentence-2)
— *end note*]
[15](#span.cons-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20468)
*Postconditions*: size() == N && data() == std::data(arr) is true[.](#span.cons-15.sentence-1)
[🔗](#lib:span,constructor____)
`template<class R> constexpr explicit(extent != dynamic_extent) span(R&& r);
`
[16](#span.cons-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20479)
*Constraints*: Let U be remove_reference_t<ranges::range_reference_t<R>>[.](#span.cons-16.sentence-1)
- [(16.1)](#span.cons-16.1)
R satisfies ranges::[contiguous_range](range.refinements#concept:contiguous_range "25.4.6Other range refinements[range.refinements]") and ranges::[sized_range](range.sized#concept:sized_range "25.4.4Sized ranges[range.sized]")[.](#span.cons-16.1.sentence-1)
- [(16.2)](#span.cons-16.2)
Either R satisfies ranges::[borrowed_range](range.range#concept:borrowed_range "25.4.2Ranges[range.range]") oris_const_v<element_type> is true[.](#span.cons-16.2.sentence-1)
- [(16.3)](#span.cons-16.3)
remove_cvref_t<R> is not a specialization of span[.](#span.cons-16.3.sentence-1)
- [(16.4)](#span.cons-16.4)
remove_cvref_t<R> is not a specialization of array[.](#span.cons-16.4.sentence-1)
- [(16.5)](#span.cons-16.5)
is_array_v<remove_cvref_t<R>> is false[.](#span.cons-16.5.sentence-1)
- [(16.6)](#span.cons-16.6)
is_convertible_v<U(*)[], element_type(*)[]> is true[.](#span.cons-16.6.sentence-1)
[*Note [5](#span.cons-note-5)*:
The intent is to allow only qualification conversions
of the range reference type to element_type[.](#span.cons-16.6.sentence-2)
— *end note*]
[17](#span.cons-17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20498)
*Preconditions*:
- [(17.1)](#span.cons-17.1)
R models ranges::[contiguous_range](range.refinements#concept:contiguous_range "25.4.6Other range refinements[range.refinements]") andranges::[sized_range](range.sized#concept:sized_range "25.4.4Sized ranges[range.sized]")[.](#span.cons-17.1.sentence-1)
- [(17.2)](#span.cons-17.2)
If is_const_v<element_type> is false,R models ranges::[borrowed_range](range.range#concept:borrowed_range "25.4.2Ranges[range.range]")[.](#span.cons-17.2.sentence-1)
[18](#span.cons-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20507)
*Hardened preconditions*: If extent is not equal to dynamic_extent,
then ranges::size(r) == extent is true[.](#span.cons-18.sentence-1)
[19](#span.cons-19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20512)
*Effects*: Initializes *data_* with ranges::data(r) and*size_* with ranges::size(r)[.](#span.cons-19.sentence-1)
[20](#span.cons-20)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20517)
*Throws*: What and when ranges::data(r) and ranges::size(r) throw[.](#span.cons-20.sentence-1)
[🔗](#lib:span,constructor_____)
`constexpr explicit(extent != dynamic_extent) span(std::initializer_list<value_type> il);
`
[21](#span.cons-21)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20528)
*Constraints*: is_const_v<element_type> is true[.](#span.cons-21.sentence-1)
[22](#span.cons-22)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20532)
*Hardened preconditions*: If extent is not equal to dynamic_extent,
then il.size() == extent is true[.](#span.cons-22.sentence-1)
[23](#span.cons-23)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20537)
*Effects*: Initializes *data_* with il.begin() and*size_* with il.size()[.](#span.cons-23.sentence-1)
[🔗](#lib:span,constructor______)
`constexpr span(const span& other) noexcept = default;
`
[24](#span.cons-24)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20549)
*Postconditions*: other.size() == size() && other.data() == data()[.](#span.cons-24.sentence-1)
[🔗](#lib:span,constructor_______)
`template<class OtherElementType, size_t OtherExtent>
constexpr explicit(see below) span(const span<OtherElementType, OtherExtent>& s) noexcept;
`
[25](#span.cons-25)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20561)
*Constraints*:
- [(25.1)](#span.cons-25.1)
extent == dynamic_extent || OtherExtent == dynamic_extent || extent == OtherExtent is true, and
- [(25.2)](#span.cons-25.2)
is_convertible_v<OtherElementType(*)[], element_type(*)[]> is true[.](#span.cons-25.sentence-1)
[*Note [6](#span.cons-note-6)*:
The intent is to allow only qualification conversions
of the OtherElementType to element_type[.](#span.cons-25.2.sentence-2)
— *end note*]
[26](#span.cons-26)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20572)
*Hardened preconditions*: If extent is not equal to dynamic_extent,
then s.size() == extent is true[.](#span.cons-26.sentence-1)
[27](#span.cons-27)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20577)
*Effects*: Constructs a span that is a view over the range
[s.data(), s.data() + s.size())[.](#span.cons-27.sentence-1)
[28](#span.cons-28)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20582)
*Postconditions*: size() == s.size() && data() == s.data()[.](#span.cons-28.sentence-1)
[29](#span.cons-29)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20586)
*Remarks*: The expression inside explicit is equivalent to:extent != dynamic_extent && OtherExtent == dynamic_extent
[🔗](#lib:operator=,span)
`constexpr span& operator=(const span& other) noexcept = default;
`
[30](#span.cons-30)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20600)
*Postconditions*: size() == other.size() && data() == other.data()[.](#span.cons-30.sentence-1)
#### [23.7.2.2.3](#span.deduct) Deduction guides [[span.deduct]](span.deduct)
[🔗](#lib:span,deduction_guide)
`template<class It, class EndOrSize>
span(It, EndOrSize) -> span<remove_reference_t<iter_reference_t<It>>,
[maybe-static-ext](span.syn#concept:maybe-static-ext "23.7.2.1Header <span> synopsis[span.syn]")<EndOrSize>>;
`
[1](#span.deduct-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20615)
*Constraints*: It satisfies [contiguous_iterator](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]")[.](#span.deduct-1.sentence-1)
[🔗](#lib:span,deduction_guide_)
`template<class R>
span(R&&) -> span<remove_reference_t<ranges::range_reference_t<R>>>;
`
[2](#span.deduct-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20627)
*Constraints*: R satisfies ranges::[contiguous_range](range.refinements#concept:contiguous_range "25.4.6Other range refinements[range.refinements]")[.](#span.deduct-2.sentence-1)
#### [23.7.2.2.4](#span.sub) Subviews [[span.sub]](span.sub)
[🔗](#lib:span,first)
`template<size_t Count> constexpr span<element_type, Count> first() const;
`
[1](#span.sub-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20640)
*Mandates*: Count <= Extent is true[.](#span.sub-1.sentence-1)
[2](#span.sub-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20644)
*Hardened preconditions*: Count <= size() is true[.](#span.sub-2.sentence-1)
[3](#span.sub-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20648)
*Effects*: Equivalent to: return R{data(), Count}; where R is the return type[.](#span.sub-3.sentence-1)
[🔗](#lib:span,last)
`template<size_t Count> constexpr span<element_type, Count> last() const;
`
[4](#span.sub-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20660)
*Mandates*: Count <= Extent is true[.](#span.sub-4.sentence-1)
[5](#span.sub-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20664)
*Hardened preconditions*: Count <= size() is true[.](#span.sub-5.sentence-1)
[6](#span.sub-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20668)
*Effects*: Equivalent to: return R{data() + (size() - Count), Count}; where R is the return type[.](#span.sub-6.sentence-1)
[🔗](#lib:span,subspan)
`template<size_t Offset, size_t Count = dynamic_extent>
constexpr span<element_type, see below> subspan() const;
`
[7](#span.sub-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20681)
*Mandates*: Offset <= Extent && (Count == dynamic_extent || Count <= Extent - Offset) is true[.](#span.sub-7.sentence-1)
[8](#span.sub-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20688)
*Hardened preconditions*: Offset <= size() && (Count == dynamic_extent || Count <= size() - Offset) is true[.](#span.sub-8.sentence-1)
[9](#span.sub-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20695)
*Effects*: Equivalent to:return span<ElementType, *see below*>( data() + Offset, Count != dynamic_extent ? Count : size() - Offset);
[10](#span.sub-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20703)
*Remarks*: The second template argument of the returned span type is:Count != dynamic_extent ? Count : (Extent != dynamic_extent ? Extent - Offset : dynamic_extent)
[🔗](#lib:span,first_)
`constexpr span<element_type, dynamic_extent> first(size_type count) const;
`
[11](#span.sub-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20719)
*Hardened preconditions*: count <= size() is true[.](#span.sub-11.sentence-1)
[12](#span.sub-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20723)
*Effects*: Equivalent to: return {data(), count};
[🔗](#lib:span,last_)
`constexpr span<element_type, dynamic_extent> last(size_type count) const;
`
[13](#span.sub-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20734)
*Hardened preconditions*: count <= size() is true[.](#span.sub-13.sentence-1)
[14](#span.sub-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20738)
*Effects*: Equivalent to: return {data() + (size() - count), count};
[🔗](#lib:span,subspan_)
`constexpr span<element_type, dynamic_extent> subspan(
size_type offset, size_type count = dynamic_extent) const;
`
[15](#span.sub-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20750)
*Hardened preconditions*: offset <= size() && (count == dynamic_extent || count <= size() - offset) is true[.](#span.sub-15.sentence-1)
[16](#span.sub-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20757)
*Effects*: Equivalent to:return {data() + offset, count == dynamic_extent ? size() - offset : count};
#### [23.7.2.2.5](#span.obs) Observers [[span.obs]](span.obs)
[🔗](#lib:span,size)
`constexpr size_type size() const noexcept;
`
[1](#span.obs-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20773)
*Effects*: Equivalent to: return *size_*;
[🔗](#lib:span,size_bytes)
`constexpr size_type size_bytes() const noexcept;
`
[2](#span.obs-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20784)
*Effects*: Equivalent to: return size() * sizeof(element_type);
[🔗](#lib:span,empty)
`constexpr bool empty() const noexcept;
`
[3](#span.obs-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20795)
*Effects*: Equivalent to: return size() == 0;
#### [23.7.2.2.6](#span.elem) Element access [[span.elem]](span.elem)
[🔗](#lib:operator%5b%5d,span)
`constexpr reference operator[](size_type idx) const;
`
[1](#span.elem-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20808)
*Hardened preconditions*: idx < size() is true[.](#span.elem-1.sentence-1)
[2](#span.elem-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20812)
*Returns*: *(data() + idx)[.](#span.elem-2.sentence-1)
[3](#span.elem-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20816)
*Throws*: Nothing[.](#span.elem-3.sentence-1)
[🔗](#lib:span,at)
`constexpr reference at(size_type idx) const;
`
[4](#span.elem-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20827)
*Returns*: *(data() + idx)[.](#span.elem-4.sentence-1)
[5](#span.elem-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20831)
*Throws*: out_of_range if idx >= size() is true[.](#span.elem-5.sentence-1)
[🔗](#lib:span,front)
`constexpr reference front() const;
`
[6](#span.elem-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20842)
*Hardened preconditions*: empty() is false[.](#span.elem-6.sentence-1)
[7](#span.elem-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20846)
*Returns*: *data()[.](#span.elem-7.sentence-1)
[8](#span.elem-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20850)
*Throws*: Nothing[.](#span.elem-8.sentence-1)
[🔗](#lib:span,back)
`constexpr reference back() const;
`
[9](#span.elem-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20861)
*Hardened preconditions*: empty() is false[.](#span.elem-9.sentence-1)
[10](#span.elem-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20865)
*Returns*: *(data() + (size() - 1))[.](#span.elem-10.sentence-1)
[11](#span.elem-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20869)
*Throws*: Nothing[.](#span.elem-11.sentence-1)
[🔗](#lib:span,data)
`constexpr pointer data() const noexcept;
`
[12](#span.elem-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20880)
*Returns*: *data_*[.](#span.elem-12.sentence-1)
#### [23.7.2.2.7](#span.iterators) Iterator support [[span.iterators]](span.iterators)
[🔗](#lib:iterator,span)
`using iterator = implementation-defined;
`
[1](#span.iterators-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20893)
The type
models [contiguous_iterator](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14Concept contiguous_­iterator[iterator.concept.contiguous]") ([[iterator.concept.contiguous]](iterator.concept.contiguous "24.3.4.14Concept contiguous_­iterator")),
meets the *Cpp17RandomAccessIterator* requirements ([[random.access.iterators]](random.access.iterators "24.3.5.7Random access iterators")),
and
meets the requirements for
constexpr iterators ([[iterator.requirements.general]](iterator.requirements.general "24.3.1General")),
whose value type is value_type and
whose reference type is reference[.](#span.iterators-1.sentence-1)
[2](#span.iterators-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20904)
All requirements on container iterators ([[container.reqmts]](container.reqmts "23.2.2.2Container requirements")) apply tospan::iterator as well[.](#span.iterators-2.sentence-1)
[🔗](#lib:span,begin)
`constexpr iterator begin() const noexcept;
`
[3](#span.iterators-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20915)
*Returns*: An iterator referring to the first element in the span[.](#span.iterators-3.sentence-1)
If empty() is true, then it returns the
same value as end()[.](#span.iterators-3.sentence-2)
[🔗](#lib:span,end)
`constexpr iterator end() const noexcept;
`
[4](#span.iterators-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20928)
*Returns*: An iterator which is the past-the-end value[.](#span.iterators-4.sentence-1)
[🔗](#lib:span,rbegin)
`constexpr reverse_iterator rbegin() const noexcept;
`
[5](#span.iterators-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20939)
*Effects*: Equivalent to: return reverse_iterator(end());
[🔗](#lib:span,rend)
`constexpr reverse_iterator rend() const noexcept;
`
[6](#span.iterators-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20950)
*Effects*: Equivalent to: return reverse_iterator(begin());