]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/libcxx/include/array
Merge llvm-project main llvmorg-17-init-19304-gd0b54bb50e51
[FreeBSD/FreeBSD.git] / contrib / llvm-project / libcxx / include / array
1 // -*- C++ -*-
2 //===----------------------------------------------------------------------===//
3 //
4 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 // See https://llvm.org/LICENSE.txt for license information.
6 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //
8 //===----------------------------------------------------------------------===//
9
10 #ifndef _LIBCPP_ARRAY
11 #define _LIBCPP_ARRAY
12
13 /*
14     array synopsis
15
16 namespace std
17 {
18 template <class T, size_t N >
19 struct array
20 {
21     // types:
22     typedef T & reference;
23     typedef const T & const_reference;
24     typedef implementation defined iterator;
25     typedef implementation defined const_iterator;
26     typedef size_t size_type;
27     typedef ptrdiff_t difference_type;
28     typedef T value_type;
29     typedef T* pointer;
30     typedef const T* const_pointer;
31     typedef std::reverse_iterator<iterator> reverse_iterator;
32     typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
33
34     // No explicit construct/copy/destroy for aggregate type
35     void fill(const T& u);                                      // constexpr in C++20
36     void swap(array& a) noexcept(is_nothrow_swappable_v<T>);    // constexpr in C++20
37
38     // iterators:
39     iterator begin() noexcept;                                  // constexpr in C++17
40     const_iterator begin() const noexcept;                      // constexpr in C++17
41     iterator end() noexcept;                                    // constexpr in C++17
42     const_iterator end() const noexcept;                        // constexpr in C++17
43
44     reverse_iterator rbegin() noexcept;                         // constexpr in C++17
45     const_reverse_iterator rbegin() const noexcept;             // constexpr in C++17
46     reverse_iterator rend() noexcept;                           // constexpr in C++17
47     const_reverse_iterator rend() const noexcept;               // constexpr in C++17
48
49     const_iterator cbegin() const noexcept;                     // constexpr in C++17
50     const_iterator cend() const noexcept;                       // constexpr in C++17
51     const_reverse_iterator crbegin() const noexcept;            // constexpr in C++17
52     const_reverse_iterator crend() const noexcept;              // constexpr in C++17
53
54     // capacity:
55     constexpr size_type size() const noexcept;
56     constexpr size_type max_size() const noexcept;
57     constexpr bool empty() const noexcept;
58
59     // element access:
60     reference operator[](size_type n);                          // constexpr in C++17
61     const_reference operator[](size_type n) const;              // constexpr in C++14
62     reference at(size_type n);                                  // constexpr in C++17
63     const_reference at(size_type n) const;                      // constexpr in C++14
64
65     reference front();                                          // constexpr in C++17
66     const_reference front() const;                              // constexpr in C++14
67     reference back();                                           // constexpr in C++17
68     const_reference back() const;                               // constexpr in C++14
69
70     T* data() noexcept;                                         // constexpr in C++17
71     const T* data() const noexcept;                             // constexpr in C++17
72 };
73
74 template <class T, class... U>
75   array(T, U...) -> array<T, 1 + sizeof...(U)>;                 // C++17
76
77 template <class T, size_t N>
78   bool operator==(const array<T,N>& x, const array<T,N>& y);    // constexpr in C++20
79 template <class T, size_t N>
80   bool operator!=(const array<T,N>& x, const array<T,N>& y);    // removed in C++20
81 template <class T, size_t N>
82   bool operator<(const array<T,N>& x, const array<T,N>& y);     // removed in C++20
83 template <class T, size_t N>
84   bool operator>(const array<T,N>& x, const array<T,N>& y);     // removed in C++20
85 template <class T, size_t N>
86   bool operator<=(const array<T,N>& x, const array<T,N>& y);    // removed in C++20
87 template <class T, size_t N>
88   bool operator>=(const array<T,N>& x, const array<T,N>& y);    // removed in C++20
89 template<class T, size_t N>
90   constexpr synth-three-way-result<T>
91     operator<=>(const array<T, N>& x, const array<T, N>& y);    // since C++20
92
93 template <class T, size_t N >
94   void swap(array<T,N>& x, array<T,N>& y) noexcept(noexcept(x.swap(y))); // constexpr in C++20
95
96 template <class T, size_t N>
97   constexpr array<remove_cv_t<T>, N> to_array(T (&a)[N]);  // C++20
98 template <class T, size_t N>
99   constexpr array<remove_cv_t<T>, N> to_array(T (&&a)[N]); // C++20
100
101 template <class T> struct tuple_size;
102 template <size_t I, class T> struct tuple_element;
103 template <class T, size_t N> struct tuple_size<array<T, N>>;
104 template <size_t I, class T, size_t N> struct tuple_element<I, array<T, N>>;
105 template <size_t I, class T, size_t N> T& get(array<T, N>&) noexcept;               // constexpr in C++14
106 template <size_t I, class T, size_t N> const T& get(const array<T, N>&) noexcept;   // constexpr in C++14
107 template <size_t I, class T, size_t N> T&& get(array<T, N>&&) noexcept;             // constexpr in C++14
108 template <size_t I, class T, size_t N> const T&& get(const array<T, N>&&) noexcept; // constexpr in C++14
109
110 }  // std
111
112 */
113
114 #include <__algorithm/equal.h>
115 #include <__algorithm/fill_n.h>
116 #include <__algorithm/lexicographical_compare.h>
117 #include <__algorithm/lexicographical_compare_three_way.h>
118 #include <__algorithm/swap_ranges.h>
119 #include <__assert> // all public C++ headers provide the assertion handler
120 #include <__config>
121 #include <__fwd/array.h>
122 #include <__iterator/reverse_iterator.h>
123 #include <__tuple/sfinae_helpers.h>
124 #include <__type_traits/conditional.h>
125 #include <__type_traits/is_array.h>
126 #include <__type_traits/is_const.h>
127 #include <__type_traits/is_constructible.h>
128 #include <__type_traits/is_move_constructible.h>
129 #include <__type_traits/is_nothrow_constructible.h>
130 #include <__type_traits/is_nothrow_move_constructible.h>
131 #include <__type_traits/is_same.h>
132 #include <__type_traits/is_swappable.h>
133 #include <__type_traits/remove_cv.h>
134 #include <__utility/integer_sequence.h>
135 #include <__utility/move.h>
136 #include <__utility/unreachable.h>
137 #include <stdexcept>
138 #include <version>
139
140 // standard-mandated includes
141
142 // [iterator.range]
143 #include <__iterator/access.h>
144 #include <__iterator/data.h>
145 #include <__iterator/empty.h>
146 #include <__iterator/reverse_access.h>
147 #include <__iterator/size.h>
148
149 // [array.syn]
150 #include <compare>
151 #include <initializer_list>
152
153 // [tuple.helper]
154 #include <__tuple/tuple_element.h>
155 #include <__tuple/tuple_size.h>
156
157 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
158 #  pragma GCC system_header
159 #endif
160
161 _LIBCPP_BEGIN_NAMESPACE_STD
162
163 template <class _Tp, size_t _Size>
164 struct _LIBCPP_TEMPLATE_VIS array
165 {
166     // types:
167     typedef array __self;
168     typedef _Tp                                   value_type;
169     typedef value_type&                           reference;
170     typedef const value_type&                     const_reference;
171     typedef value_type*                           iterator;
172     typedef const value_type*                     const_iterator;
173     typedef value_type*                           pointer;
174     typedef const value_type*                     const_pointer;
175     typedef size_t                                size_type;
176     typedef ptrdiff_t                             difference_type;
177     typedef _VSTD::reverse_iterator<iterator>       reverse_iterator;
178     typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
179
180     _Tp __elems_[_Size];
181
182     // No explicit construct/copy/destroy for aggregate type
183     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
184     void fill(const value_type& __u) {
185         _VSTD::fill_n(data(), _Size, __u);
186     }
187
188     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
189     void swap(array& __a) _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) {
190         _VSTD::swap_ranges(data(), data() + _Size, __a.data());
191     }
192
193     // iterators:
194     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
195     iterator begin() _NOEXCEPT {return iterator(data());}
196     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
197     const_iterator begin() const _NOEXCEPT {return const_iterator(data());}
198     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
199     iterator end() _NOEXCEPT {return iterator(data() + _Size);}
200     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
201     const_iterator end() const _NOEXCEPT {return const_iterator(data() + _Size);}
202
203     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
204     reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());}
205     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
206     const_reverse_iterator rbegin() const _NOEXCEPT {return const_reverse_iterator(end());}
207     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
208     reverse_iterator rend() _NOEXCEPT {return reverse_iterator(begin());}
209     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
210     const_reverse_iterator rend() const _NOEXCEPT {return const_reverse_iterator(begin());}
211
212     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
213     const_iterator cbegin() const _NOEXCEPT {return begin();}
214     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
215     const_iterator cend() const _NOEXCEPT {return end();}
216     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
217     const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();}
218     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
219     const_reverse_iterator crend() const _NOEXCEPT {return rend();}
220
221     // capacity:
222     _LIBCPP_INLINE_VISIBILITY
223     _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT {return _Size;}
224     _LIBCPP_INLINE_VISIBILITY
225     _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT {return _Size;}
226     _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
227     _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT {return _Size == 0;}
228
229     // element access:
230     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
231     reference operator[](size_type __n) _NOEXCEPT {
232         _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < _Size, "out-of-bounds access in std::array<T, N>");
233         return __elems_[__n];
234     }
235     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
236     const_reference operator[](size_type __n) const _NOEXCEPT {
237         _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < _Size, "out-of-bounds access in std::array<T, N>");
238         return __elems_[__n];
239     }
240
241     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference at(size_type __n)
242     {
243         if (__n >= _Size)
244             __throw_out_of_range("array::at");
245         return __elems_[__n];
246     }
247
248     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference at(size_type __n) const
249     {
250         if (__n >= _Size)
251             __throw_out_of_range("array::at");
252         return __elems_[__n];
253     }
254
255     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 reference front()             _NOEXCEPT {return (*this)[0];}
256     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference front() const _NOEXCEPT {return (*this)[0];}
257     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17 reference back()              _NOEXCEPT {return (*this)[_Size - 1];}
258     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference back() const  _NOEXCEPT {return (*this)[_Size - 1];}
259
260     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
261     value_type* data() _NOEXCEPT {return __elems_;}
262     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
263     const value_type* data() const _NOEXCEPT {return __elems_;}
264 };
265
266 template <class _Tp>
267 struct _LIBCPP_TEMPLATE_VIS array<_Tp, 0>
268 {
269     // types:
270     typedef array __self;
271     typedef _Tp                                   value_type;
272     typedef value_type&                           reference;
273     typedef const value_type&                     const_reference;
274     typedef value_type*                           iterator;
275     typedef const value_type*                     const_iterator;
276     typedef value_type*                           pointer;
277     typedef const value_type*                     const_pointer;
278     typedef size_t                                size_type;
279     typedef ptrdiff_t                             difference_type;
280     typedef _VSTD::reverse_iterator<iterator>       reverse_iterator;
281     typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
282
283     typedef __conditional_t<is_const<_Tp>::value, const char, char> _CharType;
284
285     struct  _ArrayInStructT { _Tp __data_[1]; };
286     _ALIGNAS_TYPE(_ArrayInStructT) _CharType __elems_[sizeof(_ArrayInStructT)];
287
288     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
289     value_type* data() _NOEXCEPT {return nullptr;}
290     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
291     const value_type* data() const _NOEXCEPT {return nullptr;}
292
293     // No explicit construct/copy/destroy for aggregate type
294     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
295     void fill(const value_type&) {
296       static_assert(!is_const<_Tp>::value,
297                     "cannot fill zero-sized array of type 'const T'");
298     }
299
300     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
301     void swap(array&) _NOEXCEPT {
302       static_assert(!is_const<_Tp>::value,
303                     "cannot swap zero-sized array of type 'const T'");
304     }
305
306     // iterators:
307     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
308     iterator begin() _NOEXCEPT {return iterator(data());}
309     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
310     const_iterator begin() const _NOEXCEPT {return const_iterator(data());}
311     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
312     iterator end() _NOEXCEPT {return iterator(data());}
313     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
314     const_iterator end() const _NOEXCEPT {return const_iterator(data());}
315
316     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
317     reverse_iterator rbegin() _NOEXCEPT {return reverse_iterator(end());}
318     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
319     const_reverse_iterator rbegin() const _NOEXCEPT {return const_reverse_iterator(end());}
320     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
321     reverse_iterator rend() _NOEXCEPT {return reverse_iterator(begin());}
322     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
323     const_reverse_iterator rend() const _NOEXCEPT {return const_reverse_iterator(begin());}
324
325     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
326     const_iterator cbegin() const _NOEXCEPT {return begin();}
327     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
328     const_iterator cend() const _NOEXCEPT {return end();}
329     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
330     const_reverse_iterator crbegin() const _NOEXCEPT {return rbegin();}
331     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
332     const_reverse_iterator crend() const _NOEXCEPT {return rend();}
333
334     // capacity:
335     _LIBCPP_INLINE_VISIBILITY
336     _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT {return 0; }
337     _LIBCPP_INLINE_VISIBILITY
338     _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT {return 0;}
339     _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_INLINE_VISIBILITY
340     _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT {return true;}
341
342     // element access:
343     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
344     reference operator[](size_type) _NOEXCEPT {
345       _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::operator[] on a zero-sized array");
346       __libcpp_unreachable();
347     }
348
349     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
350     const_reference operator[](size_type) const _NOEXCEPT {
351       _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::operator[] on a zero-sized array");
352       __libcpp_unreachable();
353     }
354
355     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
356     reference at(size_type) {
357       __throw_out_of_range("array<T, 0>::at");
358       __libcpp_unreachable();
359     }
360
361     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
362     const_reference at(size_type) const {
363       __throw_out_of_range("array<T, 0>::at");
364       __libcpp_unreachable();
365     }
366
367     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
368     reference front() _NOEXCEPT {
369       _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::front() on a zero-sized array");
370       __libcpp_unreachable();
371     }
372
373     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
374     const_reference front() const _NOEXCEPT {
375       _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::front() on a zero-sized array");
376       __libcpp_unreachable();
377     }
378
379     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX17
380     reference back() _NOEXCEPT {
381       _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::back() on a zero-sized array");
382       __libcpp_unreachable();
383     }
384
385     _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
386     const_reference back() const _NOEXCEPT {
387       _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::back() on a zero-sized array");
388       __libcpp_unreachable();
389     }
390 };
391
392
393 #if _LIBCPP_STD_VER >= 17
394 template<class _Tp, class... _Args,
395          class = enable_if_t<__all<_IsSame<_Tp, _Args>::value...>::value>
396          >
397 array(_Tp, _Args...)
398   -> array<_Tp, 1 + sizeof...(_Args)>;
399 #endif
400
401 template <class _Tp, size_t _Size>
402 inline _LIBCPP_INLINE_VISIBILITY
403 _LIBCPP_CONSTEXPR_SINCE_CXX20 bool
404 operator==(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y)
405 {
406     return _VSTD::equal(__x.begin(), __x.end(), __y.begin());
407 }
408
409 #if _LIBCPP_STD_VER <= 17
410
411 template <class _Tp, size_t _Size>
412 inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) {
413     return !(__x == __y);
414 }
415
416 template <class _Tp, size_t _Size>
417 inline _LIBCPP_HIDE_FROM_ABI bool operator<(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) {
418     return _VSTD::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end());
419 }
420
421 template <class _Tp, size_t _Size>
422 inline _LIBCPP_HIDE_FROM_ABI bool operator>(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) {
423     return __y < __x;
424 }
425
426 template <class _Tp, size_t _Size>
427 inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) {
428     return !(__y < __x);
429 }
430
431 template <class _Tp, size_t _Size>
432 inline _LIBCPP_HIDE_FROM_ABI bool operator>=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) {
433     return !(__x < __y);
434 }
435
436 #else // _LIBCPP_STD_VER <= 17
437
438 template <class _Tp, size_t _Size>
439 _LIBCPP_HIDE_FROM_ABI constexpr __synth_three_way_result<_Tp>
440 operator<=>(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) {
441     return std::lexicographical_compare_three_way(
442         __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way<_Tp, _Tp>);
443 }
444
445 #endif // _LIBCPP_STD_VER <= 17
446
447 template <class _Tp, size_t _Size>
448 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX20
449 __enable_if_t<_Size == 0 || __is_swappable<_Tp>::value, void>
450 swap(array<_Tp, _Size>& __x, array<_Tp, _Size>& __y)
451                                   _NOEXCEPT_(noexcept(__x.swap(__y)))
452 {
453     __x.swap(__y);
454 }
455
456 template <class _Tp, size_t _Size>
457 struct _LIBCPP_TEMPLATE_VIS tuple_size<array<_Tp, _Size> >
458     : public integral_constant<size_t, _Size> {};
459
460 template <size_t _Ip, class _Tp, size_t _Size>
461 struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, array<_Tp, _Size> >
462 {
463     static_assert(_Ip < _Size, "Index out of bounds in std::tuple_element<> (std::array)");
464     typedef _Tp type;
465 };
466
467 template <size_t _Ip, class _Tp, size_t _Size>
468 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
469 _Tp&
470 get(array<_Tp, _Size>& __a) _NOEXCEPT
471 {
472     static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array)");
473     return __a.__elems_[_Ip];
474 }
475
476 template <size_t _Ip, class _Tp, size_t _Size>
477 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
478 const _Tp&
479 get(const array<_Tp, _Size>& __a) _NOEXCEPT
480 {
481     static_assert(_Ip < _Size, "Index out of bounds in std::get<> (const std::array)");
482     return __a.__elems_[_Ip];
483 }
484
485 template <size_t _Ip, class _Tp, size_t _Size>
486 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
487 _Tp&&
488 get(array<_Tp, _Size>&& __a) _NOEXCEPT
489 {
490     static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array &&)");
491     return _VSTD::move(__a.__elems_[_Ip]);
492 }
493
494 template <size_t _Ip, class _Tp, size_t _Size>
495 inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_SINCE_CXX14
496 const _Tp&&
497 get(const array<_Tp, _Size>&& __a) _NOEXCEPT
498 {
499     static_assert(_Ip < _Size, "Index out of bounds in std::get<> (const std::array &&)");
500     return _VSTD::move(__a.__elems_[_Ip]);
501 }
502
503 #if _LIBCPP_STD_VER >= 20
504
505 template <typename _Tp, size_t _Size, size_t... _Index>
506 _LIBCPP_INLINE_VISIBILITY constexpr array<remove_cv_t<_Tp>, _Size>
507 __to_array_lvalue_impl(_Tp (&__arr)[_Size], index_sequence<_Index...>) {
508   return {{__arr[_Index]...}};
509 }
510
511 template <typename _Tp, size_t _Size, size_t... _Index>
512 _LIBCPP_INLINE_VISIBILITY constexpr array<remove_cv_t<_Tp>, _Size>
513 __to_array_rvalue_impl(_Tp(&&__arr)[_Size], index_sequence<_Index...>) {
514   return {{_VSTD::move(__arr[_Index])...}};
515 }
516
517 template <typename _Tp, size_t _Size>
518 _LIBCPP_INLINE_VISIBILITY constexpr array<remove_cv_t<_Tp>, _Size>
519 to_array(_Tp (&__arr)[_Size]) noexcept(is_nothrow_constructible_v<_Tp, _Tp&>) {
520   static_assert(
521       !is_array_v<_Tp>,
522       "[array.creation]/1: to_array does not accept multidimensional arrays.");
523   static_assert(
524       is_constructible_v<_Tp, _Tp&>,
525       "[array.creation]/1: to_array requires copy constructible elements.");
526   return _VSTD::__to_array_lvalue_impl(__arr, make_index_sequence<_Size>());
527 }
528
529 template <typename _Tp, size_t _Size>
530 _LIBCPP_INLINE_VISIBILITY constexpr array<remove_cv_t<_Tp>, _Size>
531 to_array(_Tp(&&__arr)[_Size]) noexcept(is_nothrow_move_constructible_v<_Tp>) {
532   static_assert(
533       !is_array_v<_Tp>,
534       "[array.creation]/4: to_array does not accept multidimensional arrays.");
535   static_assert(
536       is_move_constructible_v<_Tp>,
537       "[array.creation]/4: to_array requires move constructible elements.");
538   return _VSTD::__to_array_rvalue_impl(_VSTD::move(__arr),
539                                        make_index_sequence<_Size>());
540 }
541
542 #endif // _LIBCPP_STD_VER >= 20
543
544 _LIBCPP_END_NAMESPACE_STD
545
546 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
547 #  include <algorithm>
548 #  include <concepts>
549 #  include <cstdlib>
550 #  include <iterator>
551 #  include <type_traits>
552 #  include <utility>
553 #endif
554
555 #endif // _LIBCPP_ARRAY