[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 synopsis [[span.syn]](span.syn) [🔗](#header:%3cspan%3e) #include // see [[initializer.list.syn]](initializer.list.syn "17.11.2 Header synopsis")// mostly freestandingnamespace std {// constantsinline constexpr size_t [dynamic_extent](#lib:dynamic_extent "23.7.2.1 Header synopsis [span.syn]") = numeric_limits::max(); templateconcept [*integral-constant-like*](#concept:integral-constant-like "23.7.2.1 Header synopsis [span.syn]") = // *exposition only* is_integral_v> &&!is_same_v> &&[convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_­to [concept.convertible]") &&[equality_comparable_with](concept.equalitycomparable#concept:equality_comparable_with "18.5.4 Concept equality_­comparable [concept.equalitycomparable]") && bool_constant::value && bool_constant(T()) == T::value>::value; templateconstexpr size_t [*maybe-static-ext*](#concept:maybe-static-ext "23.7.2.1 Header synopsis [span.syn]") = dynamic_extent; // *exposition only*template<[*integral-constant-like*](#concept:integral-constant-like "23.7.2.1 Header synopsis [span.syn]") T>constexpr size_t [*maybe-static-ext*](#concept:maybe-static-ext "23.7.2.1 Header synopsis [span.syn]") = {T::value}; // [[views.span]](#views.span "23.7.2.2 Class template span"), class template spantemplateclass span; // partially freestandingtemplateconstexpr bool ranges::enable_view> = true; templateconstexpr bool ranges::enable_borrowed_range> = true; // [[span.objectrep]](#span.objectrep "23.7.2.3 Views of object representation"), views of object representationtemplate span as_bytes(span s) noexcept; template span as_writable_bytes(span 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 {templateclass span {public:// constants and typesusing element_type = ElementType; using value_type = remove_cv_t; 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.7 Iterator support")using const_iterator = std::const_iterator; using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::const_iterator; static constexpr size_type extent = Extent; // [[span.cons]](#span.cons "23.7.2.2.2 Constructors, copy, and assignment"), constructors, copy, and assignmentconstexpr span() noexcept; templateconstexpr explicit(extent != dynamic_extent) span(It first, size_type count); templateconstexpr explicit(extent != dynamic_extent) span(It first, End last); templateconstexpr span(type_identity_t (&arr)[N]) noexcept; templateconstexpr span(array& arr) noexcept; templateconstexpr span(const array& arr) noexcept; templateconstexpr explicit(extent != dynamic_extent) span(R&& r); constexpr explicit(extent != dynamic_extent) span(std::initializer_list il); constexpr span(const span& other) noexcept = default; templateconstexpr explicit(*see below*) span(const span& s) noexcept; constexpr span& operator=(const span& other) noexcept = default; // [[span.sub]](#span.sub "23.7.2.2.4 Subviews"), subviewstemplateconstexpr span first() const; templateconstexpr span last() const; templateconstexpr span subspan() const; constexpr span first(size_type count) const; constexpr span last(size_type count) const; constexpr span subspan( size_type offset, size_type count = dynamic_extent) const; // [[span.obs]](#span.obs "23.7.2.2.5 Observers"), 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.6 Element 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.7 Iterator 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 span(It, EndOrSize) -> span>, [*maybe-static-ext*](#concept:maybe-static-ext "23.7.2.1 Header synopsis [span.syn]")>; template span(T (&)[N]) -> span; template span(array&) -> span; template span(const array&) -> span; template span(R&&) -> span>>;} [3](#span.overview-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20322) span is a trivially copyable type ([[basic.types.general]](basic.types.general#term.trivially.copyable.type "6.9.1 General"))[.](#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 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>[.](#span.cons-3.sentence-1) - [(3.1)](#span.cons-3.1) It satisfies [contiguous_iterator](iterator.concept.contiguous#concept:contiguous_iterator "24.3.4.14 Concept contiguous_­iterator [iterator.concept.contiguous]")[.](#span.cons-3.1.sentence-1) - [(3.2)](#span.cons-3.2) is_convertible_v 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.14 Concept 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 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>[.](#span.cons-8.sentence-1) - [(8.1)](#span.cons-8.1) is_convertible_v 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.14 Concept 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.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]")[.](#span.cons-8.3.sentence-1) - [(8.4)](#span.cons-8.4) is_convertible_v 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.14 Concept 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.8 Concept sized_­sentinel_­for [iterator.concept.sizedsentinel]")[.](#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 constexpr span(type_identity_t (&arr)[N]) noexcept; template constexpr span(array& arr) noexcept; template constexpr span(const array& arr) noexcept; ` [13](#span.cons-13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20449) *Constraints*: Let U be remove_pointer_t[.](#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 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 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>[.](#span.cons-16.sentence-1) - [(16.1)](#span.cons-16.1) R satisfies ranges​::​[contiguous_range](range.refinements#concept:contiguous_range "25.4.6 Other range refinements [range.refinements]") and ranges​::​[sized_range](range.sized#concept:sized_range "25.4.4 Sized 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.2 Ranges [range.range]") oris_const_v is true[.](#span.cons-16.2.sentence-1) - [(16.3)](#span.cons-16.3) remove_cvref_t is not a specialization of span[.](#span.cons-16.3.sentence-1) - [(16.4)](#span.cons-16.4) remove_cvref_t is not a specialization of array[.](#span.cons-16.4.sentence-1) - [(16.5)](#span.cons-16.5) is_array_v> is false[.](#span.cons-16.5.sentence-1) - [(16.6)](#span.cons-16.6) is_convertible_v 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.6 Other range refinements [range.refinements]") andranges​::​[sized_range](range.sized#concept:sized_range "25.4.4 Sized ranges [range.sized]")[.](#span.cons-17.1.sentence-1) - [(17.2)](#span.cons-17.2) If is_const_v is false,R models ranges​::​[borrowed_range](range.range#concept:borrowed_range "25.4.2 Ranges [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 il); ` [21](#span.cons-21) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20528) *Constraints*: is_const_v 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 constexpr explicit(see below) span(const span& 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 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 span(It, EndOrSize) -> span>, [maybe-static-ext](#concept:maybe-static-ext "23.7.2.1 Header synopsis [span.syn]")>; ` [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.14 Concept contiguous_­iterator [iterator.concept.contiguous]")[.](#span.deduct-1.sentence-1) [🔗](#lib:span,deduction_guide_) `template span(R&&) -> span>>; ` [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.6 Other 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 constexpr span 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 constexpr span 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 constexpr span 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( 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 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 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 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.14 Concept contiguous_­iterator [iterator.concept.contiguous]") ([[iterator.concept.contiguous]](iterator.concept.contiguous "24.3.4.14 Concept contiguous_­iterator")), meets the *Cpp17RandomAccessIterator* requirements ([[random.access.iterators]](random.access.iterators "24.3.5.7 Random access iterators")), and meets the requirements for constexpr iterators ([[iterator.requirements.general]](iterator.requirements.general "24.3.1 General")), 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.2 Container 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 span as_bytes(span s) noexcept; ` [1](#span.objectrep-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20965) *Effects*: Equivalent to: return R{reinterpret_cast(s.data()), s.size_bytes()}; where R is the return type[.](#span.objectrep-1.sentence-1) [🔗](#lib:as_writable_bytes) `template span as_writable_bytes(span s) noexcept; ` [2](#span.objectrep-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/containers.tex#L20979) *Constraints*: is_const_v 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(s.data()), s.size_bytes()}; where R is the return type[.](#span.objectrep-3.sentence-1)