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
    void fill(const T& u);
    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:
    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)>;
}template<class T, class... U>
  array(T, U...) -> array<T, 1 + sizeof...(U)>;
template <class T, size_t N>
  void swap(array<T, N>& x, array<T, N>& y) noexcept(noexcept(x.swap(y)));
template <class T, size_t N> constexpr size_type array<T, N>::size() const noexcept;
constexpr T* data() noexcept;
constexpr const T* data() const noexcept;
void fill(const T& u);
void swap(array& y) noexcept(is_nothrow_swappable_v<T>);
template <class T, size_t N>
  struct tuple_size<array<T, N>> : integral_constant<size_t, N> { };
tuple_element<I, array<T, N>>::type
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;