[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.7 Iterator 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.2 Constructors, 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.4 Subviews"), 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.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<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.1 Header <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.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<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.14 Concept 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.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<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.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]")<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.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]")<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.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<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.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<element_type> 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<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.1 Header <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.14 Concept 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.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<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.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());
