22 Containers library [containers]

22.3 Sequence containers [sequences]

22.3.7 Class template array [array]

22.3.7.1 Overview [array.overview]

The header <array> defines a class template for storing fixed-size sequences of objects.
An array is a contiguous container.
An instance of array<T, N> stores N elements of type T, so that size() == N is an invariant.
An array is an aggregate that can be list-initialized with up to N elements whose types are convertible to T.
An array meets all of the requirements of a container and of a reversible container ([container.requirements]), except that a default constructed array object is not empty and that swap does not have constant complexity.
An array meets some of the requirements of a sequence container.
Descriptions are provided here only for operations on array that are not described in one of these tables and for operations where there is additional semantic information.
array<T, N> is a structural type ([temp.param]) if T is a structural type.
Two values a1 and a2 of type array<T, N> are template-argument-equivalent ([temp.type]) if and only if each pair of corresponding elements in a1 and a2 are template-argument-equivalent.
The types iterator and const_­iterator meet the constexpr iterator requirements ([iterator.requirements.general]).
namespace std {
  template<class T, size_t N>
  struct array {
    // types
    using value_type             = T;
    using pointer                = T*;
    using const_pointer          = const T*;
    using reference              = T&;
    using const_reference        = const T&;
    using size_type              = size_t;
    using difference_type        = ptrdiff_t;
    using iterator               = implementation-defined; // see [container.requirements]
    using const_iterator         = implementation-defined; // see [container.requirements]
    using reverse_iterator       = std::reverse_iterator<iterator>;
    using const_reverse_iterator = std::reverse_iterator<const_iterator>;

    // no explicit construct/copy/destroy for aggregate type

    constexpr void fill(const T& u);
    constexpr void swap(array&) noexcept(is_nothrow_swappable_v<T>);

    // iterators
    constexpr iterator               begin() noexcept;
    constexpr const_iterator         begin() const noexcept;
    constexpr iterator               end() noexcept;
    constexpr const_iterator         end() const noexcept;

    constexpr reverse_iterator       rbegin() noexcept;
    constexpr const_reverse_iterator rbegin() const noexcept;
    constexpr reverse_iterator       rend() noexcept;
    constexpr const_reverse_iterator rend() const noexcept;

    constexpr const_iterator         cbegin() const noexcept;
    constexpr const_iterator         cend() const noexcept;
    constexpr const_reverse_iterator crbegin() const noexcept;
    constexpr const_reverse_iterator crend() const noexcept;

    // capacity
    [[nodiscard]] constexpr bool empty() const noexcept;
    constexpr size_type size() const noexcept;
    constexpr size_type max_size() const noexcept;

    // element access
    constexpr reference       operator[](size_type n);
    constexpr const_reference operator[](size_type n) const;
    constexpr reference       at(size_type n);
    constexpr const_reference at(size_type n) const;
    constexpr reference       front();
    constexpr const_reference front() const;
    constexpr reference       back();
    constexpr const_reference back() const;

    constexpr T *       data() noexcept;
    constexpr const T * data() const noexcept;
  };

  template<class T, class... U>
    array(T, U...) -> array<T, 1 + sizeof...(U)>;
}

22.3.7.2 Constructors, copy, and assignment [array.cons]

The conditions for an aggregate shall be met.
Class array relies on the implicitly-declared special member functions ([class.default.ctor], [class.dtor], and [class.copy.ctor]) to conform to the container requirements table in [container.requirements].
In addition to the requirements specified in the container requirements table, the implicit move constructor and move assignment operator for array require that T be Cpp17MoveConstructible or Cpp17MoveAssignable, respectively.
template<class T, class... U> array(T, U...) -> array<T, 1 + sizeof...(U)>;
Mandates: (is_­same_­v<T, U> && ...) is true.

22.3.7.3 Member functions [array.members]

constexpr size_type size() const noexcept;
Returns: N.
constexpr T* data() noexcept; constexpr const T* data() const noexcept;
Returns: A pointer such that [data(), data() + size()) is a valid range.
For a non-empty array, data() == addressof(front()).
constexpr void fill(const T& u);
Effects: As if by fill_­n(begin(), N, u).
constexpr void swap(array& y) noexcept(is_nothrow_swappable_v<T>);
Effects: Equivalent to swap_­ranges(begin(), end(), y.begin()).
Note
:
Unlike the swap function for other containers, array​::​swap takes linear time, may exit via an exception, and does not cause iterators to become associated with the other container.
— end note
 ]

22.3.7.4 Specialized algorithms [array.special]

template<class T, size_t N> constexpr void swap(array<T, N>& x, array<T, N>& y) noexcept(noexcept(x.swap(y)));
Constraints: N == 0 or is_­swappable_­v<T> is true.
Effects: As if by x.swap(y).
Complexity: Linear in N.

22.3.7.5 Zero-sized arrays [array.zero]

array shall provide support for the special case N == 0.
In the case that N == 0, begin() == end() == unique value.
The return value of data() is unspecified.
The effect of calling front() or back() for a zero-sized array is undefined.
Member function swap() shall have a non-throwing exception specification.

22.3.7.6 Array creation functions [array.creation]

template<class T, size_t N> constexpr array<remove_cv_t<T>, N> to_array(T (&a)[N]);
Mandates: is_­array_­v<T> is false and is_­constructible_­v<T, T&> is true.
Preconditions: T meets the Cpp17CopyConstructible requirements.
Returns: {{ a[0], , a[N - 1] }}.
template<class T, size_t N> constexpr array<remove_cv_t<T>, N> to_array(T (&&a)[N]);
Mandates: is_­array_­v<T> is false and is_­move_­constructible_­v<T> is true.
Preconditions: T meets the Cpp17MoveConstructible requirements.
Returns: {{ std​::​move(a[0]), , std​::​move(a[N - 1]) }}.

22.3.7.7 Tuple interface [array.tuple]

template<class T, size_t N> struct tuple_size<array<T, N>> : integral_constant<size_t, N> { };
template<size_t I, class T, size_t N> struct tuple_element<I, array<T, N>> { using type = T; };
Mandates: I < N is true.
template<size_t I, class T, size_t N> constexpr T& get(array<T, N>& a) noexcept; template<size_t I, class T, size_t N> constexpr T&& get(array<T, N>&& a) noexcept; template<size_t I, class T, size_t N> constexpr const T& get(const array<T, N>& a) noexcept; template<size_t I, class T, size_t N> constexpr const T&& get(const array<T, N>&& a) noexcept;
Mandates: I < N is true.
Returns: A reference to the element of a, where indexing is zero-based.