xref: /openbsd-src/gnu/llvm/libcxx/include/array (revision 4bdff4bed0e3d54e55670334c7d0077db4170f86)
146035553Spatrick// -*- C++ -*-
2*4bdff4beSrobert//===----------------------------------------------------------------------===//
346035553Spatrick//
446035553Spatrick// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
546035553Spatrick// See https://llvm.org/LICENSE.txt for license information.
646035553Spatrick// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
746035553Spatrick//
846035553Spatrick//===----------------------------------------------------------------------===//
946035553Spatrick
1046035553Spatrick#ifndef _LIBCPP_ARRAY
1146035553Spatrick#define _LIBCPP_ARRAY
1246035553Spatrick
1346035553Spatrick/*
1446035553Spatrick    array synopsis
1546035553Spatrick
1646035553Spatricknamespace std
1746035553Spatrick{
1846035553Spatricktemplate <class T, size_t N >
1946035553Spatrickstruct array
2046035553Spatrick{
2146035553Spatrick    // types:
2246035553Spatrick    typedef T & reference;
2346035553Spatrick    typedef const T & const_reference;
2446035553Spatrick    typedef implementation defined iterator;
2546035553Spatrick    typedef implementation defined const_iterator;
2646035553Spatrick    typedef size_t size_type;
2746035553Spatrick    typedef ptrdiff_t difference_type;
2846035553Spatrick    typedef T value_type;
2946035553Spatrick    typedef T* pointer;
3046035553Spatrick    typedef const T* const_pointer;
3146035553Spatrick    typedef std::reverse_iterator<iterator> reverse_iterator;
3246035553Spatrick    typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
3346035553Spatrick
3446035553Spatrick    // No explicit construct/copy/destroy for aggregate type
35037e7968Spatrick    void fill(const T& u);                                      // constexpr in C++20
36037e7968Spatrick    void swap(array& a) noexcept(is_nothrow_swappable_v<T>);    // constexpr in C++20
3746035553Spatrick
3846035553Spatrick    // iterators:
39037e7968Spatrick    iterator begin() noexcept;                                  // constexpr in C++17
40037e7968Spatrick    const_iterator begin() const noexcept;                      // constexpr in C++17
41037e7968Spatrick    iterator end() noexcept;                                    // constexpr in C++17
42037e7968Spatrick    const_iterator end() const noexcept;                        // constexpr in C++17
4346035553Spatrick
44037e7968Spatrick    reverse_iterator rbegin() noexcept;                         // constexpr in C++17
45037e7968Spatrick    const_reverse_iterator rbegin() const noexcept;             // constexpr in C++17
46037e7968Spatrick    reverse_iterator rend() noexcept;                           // constexpr in C++17
47037e7968Spatrick    const_reverse_iterator rend() const noexcept;               // constexpr in C++17
4846035553Spatrick
49037e7968Spatrick    const_iterator cbegin() const noexcept;                     // constexpr in C++17
50037e7968Spatrick    const_iterator cend() const noexcept;                       // constexpr in C++17
51037e7968Spatrick    const_reverse_iterator crbegin() const noexcept;            // constexpr in C++17
52037e7968Spatrick    const_reverse_iterator crend() const noexcept;              // constexpr in C++17
5346035553Spatrick
5446035553Spatrick    // capacity:
5546035553Spatrick    constexpr size_type size() const noexcept;
5646035553Spatrick    constexpr size_type max_size() const noexcept;
5746035553Spatrick    constexpr bool empty() const noexcept;
5846035553Spatrick
5946035553Spatrick    // element access:
60037e7968Spatrick    reference operator[](size_type n);                          // constexpr in C++17
6146035553Spatrick    const_reference operator[](size_type n) const;              // constexpr in C++14
62037e7968Spatrick    reference at(size_type n);                                  // constexpr in C++17
6346035553Spatrick    const_reference at(size_type n) const;                      // constexpr in C++14
6446035553Spatrick
65037e7968Spatrick    reference front();                                          // constexpr in C++17
6646035553Spatrick    const_reference front() const;                              // constexpr in C++14
67037e7968Spatrick    reference back();                                           // constexpr in C++17
6846035553Spatrick    const_reference back() const;                               // constexpr in C++14
6946035553Spatrick
70037e7968Spatrick    T* data() noexcept;                                         // constexpr in C++17
71037e7968Spatrick    const T* data() const noexcept;                             // constexpr in C++17
7246035553Spatrick};
7346035553Spatrick
7446035553Spatricktemplate <class T, class... U>
75037e7968Spatrick  array(T, U...) -> array<T, 1 + sizeof...(U)>;                 // C++17
7646035553Spatrick
7746035553Spatricktemplate <class T, size_t N>
78037e7968Spatrick  bool operator==(const array<T,N>& x, const array<T,N>& y);    // constexpr in C++20
7946035553Spatricktemplate <class T, size_t N>
80037e7968Spatrick  bool operator!=(const array<T,N>& x, const array<T,N>& y);    // constexpr in C++20
8146035553Spatricktemplate <class T, size_t N>
82037e7968Spatrick  bool operator<(const array<T,N>& x, const array<T,N>& y);     // constexpr in C++20
8346035553Spatricktemplate <class T, size_t N>
84037e7968Spatrick  bool operator>(const array<T,N>& x, const array<T,N>& y);     // constexpr in C++20
8546035553Spatricktemplate <class T, size_t N>
86037e7968Spatrick  bool operator<=(const array<T,N>& x, const array<T,N>& y);    // constexpr in C++20
8746035553Spatricktemplate <class T, size_t N>
88037e7968Spatrick  bool operator>=(const array<T,N>& x, const array<T,N>& y);    // constexpr in C++20
8946035553Spatrick
9046035553Spatricktemplate <class T, size_t N >
91037e7968Spatrick  void swap(array<T,N>& x, array<T,N>& y) noexcept(noexcept(x.swap(y))); // constexpr in C++20
92037e7968Spatrick
93037e7968Spatricktemplate <class T, size_t N>
94037e7968Spatrick  constexpr array<remove_cv_t<T>, N> to_array(T (&a)[N]);  // C++20
95037e7968Spatricktemplate <class T, size_t N>
96037e7968Spatrick  constexpr array<remove_cv_t<T>, N> to_array(T (&&a)[N]); // C++20
9746035553Spatrick
9846035553Spatricktemplate <class T> struct tuple_size;
9946035553Spatricktemplate <size_t I, class T> struct tuple_element;
10046035553Spatricktemplate <class T, size_t N> struct tuple_size<array<T, N>>;
10146035553Spatricktemplate <size_t I, class T, size_t N> struct tuple_element<I, array<T, N>>;
10246035553Spatricktemplate <size_t I, class T, size_t N> T& get(array<T, N>&) noexcept;               // constexpr in C++14
10346035553Spatricktemplate <size_t I, class T, size_t N> const T& get(const array<T, N>&) noexcept;   // constexpr in C++14
10446035553Spatricktemplate <size_t I, class T, size_t N> T&& get(array<T, N>&&) noexcept;             // constexpr in C++14
10546035553Spatricktemplate <size_t I, class T, size_t N> const T&& get(const array<T, N>&&) noexcept; // constexpr in C++14
10646035553Spatrick
10746035553Spatrick}  // std
10846035553Spatrick
10946035553Spatrick*/
11046035553Spatrick
111*4bdff4beSrobert#include <__algorithm/equal.h>
112*4bdff4beSrobert#include <__algorithm/fill_n.h>
113*4bdff4beSrobert#include <__algorithm/lexicographical_compare.h>
114*4bdff4beSrobert#include <__algorithm/swap_ranges.h>
115*4bdff4beSrobert#include <__assert> // all public C++ headers provide the assertion handler
11646035553Spatrick#include <__config>
117*4bdff4beSrobert#include <__iterator/reverse_iterator.h>
118*4bdff4beSrobert#include <__tuple_dir/sfinae_helpers.h>
119*4bdff4beSrobert#include <__utility/integer_sequence.h>
120*4bdff4beSrobert#include <__utility/move.h>
121*4bdff4beSrobert#include <__utility/unreachable.h>
12276d0caaeSpatrick#include <stdexcept>
12346035553Spatrick#include <type_traits>
12446035553Spatrick#include <version>
12546035553Spatrick
126*4bdff4beSrobert// standard-mandated includes
127*4bdff4beSrobert
128*4bdff4beSrobert// [iterator.range]
129*4bdff4beSrobert#include <__iterator/access.h>
130*4bdff4beSrobert#include <__iterator/data.h>
131*4bdff4beSrobert#include <__iterator/empty.h>
132*4bdff4beSrobert#include <__iterator/reverse_access.h>
133*4bdff4beSrobert#include <__iterator/size.h>
134*4bdff4beSrobert
135*4bdff4beSrobert// [array.syn]
136*4bdff4beSrobert#include <compare>
137*4bdff4beSrobert#include <initializer_list>
138*4bdff4beSrobert
139*4bdff4beSrobert// [tuple.helper]
140*4bdff4beSrobert#include <__tuple_dir/tuple_element.h>
141*4bdff4beSrobert#include <__tuple_dir/tuple_size.h>
142*4bdff4beSrobert
14346035553Spatrick#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
14446035553Spatrick#  pragma GCC system_header
14546035553Spatrick#endif
14646035553Spatrick
14746035553Spatrick_LIBCPP_BEGIN_NAMESPACE_STD
14846035553Spatrick
14946035553Spatricktemplate <class _Tp, size_t _Size>
15046035553Spatrickstruct _LIBCPP_TEMPLATE_VIS array
15146035553Spatrick{
15246035553Spatrick    // types:
15346035553Spatrick    typedef array __self;
15446035553Spatrick    typedef _Tp                                   value_type;
15546035553Spatrick    typedef value_type&                           reference;
15646035553Spatrick    typedef const value_type&                     const_reference;
15746035553Spatrick    typedef value_type*                           iterator;
15846035553Spatrick    typedef const value_type*                     const_iterator;
15946035553Spatrick    typedef value_type*                           pointer;
16046035553Spatrick    typedef const value_type*                     const_pointer;
16146035553Spatrick    typedef size_t                                size_type;
16246035553Spatrick    typedef ptrdiff_t                             difference_type;
16376d0caaeSpatrick    typedef _VSTD::reverse_iterator<iterator>       reverse_iterator;
16476d0caaeSpatrick    typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
16546035553Spatrick
16646035553Spatrick    _Tp __elems_[_Size];
16746035553Spatrick
16846035553Spatrick    // No explicit construct/copy/destroy for aggregate type
169*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
170037e7968Spatrick    void fill(const value_type& __u) {
171037e7968Spatrick        _VSTD::fill_n(data(), _Size, __u);
17246035553Spatrick    }
17346035553Spatrick
174*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
17546035553Spatrick    void swap(array& __a) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) {
17676d0caaeSpatrick        _VSTD::swap_ranges(data(), data() + _Size, __a.data());
17746035553Spatrick    }
17846035553Spatrick
17946035553Spatrick    // iterators:
180*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
18146035553Spatrick    iterator begin() _NOEXCEPT {return iterator(data());}
182*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
18346035553Spatrick    const_iterator begin() const _NOEXCEPT {return const_iterator(data());}
184*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
18546035553Spatrick    iterator end() _NOEXCEPT {return iterator(data() + _Size);}
186*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
18746035553Spatrick    const_iterator end() const _NOEXCEPT {return const_iterator(data() + _Size);}
18846035553Spatrick
189*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
19046035553Spatrick    reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());}
191*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
19246035553Spatrick    const_reverse_iterator rbegin() const _NOEXCEPT {return const_reverse_iterator(end());}
193*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
19446035553Spatrick    reverse_iterator rend() _NOEXCEPT {return reverse_iterator(begin());}
195*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
19646035553Spatrick    const_reverse_iterator rend() const _NOEXCEPT {return const_reverse_iterator(begin());}
19746035553Spatrick
198*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
19946035553Spatrick    const_iterator cbegin() const _NOEXCEPT {return begin();}
200*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
20146035553Spatrick    const_iterator cend() const _NOEXCEPT {return end();}
202*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
20346035553Spatrick    const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();}
204*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
20546035553Spatrick    const_reverse_iterator crend() const _NOEXCEPT {return rend();}
20646035553Spatrick
20746035553Spatrick    // capacity:
20846035553Spatrick    _LIBCPP_INLINE_VISIBILITY
20946035553Spatrick    _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT {return _Size;}
21046035553Spatrick    _LIBCPP_INLINE_VISIBILITY
21146035553Spatrick    _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT {return _Size;}
21246035553Spatrick    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
213037e7968Spatrick    _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT {return _Size == 0;}
21446035553Spatrick
21546035553Spatrick    // element access:
216*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
217037e7968Spatrick    reference operator[](size_type __n) _NOEXCEPT {
218037e7968Spatrick        _LIBCPP_ASSERT(__n < _Size, "out-of-bounds access in std::array<T, N>");
219037e7968Spatrick        return __elems_[__n];
220037e7968Spatrick    }
221*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
222037e7968Spatrick    const_reference operator[](size_type __n) const _NOEXCEPT {
223037e7968Spatrick        _LIBCPP_ASSERT(__n < _Size, "out-of-bounds access in std::array<T, N>");
224037e7968Spatrick        return __elems_[__n];
225037e7968Spatrick    }
22646035553Spatrick
227*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX17 reference at(size_type __n)
228037e7968Spatrick    {
229037e7968Spatrick        if (__n >= _Size)
230037e7968Spatrick            __throw_out_of_range("array::at");
231037e7968Spatrick        return __elems_[__n];
232037e7968Spatrick    }
23346035553Spatrick
234*4bdff4beSrobert    _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference at(size_type __n) const
235037e7968Spatrick    {
236037e7968Spatrick        if (__n >= _Size)
237037e7968Spatrick            __throw_out_of_range("array::at");
238037e7968Spatrick        return __elems_[__n];
239037e7968Spatrick    }
240037e7968Spatrick
241*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 reference front()             _NOEXCEPT {return (*this)[0];}
242*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference front() const _NOEXCEPT {return (*this)[0];}
243*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 reference back()              _NOEXCEPT {return (*this)[_Size - 1];}
244*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference back() const  _NOEXCEPT {return (*this)[_Size - 1];}
24546035553Spatrick
246*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
24746035553Spatrick    value_type* data() _NOEXCEPT {return __elems_;}
248*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
24946035553Spatrick    const value_type* data() const _NOEXCEPT {return __elems_;}
25046035553Spatrick};
25146035553Spatrick
25246035553Spatricktemplate <class _Tp>
25346035553Spatrickstruct _LIBCPP_TEMPLATE_VIS array<_Tp, 0>
25446035553Spatrick{
25546035553Spatrick    // types:
25646035553Spatrick    typedef array __self;
25746035553Spatrick    typedef _Tp                                   value_type;
25846035553Spatrick    typedef value_type&                           reference;
25946035553Spatrick    typedef const value_type&                     const_reference;
26046035553Spatrick    typedef value_type*                           iterator;
26146035553Spatrick    typedef const value_type*                     const_iterator;
26246035553Spatrick    typedef value_type*                           pointer;
26346035553Spatrick    typedef const value_type*                     const_pointer;
26446035553Spatrick    typedef size_t                                size_type;
26546035553Spatrick    typedef ptrdiff_t                             difference_type;
26676d0caaeSpatrick    typedef _VSTD::reverse_iterator<iterator>       reverse_iterator;
26776d0caaeSpatrick    typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
26846035553Spatrick
269*4bdff4beSrobert    typedef __conditional_t<is_const<_Tp>::value, const char, char> _CharType;
27046035553Spatrick
27146035553Spatrick    struct  _ArrayInStructT { _Tp __data_[1]; };
27246035553Spatrick    _ALIGNAS_TYPE(_ArrayInStructT) _CharType __elems_[sizeof(_ArrayInStructT)];
27346035553Spatrick
274*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
275037e7968Spatrick    value_type* data() _NOEXCEPT {return nullptr;}
276*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
277037e7968Spatrick    const value_type* data() const _NOEXCEPT {return nullptr;}
278037e7968Spatrick
27946035553Spatrick    // No explicit construct/copy/destroy for aggregate type
280*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
281037e7968Spatrick    void fill(const value_type&) {
28246035553Spatrick      static_assert(!is_const<_Tp>::value,
28346035553Spatrick                    "cannot fill zero-sized array of type 'const T'");
28446035553Spatrick    }
28546035553Spatrick
286*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
28746035553Spatrick    void swap(array&) _NOEXCEPT {
28846035553Spatrick      static_assert(!is_const<_Tp>::value,
28946035553Spatrick                    "cannot swap zero-sized array of type 'const T'");
29046035553Spatrick    }
29146035553Spatrick
29246035553Spatrick    // iterators:
293*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
29446035553Spatrick    iterator begin() _NOEXCEPT {return iterator(data());}
295*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
29646035553Spatrick    const_iterator begin() const _NOEXCEPT {return const_iterator(data());}
297*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
29846035553Spatrick    iterator end() _NOEXCEPT {return iterator(data());}
299*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
30046035553Spatrick    const_iterator end() const _NOEXCEPT {return const_iterator(data());}
30146035553Spatrick
302*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
30346035553Spatrick    reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());}
304*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
30546035553Spatrick    const_reverse_iterator rbegin() const _NOEXCEPT {return const_reverse_iterator(end());}
306*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
30746035553Spatrick    reverse_iterator rend() _NOEXCEPT {return reverse_iterator(begin());}
308*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
30946035553Spatrick    const_reverse_iterator rend() const _NOEXCEPT {return const_reverse_iterator(begin());}
31046035553Spatrick
311*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
31246035553Spatrick    const_iterator cbegin() const _NOEXCEPT {return begin();}
313*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
31446035553Spatrick    const_iterator cend() const _NOEXCEPT {return end();}
315*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
31646035553Spatrick    const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();}
317*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
31846035553Spatrick    const_reverse_iterator crend() const _NOEXCEPT {return rend();}
31946035553Spatrick
32046035553Spatrick    // capacity:
32146035553Spatrick    _LIBCPP_INLINE_VISIBILITY
32246035553Spatrick    _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT {return 0; }
32346035553Spatrick    _LIBCPP_INLINE_VISIBILITY
32446035553Spatrick    _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT {return 0;}
32546035553Spatrick    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
32646035553Spatrick    _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT {return true;}
32746035553Spatrick
32846035553Spatrick    // element access:
329*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
33046035553Spatrick    reference operator[](size_type) _NOEXCEPT {
33146035553Spatrick      _LIBCPP_ASSERT(false, "cannot call array<T, 0>::operator[] on a zero-sized array");
332*4bdff4beSrobert      __libcpp_unreachable();
33346035553Spatrick    }
33446035553Spatrick
335*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
33646035553Spatrick    const_reference operator[](size_type) const _NOEXCEPT {
33746035553Spatrick      _LIBCPP_ASSERT(false, "cannot call array<T, 0>::operator[] on a zero-sized array");
338*4bdff4beSrobert      __libcpp_unreachable();
33946035553Spatrick    }
34046035553Spatrick
341*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
34246035553Spatrick    reference at(size_type) {
34346035553Spatrick      __throw_out_of_range("array<T, 0>::at");
344*4bdff4beSrobert      __libcpp_unreachable();
34546035553Spatrick    }
34646035553Spatrick
347*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
34846035553Spatrick    const_reference at(size_type) const {
34946035553Spatrick      __throw_out_of_range("array<T, 0>::at");
350*4bdff4beSrobert      __libcpp_unreachable();
35146035553Spatrick    }
35246035553Spatrick
353*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
35446035553Spatrick    reference front() _NOEXCEPT {
35546035553Spatrick      _LIBCPP_ASSERT(false, "cannot call array<T, 0>::front() on a zero-sized array");
356*4bdff4beSrobert      __libcpp_unreachable();
35746035553Spatrick    }
35846035553Spatrick
359*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
36046035553Spatrick    const_reference front() const _NOEXCEPT {
36146035553Spatrick      _LIBCPP_ASSERT(false, "cannot call array<T, 0>::front() on a zero-sized array");
362*4bdff4beSrobert      __libcpp_unreachable();
36346035553Spatrick    }
36446035553Spatrick
365*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
36646035553Spatrick    reference back() _NOEXCEPT {
36746035553Spatrick      _LIBCPP_ASSERT(false, "cannot call array<T, 0>::back() on a zero-sized array");
368*4bdff4beSrobert      __libcpp_unreachable();
36946035553Spatrick    }
37046035553Spatrick
371*4bdff4beSrobert    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
37246035553Spatrick    const_reference back() const _NOEXCEPT {
37346035553Spatrick      _LIBCPP_ASSERT(false, "cannot call array<T, 0>::back() on a zero-sized array");
374*4bdff4beSrobert      __libcpp_unreachable();
37546035553Spatrick    }
37646035553Spatrick};
37746035553Spatrick
37846035553Spatrick
379*4bdff4beSrobert#if _LIBCPP_STD_VER > 14
38046035553Spatricktemplate<class _Tp, class... _Args,
381*4bdff4beSrobert         class = enable_if_t<__all<_IsSame<_Tp, _Args>::value...>::value>
38246035553Spatrick         >
38346035553Spatrickarray(_Tp, _Args...)
38446035553Spatrick  -> array<_Tp, 1 + sizeof...(_Args)>;
38546035553Spatrick#endif
38646035553Spatrick
38746035553Spatricktemplate <class _Tp, size_t _Size>
38846035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
389*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20 bool
39046035553Spatrickoperator==(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
39146035553Spatrick{
39246035553Spatrick    return _VSTD::equal(__x.begin(), __x.end(), __y.begin());
39346035553Spatrick}
39446035553Spatrick
39546035553Spatricktemplate <class _Tp, size_t _Size>
39646035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
397*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20 bool
39846035553Spatrickoperator!=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
39946035553Spatrick{
40046035553Spatrick    return !(__x == __y);
40146035553Spatrick}
40246035553Spatrick
40346035553Spatricktemplate <class _Tp, size_t _Size>
40446035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
405*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20 bool
40646035553Spatrickoperator<(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
40746035553Spatrick{
40846035553Spatrick    return _VSTD::lexicographical_compare(__x.begin(), __x.end(),
40946035553Spatrick                                          __y.begin(), __y.end());
41046035553Spatrick}
41146035553Spatrick
41246035553Spatricktemplate <class _Tp, size_t _Size>
41346035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
414*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20 bool
41546035553Spatrickoperator>(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
41646035553Spatrick{
41746035553Spatrick    return __y < __x;
41846035553Spatrick}
41946035553Spatrick
42046035553Spatricktemplate <class _Tp, size_t _Size>
42146035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
422*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20 bool
42346035553Spatrickoperator<=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
42446035553Spatrick{
42546035553Spatrick    return !(__y < __x);
42646035553Spatrick}
42746035553Spatrick
42846035553Spatricktemplate <class _Tp, size_t _Size>
42946035553Spatrickinline _LIBCPP_INLINE_VISIBILITY
430*4bdff4beSrobert_LIBCPP_CONSTEXPR_SINCE_CXX20 bool
43146035553Spatrickoperator>=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
43246035553Spatrick{
43346035553Spatrick    return !(__x < __y);
43446035553Spatrick}
43546035553Spatrick
43646035553Spatricktemplate <class _Tp, size_t _Size>
437*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
438*4bdff4beSrobert__enable_if_t<_Size == 0 || __is_swappable<_Tp>::value, void>
43946035553Spatrickswap(array<_Tp, _Size>& __x, array<_Tp, _Size>& __y)
44046035553Spatrick                                  _NOEXCEPT_(noexcept(__x.swap(__y)))
44146035553Spatrick{
44246035553Spatrick    __x.swap(__y);
44346035553Spatrick}
44446035553Spatrick
44546035553Spatricktemplate <class _Tp, size_t _Size>
44646035553Spatrickstruct _LIBCPP_TEMPLATE_VIS tuple_size<array<_Tp, _Size> >
44746035553Spatrick    : public integral_constant<size_t, _Size> {};
44846035553Spatrick
44946035553Spatricktemplate <size_t _Ip, class _Tp, size_t _Size>
45046035553Spatrickstruct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, array<_Tp, _Size> >
45146035553Spatrick{
45246035553Spatrick    static_assert(_Ip < _Size, "Index out of bounds in std::tuple_element<> (std::array)");
45346035553Spatrick    typedef _Tp type;
45446035553Spatrick};
45546035553Spatrick
45646035553Spatricktemplate <size_t _Ip, class _Tp, size_t _Size>
457*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
45846035553Spatrick_Tp&
45946035553Spatrickget(array<_Tp, _Size>& __a) _NOEXCEPT
46046035553Spatrick{
46146035553Spatrick    static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array)");
46246035553Spatrick    return __a.__elems_[_Ip];
46346035553Spatrick}
46446035553Spatrick
46546035553Spatricktemplate <size_t _Ip, class _Tp, size_t _Size>
466*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
46746035553Spatrickconst _Tp&
46846035553Spatrickget(const array<_Tp, _Size>& __a) _NOEXCEPT
46946035553Spatrick{
47046035553Spatrick    static_assert(_Ip < _Size, "Index out of bounds in std::get<> (const std::array)");
47146035553Spatrick    return __a.__elems_[_Ip];
47246035553Spatrick}
47346035553Spatrick
47446035553Spatricktemplate <size_t _Ip, class _Tp, size_t _Size>
475*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
47646035553Spatrick_Tp&&
47746035553Spatrickget(array<_Tp, _Size>&& __a) _NOEXCEPT
47846035553Spatrick{
47946035553Spatrick    static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array &&)");
48046035553Spatrick    return _VSTD::move(__a.__elems_[_Ip]);
48146035553Spatrick}
48246035553Spatrick
48346035553Spatricktemplate <size_t _Ip, class _Tp, size_t _Size>
484*4bdff4beSrobertinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
48546035553Spatrickconst _Tp&&
48646035553Spatrickget(const array<_Tp, _Size>&& __a) _NOEXCEPT
48746035553Spatrick{
48846035553Spatrick    static_assert(_Ip < _Size, "Index out of bounds in std::get<> (const std::array &&)");
48946035553Spatrick    return _VSTD::move(__a.__elems_[_Ip]);
49046035553Spatrick}
49146035553Spatrick
492037e7968Spatrick#if _LIBCPP_STD_VER > 17
493037e7968Spatrick
494037e7968Spatricktemplate <typename _Tp, size_t _Size, size_t... _Index>
495037e7968Spatrick_LIBCPP_INLINE_VISIBILITY constexpr array<remove_cv_t<_Tp>, _Size>
496037e7968Spatrick__to_array_lvalue_impl(_Tp (&__arr)[_Size], index_sequence<_Index...>) {
497037e7968Spatrick  return {{__arr[_Index]...}};
498037e7968Spatrick}
499037e7968Spatrick
500037e7968Spatricktemplate <typename _Tp, size_t _Size, size_t... _Index>
501037e7968Spatrick_LIBCPP_INLINE_VISIBILITY constexpr array<remove_cv_t<_Tp>, _Size>
502037e7968Spatrick__to_array_rvalue_impl(_Tp(&&__arr)[_Size], index_sequence<_Index...>) {
503037e7968Spatrick  return {{_VSTD::move(__arr[_Index])...}};
504037e7968Spatrick}
505037e7968Spatrick
506037e7968Spatricktemplate <typename _Tp, size_t _Size>
507037e7968Spatrick_LIBCPP_INLINE_VISIBILITY constexpr array<remove_cv_t<_Tp>, _Size>
508037e7968Spatrickto_array(_Tp (&__arr)[_Size]) noexcept(is_nothrow_constructible_v<_Tp, _Tp&>) {
509037e7968Spatrick  static_assert(
510037e7968Spatrick      !is_array_v<_Tp>,
511037e7968Spatrick      "[array.creation]/1: to_array does not accept multidimensional arrays.");
512037e7968Spatrick  static_assert(
513037e7968Spatrick      is_constructible_v<_Tp, _Tp&>,
514037e7968Spatrick      "[array.creation]/1: to_array requires copy constructible elements.");
51576d0caaeSpatrick  return _VSTD::__to_array_lvalue_impl(__arr, make_index_sequence<_Size>());
516037e7968Spatrick}
517037e7968Spatrick
518037e7968Spatricktemplate <typename _Tp, size_t _Size>
519037e7968Spatrick_LIBCPP_INLINE_VISIBILITY constexpr array<remove_cv_t<_Tp>, _Size>
520037e7968Spatrickto_array(_Tp(&&__arr)[_Size]) noexcept(is_nothrow_move_constructible_v<_Tp>) {
521037e7968Spatrick  static_assert(
522037e7968Spatrick      !is_array_v<_Tp>,
523037e7968Spatrick      "[array.creation]/4: to_array does not accept multidimensional arrays.");
524037e7968Spatrick  static_assert(
525037e7968Spatrick      is_move_constructible_v<_Tp>,
526037e7968Spatrick      "[array.creation]/4: to_array requires move constructible elements.");
52776d0caaeSpatrick  return _VSTD::__to_array_rvalue_impl(_VSTD::move(__arr),
528037e7968Spatrick                                       make_index_sequence<_Size>());
529037e7968Spatrick}
530037e7968Spatrick
531037e7968Spatrick#endif // _LIBCPP_STD_VER > 17
532037e7968Spatrick
53346035553Spatrick_LIBCPP_END_NAMESPACE_STD
53446035553Spatrick
535*4bdff4beSrobert#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
536*4bdff4beSrobert#  include <algorithm>
537*4bdff4beSrobert#  include <concepts>
538*4bdff4beSrobert#  include <iterator>
539*4bdff4beSrobert#  include <utility>
540*4bdff4beSrobert#endif
541*4bdff4beSrobert
54246035553Spatrick#endif // _LIBCPP_ARRAY
543