xref: /freebsd/contrib/llvm-project/libcxx/include/array (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric// -*- C++ -*-
2*0b57cec5SDimitry Andric//===---------------------------- array -----------------------------------===//
3*0b57cec5SDimitry Andric//
4*0b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5*0b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
6*0b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7*0b57cec5SDimitry Andric//
8*0b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
9*0b57cec5SDimitry Andric
10*0b57cec5SDimitry Andric#ifndef _LIBCPP_ARRAY
11*0b57cec5SDimitry Andric#define _LIBCPP_ARRAY
12*0b57cec5SDimitry Andric
13*0b57cec5SDimitry Andric/*
14*0b57cec5SDimitry Andric    array synopsis
15*0b57cec5SDimitry Andric
16*0b57cec5SDimitry Andricnamespace std
17*0b57cec5SDimitry Andric{
18*0b57cec5SDimitry Andrictemplate <class T, size_t N >
19*0b57cec5SDimitry Andricstruct array
20*0b57cec5SDimitry Andric{
21*0b57cec5SDimitry Andric    // types:
22*0b57cec5SDimitry Andric    typedef T & reference;
23*0b57cec5SDimitry Andric    typedef const T & const_reference;
24*0b57cec5SDimitry Andric    typedef implementation defined iterator;
25*0b57cec5SDimitry Andric    typedef implementation defined const_iterator;
26*0b57cec5SDimitry Andric    typedef size_t size_type;
27*0b57cec5SDimitry Andric    typedef ptrdiff_t difference_type;
28*0b57cec5SDimitry Andric    typedef T value_type;
29*0b57cec5SDimitry Andric    typedef T* pointer;
30*0b57cec5SDimitry Andric    typedef const T* const_pointer;
31*0b57cec5SDimitry Andric    typedef std::reverse_iterator<iterator> reverse_iterator;
32*0b57cec5SDimitry Andric    typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
33*0b57cec5SDimitry Andric
34*0b57cec5SDimitry Andric    // No explicit construct/copy/destroy for aggregate type
35*0b57cec5SDimitry Andric    void fill(const T& u);
36*0b57cec5SDimitry Andric    void swap(array& a) noexcept(is_nothrow_swappable_v<T>);
37*0b57cec5SDimitry Andric
38*0b57cec5SDimitry Andric    // iterators:
39*0b57cec5SDimitry Andric    iterator begin() noexcept;
40*0b57cec5SDimitry Andric    const_iterator begin() const noexcept;
41*0b57cec5SDimitry Andric    iterator end() noexcept;
42*0b57cec5SDimitry Andric    const_iterator end() const noexcept;
43*0b57cec5SDimitry Andric
44*0b57cec5SDimitry Andric    reverse_iterator rbegin() noexcept;
45*0b57cec5SDimitry Andric    const_reverse_iterator rbegin() const noexcept;
46*0b57cec5SDimitry Andric    reverse_iterator rend() noexcept;
47*0b57cec5SDimitry Andric    const_reverse_iterator rend() const noexcept;
48*0b57cec5SDimitry Andric
49*0b57cec5SDimitry Andric    const_iterator cbegin() const noexcept;
50*0b57cec5SDimitry Andric    const_iterator cend() const noexcept;
51*0b57cec5SDimitry Andric    const_reverse_iterator crbegin() const noexcept;
52*0b57cec5SDimitry Andric    const_reverse_iterator crend() const noexcept;
53*0b57cec5SDimitry Andric
54*0b57cec5SDimitry Andric    // capacity:
55*0b57cec5SDimitry Andric    constexpr size_type size() const noexcept;
56*0b57cec5SDimitry Andric    constexpr size_type max_size() const noexcept;
57*0b57cec5SDimitry Andric    constexpr bool empty() const noexcept;
58*0b57cec5SDimitry Andric
59*0b57cec5SDimitry Andric    // element access:
60*0b57cec5SDimitry Andric    reference operator[](size_type n);
61*0b57cec5SDimitry Andric    const_reference operator[](size_type n) const; // constexpr in C++14
62*0b57cec5SDimitry Andric    const_reference at(size_type n) const; // constexpr in C++14
63*0b57cec5SDimitry Andric    reference at(size_type n);
64*0b57cec5SDimitry Andric
65*0b57cec5SDimitry Andric    reference front();
66*0b57cec5SDimitry Andric    const_reference front() const; // constexpr in C++14
67*0b57cec5SDimitry Andric    reference back();
68*0b57cec5SDimitry Andric    const_reference back() const; // constexpr in C++14
69*0b57cec5SDimitry Andric
70*0b57cec5SDimitry Andric    T* data() noexcept;
71*0b57cec5SDimitry Andric    const T* data() const noexcept;
72*0b57cec5SDimitry Andric};
73*0b57cec5SDimitry Andric
74*0b57cec5SDimitry Andric  template <class T, class... U>
75*0b57cec5SDimitry Andric    array(T, U...) -> array<T, 1 + sizeof...(U)>;
76*0b57cec5SDimitry Andric
77*0b57cec5SDimitry Andrictemplate <class T, size_t N>
78*0b57cec5SDimitry Andric  bool operator==(const array<T,N>& x, const array<T,N>& y);
79*0b57cec5SDimitry Andrictemplate <class T, size_t N>
80*0b57cec5SDimitry Andric  bool operator!=(const array<T,N>& x, const array<T,N>& y);
81*0b57cec5SDimitry Andrictemplate <class T, size_t N>
82*0b57cec5SDimitry Andric  bool operator<(const array<T,N>& x, const array<T,N>& y);
83*0b57cec5SDimitry Andrictemplate <class T, size_t N>
84*0b57cec5SDimitry Andric  bool operator>(const array<T,N>& x, const array<T,N>& y);
85*0b57cec5SDimitry Andrictemplate <class T, size_t N>
86*0b57cec5SDimitry Andric  bool operator<=(const array<T,N>& x, const array<T,N>& y);
87*0b57cec5SDimitry Andrictemplate <class T, size_t N>
88*0b57cec5SDimitry Andric  bool operator>=(const array<T,N>& x, const array<T,N>& y);
89*0b57cec5SDimitry Andric
90*0b57cec5SDimitry Andrictemplate <class T, size_t N >
91*0b57cec5SDimitry Andric  void swap(array<T,N>& x, array<T,N>& y) noexcept(noexcept(x.swap(y))); // C++17
92*0b57cec5SDimitry Andric
93*0b57cec5SDimitry Andrictemplate <class T> struct tuple_size;
94*0b57cec5SDimitry Andrictemplate <size_t I, class T> struct tuple_element;
95*0b57cec5SDimitry Andrictemplate <class T, size_t N> struct tuple_size<array<T, N>>;
96*0b57cec5SDimitry Andrictemplate <size_t I, class T, size_t N> struct tuple_element<I, array<T, N>>;
97*0b57cec5SDimitry Andrictemplate <size_t I, class T, size_t N> T& get(array<T, N>&) noexcept; // constexpr in C++14
98*0b57cec5SDimitry Andrictemplate <size_t I, class T, size_t N> const T& get(const array<T, N>&) noexcept; // constexpr in C++14
99*0b57cec5SDimitry Andrictemplate <size_t I, class T, size_t N> T&& get(array<T, N>&&) noexcept; // constexpr in C++14
100*0b57cec5SDimitry Andrictemplate <size_t I, class T, size_t N> const T&& get(const array<T, N>&&) noexcept; // constexpr in C++14
101*0b57cec5SDimitry Andric
102*0b57cec5SDimitry Andric}  // std
103*0b57cec5SDimitry Andric
104*0b57cec5SDimitry Andric*/
105*0b57cec5SDimitry Andric
106*0b57cec5SDimitry Andric#include <__config>
107*0b57cec5SDimitry Andric#include <__tuple>
108*0b57cec5SDimitry Andric#include <type_traits>
109*0b57cec5SDimitry Andric#include <utility>
110*0b57cec5SDimitry Andric#include <iterator>
111*0b57cec5SDimitry Andric#include <algorithm>
112*0b57cec5SDimitry Andric#include <stdexcept>
113*0b57cec5SDimitry Andric#include <cstdlib> // for _LIBCPP_UNREACHABLE
114*0b57cec5SDimitry Andric#include <version>
115*0b57cec5SDimitry Andric#include <__debug>
116*0b57cec5SDimitry Andric
117*0b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
118*0b57cec5SDimitry Andric#pragma GCC system_header
119*0b57cec5SDimitry Andric#endif
120*0b57cec5SDimitry Andric
121*0b57cec5SDimitry Andric
122*0b57cec5SDimitry Andric
123*0b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
124*0b57cec5SDimitry Andric
125*0b57cec5SDimitry Andric
126*0b57cec5SDimitry Andrictemplate <class _Tp, size_t _Size>
127*0b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS array
128*0b57cec5SDimitry Andric{
129*0b57cec5SDimitry Andric    // types:
130*0b57cec5SDimitry Andric    typedef array __self;
131*0b57cec5SDimitry Andric    typedef _Tp                                   value_type;
132*0b57cec5SDimitry Andric    typedef value_type&                           reference;
133*0b57cec5SDimitry Andric    typedef const value_type&                     const_reference;
134*0b57cec5SDimitry Andric    typedef value_type*                           iterator;
135*0b57cec5SDimitry Andric    typedef const value_type*                     const_iterator;
136*0b57cec5SDimitry Andric    typedef value_type*                           pointer;
137*0b57cec5SDimitry Andric    typedef const value_type*                     const_pointer;
138*0b57cec5SDimitry Andric    typedef size_t                                size_type;
139*0b57cec5SDimitry Andric    typedef ptrdiff_t                             difference_type;
140*0b57cec5SDimitry Andric    typedef std::reverse_iterator<iterator>       reverse_iterator;
141*0b57cec5SDimitry Andric    typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
142*0b57cec5SDimitry Andric
143*0b57cec5SDimitry Andric    _Tp __elems_[_Size];
144*0b57cec5SDimitry Andric
145*0b57cec5SDimitry Andric    // No explicit construct/copy/destroy for aggregate type
146*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void fill(const value_type& __u) {
147*0b57cec5SDimitry Andric      _VSTD::fill_n(__elems_, _Size, __u);
148*0b57cec5SDimitry Andric    }
149*0b57cec5SDimitry Andric
150*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
151*0b57cec5SDimitry Andric    void swap(array& __a) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) {
152*0b57cec5SDimitry Andric      std::swap_ranges(__elems_, __elems_ + _Size, __a.__elems_);
153*0b57cec5SDimitry Andric    }
154*0b57cec5SDimitry Andric
155*0b57cec5SDimitry Andric    // iterators:
156*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
157*0b57cec5SDimitry Andric    iterator begin() _NOEXCEPT {return iterator(data());}
158*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
159*0b57cec5SDimitry Andric    const_iterator begin() const _NOEXCEPT {return const_iterator(data());}
160*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
161*0b57cec5SDimitry Andric    iterator end() _NOEXCEPT {return iterator(data() + _Size);}
162*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
163*0b57cec5SDimitry Andric    const_iterator end() const _NOEXCEPT {return const_iterator(data() + _Size);}
164*0b57cec5SDimitry Andric
165*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
166*0b57cec5SDimitry Andric    reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());}
167*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
168*0b57cec5SDimitry Andric    const_reverse_iterator rbegin() const _NOEXCEPT {return const_reverse_iterator(end());}
169*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
170*0b57cec5SDimitry Andric    reverse_iterator rend() _NOEXCEPT {return reverse_iterator(begin());}
171*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
172*0b57cec5SDimitry Andric    const_reverse_iterator rend() const _NOEXCEPT {return const_reverse_iterator(begin());}
173*0b57cec5SDimitry Andric
174*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
175*0b57cec5SDimitry Andric    const_iterator cbegin() const _NOEXCEPT {return begin();}
176*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
177*0b57cec5SDimitry Andric    const_iterator cend() const _NOEXCEPT {return end();}
178*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
179*0b57cec5SDimitry Andric    const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();}
180*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
181*0b57cec5SDimitry Andric    const_reverse_iterator crend() const _NOEXCEPT {return rend();}
182*0b57cec5SDimitry Andric
183*0b57cec5SDimitry Andric    // capacity:
184*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
185*0b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT {return _Size;}
186*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
187*0b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT {return _Size;}
188*0b57cec5SDimitry Andric    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
189*0b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT {return false; }
190*0b57cec5SDimitry Andric
191*0b57cec5SDimitry Andric    // element access:
192*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
193*0b57cec5SDimitry Andric    reference operator[](size_type __n)             _NOEXCEPT {return __elems_[__n];}
194*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
195*0b57cec5SDimitry Andric    const_reference operator[](size_type __n) const _NOEXCEPT {return __elems_[__n];}
196*0b57cec5SDimitry Andric
197*0b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX14       reference at(size_type __n);
198*0b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference at(size_type __n) const;
199*0b57cec5SDimitry Andric
200*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reference front()             _NOEXCEPT {return __elems_[0];}
201*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference front() const _NOEXCEPT {return __elems_[0];}
202*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14 reference back()              _NOEXCEPT {return __elems_[_Size - 1];}
203*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference back() const  _NOEXCEPT {return __elems_[_Size - 1];}
204*0b57cec5SDimitry Andric
205*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
206*0b57cec5SDimitry Andric    value_type* data() _NOEXCEPT {return __elems_;}
207*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX14
208*0b57cec5SDimitry Andric    const value_type* data() const _NOEXCEPT {return __elems_;}
209*0b57cec5SDimitry Andric};
210*0b57cec5SDimitry Andric
211*0b57cec5SDimitry Andric
212*0b57cec5SDimitry Andrictemplate <class _Tp, size_t _Size>
213*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX14
214*0b57cec5SDimitry Andrictypename array<_Tp, _Size>::reference
215*0b57cec5SDimitry Andricarray<_Tp, _Size>::at(size_type __n)
216*0b57cec5SDimitry Andric{
217*0b57cec5SDimitry Andric    if (__n >= _Size)
218*0b57cec5SDimitry Andric        __throw_out_of_range("array::at");
219*0b57cec5SDimitry Andric
220*0b57cec5SDimitry Andric    return __elems_[__n];
221*0b57cec5SDimitry Andric}
222*0b57cec5SDimitry Andric
223*0b57cec5SDimitry Andrictemplate <class _Tp, size_t _Size>
224*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX11
225*0b57cec5SDimitry Andrictypename array<_Tp, _Size>::const_reference
226*0b57cec5SDimitry Andricarray<_Tp, _Size>::at(size_type __n) const
227*0b57cec5SDimitry Andric{
228*0b57cec5SDimitry Andric    if (__n >= _Size)
229*0b57cec5SDimitry Andric        __throw_out_of_range("array::at");
230*0b57cec5SDimitry Andric    return __elems_[__n];
231*0b57cec5SDimitry Andric}
232*0b57cec5SDimitry Andric
233*0b57cec5SDimitry Andrictemplate <class _Tp>
234*0b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS array<_Tp, 0>
235*0b57cec5SDimitry Andric{
236*0b57cec5SDimitry Andric    // types:
237*0b57cec5SDimitry Andric    typedef array __self;
238*0b57cec5SDimitry Andric    typedef _Tp                                   value_type;
239*0b57cec5SDimitry Andric    typedef value_type&                           reference;
240*0b57cec5SDimitry Andric    typedef const value_type&                     const_reference;
241*0b57cec5SDimitry Andric    typedef value_type*                           iterator;
242*0b57cec5SDimitry Andric    typedef const value_type*                     const_iterator;
243*0b57cec5SDimitry Andric    typedef value_type*                           pointer;
244*0b57cec5SDimitry Andric    typedef const value_type*                     const_pointer;
245*0b57cec5SDimitry Andric    typedef size_t                                size_type;
246*0b57cec5SDimitry Andric    typedef ptrdiff_t                             difference_type;
247*0b57cec5SDimitry Andric    typedef std::reverse_iterator<iterator>       reverse_iterator;
248*0b57cec5SDimitry Andric    typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
249*0b57cec5SDimitry Andric
250*0b57cec5SDimitry Andric    typedef typename conditional<is_const<_Tp>::value, const char,
251*0b57cec5SDimitry Andric                                char>::type _CharType;
252*0b57cec5SDimitry Andric
253*0b57cec5SDimitry Andric    struct  _ArrayInStructT { _Tp __data_[1]; };
254*0b57cec5SDimitry Andric    _ALIGNAS_TYPE(_ArrayInStructT) _CharType __elems_[sizeof(_ArrayInStructT)];
255*0b57cec5SDimitry Andric
256*0b57cec5SDimitry Andric    // No explicit construct/copy/destroy for aggregate type
257*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY void fill(const value_type&) {
258*0b57cec5SDimitry Andric      static_assert(!is_const<_Tp>::value,
259*0b57cec5SDimitry Andric                    "cannot fill zero-sized array of type 'const T'");
260*0b57cec5SDimitry Andric    }
261*0b57cec5SDimitry Andric
262*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
263*0b57cec5SDimitry Andric    void swap(array&) _NOEXCEPT {
264*0b57cec5SDimitry Andric      static_assert(!is_const<_Tp>::value,
265*0b57cec5SDimitry Andric                    "cannot swap zero-sized array of type 'const T'");
266*0b57cec5SDimitry Andric    }
267*0b57cec5SDimitry Andric
268*0b57cec5SDimitry Andric    // iterators:
269*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
270*0b57cec5SDimitry Andric    iterator begin() _NOEXCEPT {return iterator(data());}
271*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
272*0b57cec5SDimitry Andric    const_iterator begin() const _NOEXCEPT {return const_iterator(data());}
273*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
274*0b57cec5SDimitry Andric    iterator end() _NOEXCEPT {return iterator(data());}
275*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
276*0b57cec5SDimitry Andric    const_iterator end() const _NOEXCEPT {return const_iterator(data());}
277*0b57cec5SDimitry Andric
278*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
279*0b57cec5SDimitry Andric    reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());}
280*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
281*0b57cec5SDimitry Andric    const_reverse_iterator rbegin() const _NOEXCEPT {return const_reverse_iterator(end());}
282*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
283*0b57cec5SDimitry Andric    reverse_iterator rend() _NOEXCEPT {return reverse_iterator(begin());}
284*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
285*0b57cec5SDimitry Andric    const_reverse_iterator rend() const _NOEXCEPT {return const_reverse_iterator(begin());}
286*0b57cec5SDimitry Andric
287*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
288*0b57cec5SDimitry Andric    const_iterator cbegin() const _NOEXCEPT {return begin();}
289*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
290*0b57cec5SDimitry Andric    const_iterator cend() const _NOEXCEPT {return end();}
291*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
292*0b57cec5SDimitry Andric    const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();}
293*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
294*0b57cec5SDimitry Andric    const_reverse_iterator crend() const _NOEXCEPT {return rend();}
295*0b57cec5SDimitry Andric
296*0b57cec5SDimitry Andric    // capacity:
297*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
298*0b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT {return 0; }
299*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
300*0b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT {return 0;}
301*0b57cec5SDimitry Andric    _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
302*0b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT {return true;}
303*0b57cec5SDimitry Andric
304*0b57cec5SDimitry Andric    // element access:
305*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
306*0b57cec5SDimitry Andric    reference operator[](size_type) _NOEXCEPT {
307*0b57cec5SDimitry Andric      _LIBCPP_ASSERT(false, "cannot call array<T, 0>::operator[] on a zero-sized array");
308*0b57cec5SDimitry Andric      _LIBCPP_UNREACHABLE();
309*0b57cec5SDimitry Andric    }
310*0b57cec5SDimitry Andric
311*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
312*0b57cec5SDimitry Andric    const_reference operator[](size_type) const _NOEXCEPT {
313*0b57cec5SDimitry Andric      _LIBCPP_ASSERT(false, "cannot call array<T, 0>::operator[] on a zero-sized array");
314*0b57cec5SDimitry Andric      _LIBCPP_UNREACHABLE();
315*0b57cec5SDimitry Andric    }
316*0b57cec5SDimitry Andric
317*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
318*0b57cec5SDimitry Andric    reference at(size_type) {
319*0b57cec5SDimitry Andric      __throw_out_of_range("array<T, 0>::at");
320*0b57cec5SDimitry Andric      _LIBCPP_UNREACHABLE();
321*0b57cec5SDimitry Andric    }
322*0b57cec5SDimitry Andric
323*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
324*0b57cec5SDimitry Andric    const_reference at(size_type) const {
325*0b57cec5SDimitry Andric      __throw_out_of_range("array<T, 0>::at");
326*0b57cec5SDimitry Andric      _LIBCPP_UNREACHABLE();
327*0b57cec5SDimitry Andric    }
328*0b57cec5SDimitry Andric
329*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
330*0b57cec5SDimitry Andric    reference front() _NOEXCEPT {
331*0b57cec5SDimitry Andric      _LIBCPP_ASSERT(false, "cannot call array<T, 0>::front() on a zero-sized array");
332*0b57cec5SDimitry Andric      _LIBCPP_UNREACHABLE();
333*0b57cec5SDimitry Andric    }
334*0b57cec5SDimitry Andric
335*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
336*0b57cec5SDimitry Andric    const_reference front() const _NOEXCEPT {
337*0b57cec5SDimitry Andric      _LIBCPP_ASSERT(false, "cannot call array<T, 0>::front() on a zero-sized array");
338*0b57cec5SDimitry Andric      _LIBCPP_UNREACHABLE();
339*0b57cec5SDimitry Andric    }
340*0b57cec5SDimitry Andric
341*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
342*0b57cec5SDimitry Andric    reference back() _NOEXCEPT {
343*0b57cec5SDimitry Andric      _LIBCPP_ASSERT(false, "cannot call array<T, 0>::back() on a zero-sized array");
344*0b57cec5SDimitry Andric      _LIBCPP_UNREACHABLE();
345*0b57cec5SDimitry Andric    }
346*0b57cec5SDimitry Andric
347*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
348*0b57cec5SDimitry Andric    const_reference back() const _NOEXCEPT {
349*0b57cec5SDimitry Andric      _LIBCPP_ASSERT(false, "cannot call array<T, 0>::back() on a zero-sized array");
350*0b57cec5SDimitry Andric      _LIBCPP_UNREACHABLE();
351*0b57cec5SDimitry Andric    }
352*0b57cec5SDimitry Andric
353*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
354*0b57cec5SDimitry Andric    value_type* data() _NOEXCEPT {return reinterpret_cast<value_type*>(__elems_);}
355*0b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
356*0b57cec5SDimitry Andric    const value_type* data() const _NOEXCEPT {return reinterpret_cast<const value_type*>(__elems_);}
357*0b57cec5SDimitry Andric};
358*0b57cec5SDimitry Andric
359*0b57cec5SDimitry Andric
360*0b57cec5SDimitry Andric#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
361*0b57cec5SDimitry Andrictemplate<class _Tp, class... _Args,
362*0b57cec5SDimitry Andric         class = typename enable_if<(is_same_v<_Tp, _Args> && ...), void>::type
363*0b57cec5SDimitry Andric         >
364*0b57cec5SDimitry Andricarray(_Tp, _Args...)
365*0b57cec5SDimitry Andric  -> array<_Tp, 1 + sizeof...(_Args)>;
366*0b57cec5SDimitry Andric#endif
367*0b57cec5SDimitry Andric
368*0b57cec5SDimitry Andrictemplate <class _Tp, size_t _Size>
369*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
370*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
371*0b57cec5SDimitry Andricoperator==(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
372*0b57cec5SDimitry Andric{
373*0b57cec5SDimitry Andric    return _VSTD::equal(__x.begin(), __x.end(), __y.begin());
374*0b57cec5SDimitry Andric}
375*0b57cec5SDimitry Andric
376*0b57cec5SDimitry Andrictemplate <class _Tp, size_t _Size>
377*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
378*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
379*0b57cec5SDimitry Andricoperator!=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
380*0b57cec5SDimitry Andric{
381*0b57cec5SDimitry Andric    return !(__x == __y);
382*0b57cec5SDimitry Andric}
383*0b57cec5SDimitry Andric
384*0b57cec5SDimitry Andrictemplate <class _Tp, size_t _Size>
385*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
386*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
387*0b57cec5SDimitry Andricoperator<(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
388*0b57cec5SDimitry Andric{
389*0b57cec5SDimitry Andric    return _VSTD::lexicographical_compare(__x.begin(), __x.end(),
390*0b57cec5SDimitry Andric                                          __y.begin(), __y.end());
391*0b57cec5SDimitry Andric}
392*0b57cec5SDimitry Andric
393*0b57cec5SDimitry Andrictemplate <class _Tp, size_t _Size>
394*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
395*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
396*0b57cec5SDimitry Andricoperator>(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
397*0b57cec5SDimitry Andric{
398*0b57cec5SDimitry Andric    return __y < __x;
399*0b57cec5SDimitry Andric}
400*0b57cec5SDimitry Andric
401*0b57cec5SDimitry Andrictemplate <class _Tp, size_t _Size>
402*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
403*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
404*0b57cec5SDimitry Andricoperator<=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
405*0b57cec5SDimitry Andric{
406*0b57cec5SDimitry Andric    return !(__y < __x);
407*0b57cec5SDimitry Andric}
408*0b57cec5SDimitry Andric
409*0b57cec5SDimitry Andrictemplate <class _Tp, size_t _Size>
410*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
411*0b57cec5SDimitry Andric_LIBCPP_CONSTEXPR_AFTER_CXX17 bool
412*0b57cec5SDimitry Andricoperator>=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
413*0b57cec5SDimitry Andric{
414*0b57cec5SDimitry Andric    return !(__x < __y);
415*0b57cec5SDimitry Andric}
416*0b57cec5SDimitry Andric
417*0b57cec5SDimitry Andrictemplate <class _Tp, size_t _Size>
418*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
419*0b57cec5SDimitry Andrictypename enable_if
420*0b57cec5SDimitry Andric<
421*0b57cec5SDimitry Andric    _Size == 0 ||
422*0b57cec5SDimitry Andric    __is_swappable<_Tp>::value,
423*0b57cec5SDimitry Andric    void
424*0b57cec5SDimitry Andric>::type
425*0b57cec5SDimitry Andricswap(array<_Tp, _Size>& __x, array<_Tp, _Size>& __y)
426*0b57cec5SDimitry Andric                                  _NOEXCEPT_(noexcept(__x.swap(__y)))
427*0b57cec5SDimitry Andric{
428*0b57cec5SDimitry Andric    __x.swap(__y);
429*0b57cec5SDimitry Andric}
430*0b57cec5SDimitry Andric
431*0b57cec5SDimitry Andrictemplate <class _Tp, size_t _Size>
432*0b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS tuple_size<array<_Tp, _Size> >
433*0b57cec5SDimitry Andric    : public integral_constant<size_t, _Size> {};
434*0b57cec5SDimitry Andric
435*0b57cec5SDimitry Andrictemplate <size_t _Ip, class _Tp, size_t _Size>
436*0b57cec5SDimitry Andricstruct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, array<_Tp, _Size> >
437*0b57cec5SDimitry Andric{
438*0b57cec5SDimitry Andric    static_assert(_Ip < _Size, "Index out of bounds in std::tuple_element<> (std::array)");
439*0b57cec5SDimitry Andric    typedef _Tp type;
440*0b57cec5SDimitry Andric};
441*0b57cec5SDimitry Andric
442*0b57cec5SDimitry Andrictemplate <size_t _Ip, class _Tp, size_t _Size>
443*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
444*0b57cec5SDimitry Andric_Tp&
445*0b57cec5SDimitry Andricget(array<_Tp, _Size>& __a) _NOEXCEPT
446*0b57cec5SDimitry Andric{
447*0b57cec5SDimitry Andric    static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array)");
448*0b57cec5SDimitry Andric    return __a.__elems_[_Ip];
449*0b57cec5SDimitry Andric}
450*0b57cec5SDimitry Andric
451*0b57cec5SDimitry Andrictemplate <size_t _Ip, class _Tp, size_t _Size>
452*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
453*0b57cec5SDimitry Andricconst _Tp&
454*0b57cec5SDimitry Andricget(const array<_Tp, _Size>& __a) _NOEXCEPT
455*0b57cec5SDimitry Andric{
456*0b57cec5SDimitry Andric    static_assert(_Ip < _Size, "Index out of bounds in std::get<> (const std::array)");
457*0b57cec5SDimitry Andric    return __a.__elems_[_Ip];
458*0b57cec5SDimitry Andric}
459*0b57cec5SDimitry Andric
460*0b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
461*0b57cec5SDimitry Andric
462*0b57cec5SDimitry Andrictemplate <size_t _Ip, class _Tp, size_t _Size>
463*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
464*0b57cec5SDimitry Andric_Tp&&
465*0b57cec5SDimitry Andricget(array<_Tp, _Size>&& __a) _NOEXCEPT
466*0b57cec5SDimitry Andric{
467*0b57cec5SDimitry Andric    static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array &&)");
468*0b57cec5SDimitry Andric    return _VSTD::move(__a.__elems_[_Ip]);
469*0b57cec5SDimitry Andric}
470*0b57cec5SDimitry Andric
471*0b57cec5SDimitry Andrictemplate <size_t _Ip, class _Tp, size_t _Size>
472*0b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
473*0b57cec5SDimitry Andricconst _Tp&&
474*0b57cec5SDimitry Andricget(const array<_Tp, _Size>&& __a) _NOEXCEPT
475*0b57cec5SDimitry Andric{
476*0b57cec5SDimitry Andric    static_assert(_Ip < _Size, "Index out of bounds in std::get<> (const std::array &&)");
477*0b57cec5SDimitry Andric    return _VSTD::move(__a.__elems_[_Ip]);
478*0b57cec5SDimitry Andric}
479*0b57cec5SDimitry Andric
480*0b57cec5SDimitry Andric#endif  // !_LIBCPP_CXX03_LANG
481*0b57cec5SDimitry Andric
482*0b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD
483*0b57cec5SDimitry Andric
484*0b57cec5SDimitry Andric#endif  // _LIBCPP_ARRAY
485