23 Containers library [containers]

23.3 Sequence containers [sequences]

23.3.2 Class template array [array]

23.3.2.1 Class template array overview [array.overview]

The header <array> defines a class template for storing fixed-size sequences of objects. An array supports random access iterators. An instance of array<T, N> stores N elements of type T, so that size() == N is an invariant. The elements of an array are stored contiguously, meaning that if a is an array<T, N> then it obeys the identity &a[n] == &a[0] + n for all 0 <= n < N.

An array is an aggregate ([dcl.init.aggr]) that can be initialized with the syntax

array<T, N> a = { initializer-list };

where initializer-list is a comma-separated list of up to N elements whose types are convertible to T.

An array satisfies 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 satisfies some of the requirements of a sequence container ([sequence.reqmts]). 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.

namespace std {
  template <class T, size_t N>
  struct array {
    //  types:
    typedef T&                                    reference;
    typedef const T&                              const_reference;
    typedef implementation-defined                iterator;
    typedef implementation-defined                const_iterator;
    typedef size_t                                size_type;
    typedef ptrdiff_t                             difference_type;
    typedef T                                     value_type;
    typedef T*                                    pointer;
    typedef const T*                              const_pointer;
    typedef std::reverse_iterator<iterator>       reverse_iterator;
    typedef std::reverse_iterator<const_iterator> const_reverse_iterator;

    T       elems[N];           // exposition only

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

    void fill(const T& u);
    void swap(array&) noexcept(noexcept(swap(declval<T&>(), declval<T&>())));

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

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

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

    // capacity:
    constexpr size_type size() const noexcept;
    constexpr size_type max_size() const noexcept;
    constexpr bool      empty() const noexcept;

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

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

Note: The member variable elems is shown for exposition only, to emphasize that array is a class aggregate. The name elems is not part of array's interface.  — end note ]

23.3.2.2 array constructors, copy, and assignment [array.cons]

The conditions for an aggregate ([dcl.init.aggr]) shall be met. Class array relies on the implicitly-declared special member functions ([class.ctor], [class.dtor], and [class.copy]) 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 MoveConstructible or MoveAssignable, respectively.

23.3.2.3 array specialized algorithms [array.special]

template <class T, size_t N> void swap(array<T,N>& x, array<T,N>& y) noexcept(noexcept(x.swap(y)));

Effects:

x.swap(y);

Complexity: Linear in N.

23.3.2.4 array::size [array.size]

template <class T, size_t N> constexpr size_type array<T,N>::size() const noexcept;

Returns: N

23.3.2.5 array::data [array.data]

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

Returns: elems.

23.3.2.6 array::fill [array.fill]

void fill(const T& u);

Effects: fill_n(begin(), N, u)

23.3.2.7 array::swap [array.swap]

void swap(array& y) noexcept(noexcept(swap(declval<T&>(), declval<T&>())));

Effects: swap_ranges(begin(), end(), y.begin())

Throws: Nothing unless one of the element-wise swap calls throws an exception.

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.

23.3.2.8 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 noexcept-specification which is equivalent to noexcept(true).

23.3.2.9 Tuple interface to class template array [array.tuple]

template <class T, size_t N> struct tuple_size<array<T, N>> : integral_constant<size_t, N> { };

tuple_element<I, array<T, N> >::type

Requires: I < N. The program is ill-formed if I is out of bounds.

Value: The type T.

template <size_t I, class T, size_t N> constexpr T& get(array<T, N>& a) noexcept;

Requires: I < N. The program is ill-formed if I is out of bounds.

Returns: A reference to the Ith element of a, where indexing is zero-based.

template <size_t I, class T, size_t N> constexpr T&& get(array<T, N>&& a) noexcept;

Effects: Equivalent to return std::move(get<I>(a));

template <size_t I, class T, size_t N> constexpr const T& get(const array<T, N>& a) noexcept;

Requires: I < N. The program is ill-formed if I is out of bounds.

Returns: A const reference to the Ith element of a, where indexing is zero-based.