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 | using value_type = T; |
23 | using pointer = T*; |
24 | using const_pointer = const T*; |
25 | using reference = T&; |
26 | using const_reference = const T&; |
27 | using size_type = size_t; |
28 | using difference_type = ptrdiff_t; |
29 | using iterator = implementation-defined; |
30 | using const_iterator = implementation-defined; |
31 | using reverse_iterator = std::reverse_iterator<iterator>; |
32 | using const_reverse_iterator = std::reverse_iterator<const_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 | #if __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS) |
115 | # include <__cxx03/array> |
116 | #else |
117 | # include <__algorithm/equal.h> |
118 | # include <__algorithm/fill_n.h> |
119 | # include <__algorithm/lexicographical_compare.h> |
120 | # include <__algorithm/lexicographical_compare_three_way.h> |
121 | # include <__algorithm/swap_ranges.h> |
122 | # include <__assert> |
123 | # include <__config> |
124 | # include <__cstddef/ptrdiff_t.h> |
125 | # include <__fwd/array.h> |
126 | # include <__iterator/reverse_iterator.h> |
127 | # include <__iterator/static_bounded_iter.h> |
128 | # include <__iterator/wrap_iter.h> |
129 | # include <__tuple/sfinae_helpers.h> |
130 | # include <__type_traits/conditional.h> |
131 | # include <__type_traits/conjunction.h> |
132 | # include <__type_traits/enable_if.h> |
133 | # include <__type_traits/is_array.h> |
134 | # include <__type_traits/is_const.h> |
135 | # include <__type_traits/is_constructible.h> |
136 | # include <__type_traits/is_nothrow_constructible.h> |
137 | # include <__type_traits/is_replaceable.h> |
138 | # include <__type_traits/is_same.h> |
139 | # include <__type_traits/is_swappable.h> |
140 | # include <__type_traits/is_trivially_relocatable.h> |
141 | # include <__type_traits/remove_cv.h> |
142 | # include <__utility/empty.h> |
143 | # include <__utility/integer_sequence.h> |
144 | # include <__utility/move.h> |
145 | # include <__utility/unreachable.h> |
146 | # include <stdexcept> |
147 | # include <version> |
148 | |
149 | // standard-mandated includes |
150 | |
151 | // [iterator.range] |
152 | # include <__iterator/access.h> |
153 | # include <__iterator/data.h> |
154 | # include <__iterator/empty.h> |
155 | # include <__iterator/reverse_access.h> |
156 | # include <__iterator/size.h> |
157 | |
158 | // [array.syn] |
159 | # include <compare> |
160 | # include <initializer_list> |
161 | |
162 | // [tuple.helper] |
163 | # include <__tuple/tuple_element.h> |
164 | # include <__tuple/tuple_size.h> |
165 | |
166 | # if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
167 | # pragma GCC system_header |
168 | # endif |
169 | |
170 | _LIBCPP_PUSH_MACROS |
171 | # include <__undef_macros> |
172 | |
173 | _LIBCPP_BEGIN_NAMESPACE_STD |
174 | |
175 | template <class _Tp, size_t _Size> |
176 | struct array { |
177 | using __trivially_relocatable _LIBCPP_NODEBUG = |
178 | __conditional_t<__libcpp_is_trivially_relocatable<_Tp>::value, array, void>; |
179 | using __replaceable _LIBCPP_NODEBUG = __conditional_t<__is_replaceable_v<_Tp>, array, void>; |
180 | |
181 | // types: |
182 | using __self _LIBCPP_NODEBUG = array; |
183 | using value_type = _Tp; |
184 | using reference = value_type&; |
185 | using const_reference = const value_type&; |
186 | using pointer = value_type*; |
187 | using const_pointer = const value_type*; |
188 | # if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY) |
189 | using iterator = __static_bounded_iter<pointer, _Size>; |
190 | using const_iterator = __static_bounded_iter<const_pointer, _Size>; |
191 | # elif defined(_LIBCPP_ABI_USE_WRAP_ITER_IN_STD_ARRAY) |
192 | using iterator = __wrap_iter<pointer>; |
193 | using const_iterator = __wrap_iter<const_pointer>; |
194 | # else |
195 | using iterator = pointer; |
196 | using const_iterator = const_pointer; |
197 | # endif |
198 | using size_type = size_t; |
199 | using difference_type = ptrdiff_t; |
200 | using reverse_iterator = std::reverse_iterator<iterator>; |
201 | using const_reverse_iterator = std::reverse_iterator<const_iterator>; |
202 | |
203 | _Tp __elems_[_Size]; |
204 | |
205 | // No explicit construct/copy/destroy for aggregate type |
206 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void fill(const value_type& __u) { |
207 | std::fill_n(data(), _Size, __u); |
208 | } |
209 | |
210 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(array& __a) _NOEXCEPT_(__is_nothrow_swappable_v<_Tp>) { |
211 | std::swap_ranges(data(), data() + _Size, __a.data()); |
212 | } |
213 | |
214 | // iterators: |
215 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator begin() _NOEXCEPT { |
216 | # if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY) |
217 | return std::__make_static_bounded_iter<_Size>(data(), data()); |
218 | # else |
219 | return iterator(data()); |
220 | # endif |
221 | } |
222 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator begin() const _NOEXCEPT { |
223 | # if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY) |
224 | return std::__make_static_bounded_iter<_Size>(data(), data()); |
225 | # else |
226 | return const_iterator(data()); |
227 | # endif |
228 | } |
229 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator end() _NOEXCEPT { |
230 | # if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY) |
231 | return std::__make_static_bounded_iter<_Size>(data() + _Size, data()); |
232 | # else |
233 | return iterator(data() + _Size); |
234 | # endif |
235 | } |
236 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator end() const _NOEXCEPT { |
237 | # if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY) |
238 | return std::__make_static_bounded_iter<_Size>(data() + _Size, data()); |
239 | # else |
240 | return const_iterator(data() + _Size); |
241 | # endif |
242 | } |
243 | |
244 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rbegin() _NOEXCEPT { |
245 | return reverse_iterator(end()); |
246 | } |
247 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator rbegin() const _NOEXCEPT { |
248 | return const_reverse_iterator(end()); |
249 | } |
250 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rend() _NOEXCEPT { |
251 | return reverse_iterator(begin()); |
252 | } |
253 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator rend() const _NOEXCEPT { |
254 | return const_reverse_iterator(begin()); |
255 | } |
256 | |
257 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cbegin() const _NOEXCEPT { return begin(); } |
258 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cend() const _NOEXCEPT { return end(); } |
259 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator crbegin() const _NOEXCEPT { |
260 | return rbegin(); |
261 | } |
262 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator crend() const _NOEXCEPT { return rend(); } |
263 | |
264 | // capacity: |
265 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT { return _Size; } |
266 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT { return _Size; } |
267 | [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT { return _Size == 0; } |
268 | |
269 | // element access: |
270 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator[](size_type __n) _NOEXCEPT { |
271 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < _Size, "out-of-bounds access in std::array<T, N>" ); |
272 | return __elems_[__n]; |
273 | } |
274 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference operator[](size_type __n) const _NOEXCEPT { |
275 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < _Size, "out-of-bounds access in std::array<T, N>" ); |
276 | return __elems_[__n]; |
277 | } |
278 | |
279 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference at(size_type __n) { |
280 | if (__n >= _Size) |
281 | std::__throw_out_of_range(msg: "array::at" ); |
282 | return __elems_[__n]; |
283 | } |
284 | |
285 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference at(size_type __n) const { |
286 | if (__n >= _Size) |
287 | std::__throw_out_of_range(msg: "array::at" ); |
288 | return __elems_[__n]; |
289 | } |
290 | |
291 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference front() _NOEXCEPT { return (*this)[0]; } |
292 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference front() const _NOEXCEPT { return (*this)[0]; } |
293 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference back() _NOEXCEPT { return (*this)[_Size - 1]; } |
294 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference back() const _NOEXCEPT { |
295 | return (*this)[_Size - 1]; |
296 | } |
297 | |
298 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 value_type* data() _NOEXCEPT { return __elems_; } |
299 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const value_type* data() const _NOEXCEPT { return __elems_; } |
300 | }; |
301 | |
302 | template <class _Tp> |
303 | struct array<_Tp, 0> { |
304 | // types: |
305 | using __self _LIBCPP_NODEBUG = array; |
306 | using value_type = _Tp; |
307 | using reference = value_type&; |
308 | using const_reference = const value_type&; |
309 | using pointer = value_type*; |
310 | using const_pointer = const value_type*; |
311 | # if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY) |
312 | using iterator = __static_bounded_iter<pointer, 0>; |
313 | using const_iterator = __static_bounded_iter<const_pointer, 0>; |
314 | # elif defined(_LIBCPP_ABI_USE_WRAP_ITER_IN_STD_ARRAY) |
315 | using iterator = __wrap_iter<pointer>; |
316 | using const_iterator = __wrap_iter<const_pointer>; |
317 | # else |
318 | using iterator = pointer; |
319 | using const_iterator = const_pointer; |
320 | # endif |
321 | using size_type = size_t; |
322 | using difference_type = ptrdiff_t; |
323 | using reverse_iterator = std::reverse_iterator<iterator>; |
324 | using const_reverse_iterator = std::reverse_iterator<const_iterator>; |
325 | |
326 | using _EmptyType _LIBCPP_NODEBUG = __conditional_t<is_const<_Tp>::value, const __empty, __empty>; |
327 | |
328 | struct _ArrayInStructT { |
329 | _Tp __data_[1]; |
330 | }; |
331 | _ALIGNAS_TYPE(_ArrayInStructT) _EmptyType __elems_[sizeof(_ArrayInStructT)]; |
332 | |
333 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 value_type* data() _NOEXCEPT { return nullptr; } |
334 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const value_type* data() const _NOEXCEPT { return nullptr; } |
335 | |
336 | // No explicit construct/copy/destroy for aggregate type |
337 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void fill(const value_type&) { |
338 | static_assert(!is_const<_Tp>::value, "cannot fill zero-sized array of type 'const T'" ); |
339 | } |
340 | |
341 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(array&) _NOEXCEPT { |
342 | static_assert(!is_const<_Tp>::value, "cannot swap zero-sized array of type 'const T'" ); |
343 | } |
344 | |
345 | // iterators: |
346 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator begin() _NOEXCEPT { |
347 | # if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY) |
348 | return std::__make_static_bounded_iter<0>(data(), data()); |
349 | # else |
350 | return iterator(data()); |
351 | # endif |
352 | } |
353 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator begin() const _NOEXCEPT { |
354 | # if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY) |
355 | return std::__make_static_bounded_iter<0>(data(), data()); |
356 | # else |
357 | return const_iterator(data()); |
358 | # endif |
359 | } |
360 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator end() _NOEXCEPT { |
361 | # if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY) |
362 | return std::__make_static_bounded_iter<0>(data(), data()); |
363 | # else |
364 | return iterator(data()); |
365 | # endif |
366 | } |
367 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator end() const _NOEXCEPT { |
368 | # if defined(_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY) |
369 | return std::__make_static_bounded_iter<0>(data(), data()); |
370 | # else |
371 | return const_iterator(data()); |
372 | # endif |
373 | } |
374 | |
375 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rbegin() _NOEXCEPT { |
376 | return reverse_iterator(end()); |
377 | } |
378 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator rbegin() const _NOEXCEPT { |
379 | return const_reverse_iterator(end()); |
380 | } |
381 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rend() _NOEXCEPT { |
382 | return reverse_iterator(begin()); |
383 | } |
384 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator rend() const _NOEXCEPT { |
385 | return const_reverse_iterator(begin()); |
386 | } |
387 | |
388 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cbegin() const _NOEXCEPT { return begin(); } |
389 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cend() const _NOEXCEPT { return end(); } |
390 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator crbegin() const _NOEXCEPT { |
391 | return rbegin(); |
392 | } |
393 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator crend() const _NOEXCEPT { return rend(); } |
394 | |
395 | // capacity: |
396 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT { return 0; } |
397 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT { return 0; } |
398 | [[__nodiscard__]] _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT { return true; } |
399 | |
400 | // element access: |
401 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator[](size_type) _NOEXCEPT { |
402 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::operator[] on a zero-sized array" ); |
403 | __libcpp_unreachable(); |
404 | } |
405 | |
406 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference operator[](size_type) const _NOEXCEPT { |
407 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::operator[] on a zero-sized array" ); |
408 | __libcpp_unreachable(); |
409 | } |
410 | |
411 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference at(size_type) { |
412 | std::__throw_out_of_range(msg: "array<T, 0>::at" ); |
413 | __libcpp_unreachable(); |
414 | } |
415 | |
416 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference at(size_type) const { |
417 | std::__throw_out_of_range(msg: "array<T, 0>::at" ); |
418 | __libcpp_unreachable(); |
419 | } |
420 | |
421 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference front() _NOEXCEPT { |
422 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::front() on a zero-sized array" ); |
423 | __libcpp_unreachable(); |
424 | } |
425 | |
426 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference front() const _NOEXCEPT { |
427 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::front() on a zero-sized array" ); |
428 | __libcpp_unreachable(); |
429 | } |
430 | |
431 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference back() _NOEXCEPT { |
432 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::back() on a zero-sized array" ); |
433 | __libcpp_unreachable(); |
434 | } |
435 | |
436 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference back() const _NOEXCEPT { |
437 | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::back() on a zero-sized array" ); |
438 | __libcpp_unreachable(); |
439 | } |
440 | }; |
441 | |
442 | # if _LIBCPP_STD_VER >= 17 |
443 | template <class _Tp, class... _Args, class = enable_if_t<__all<_IsSame<_Tp, _Args>::value...>::value> > |
444 | array(_Tp, _Args...) -> array<_Tp, 1 + sizeof...(_Args)>; |
445 | # endif |
446 | |
447 | template <class _Tp, size_t _Size> |
448 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool |
449 | operator==(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) { |
450 | return std::equal(__x.begin(), __x.end(), __y.begin()); |
451 | } |
452 | |
453 | # if _LIBCPP_STD_VER <= 17 |
454 | |
455 | template <class _Tp, size_t _Size> |
456 | inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) { |
457 | return !(__x == __y); |
458 | } |
459 | |
460 | template <class _Tp, size_t _Size> |
461 | inline _LIBCPP_HIDE_FROM_ABI bool operator<(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) { |
462 | return std::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); |
463 | } |
464 | |
465 | template <class _Tp, size_t _Size> |
466 | inline _LIBCPP_HIDE_FROM_ABI bool operator>(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) { |
467 | return __y < __x; |
468 | } |
469 | |
470 | template <class _Tp, size_t _Size> |
471 | inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) { |
472 | return !(__y < __x); |
473 | } |
474 | |
475 | template <class _Tp, size_t _Size> |
476 | inline _LIBCPP_HIDE_FROM_ABI bool operator>=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) { |
477 | return !(__x < __y); |
478 | } |
479 | |
480 | # else // _LIBCPP_STD_VER <= 17 |
481 | |
482 | template <class _Tp, size_t _Size> |
483 | _LIBCPP_HIDE_FROM_ABI constexpr __synth_three_way_result<_Tp> |
484 | operator<=>(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) { |
485 | return std::lexicographical_compare_three_way(__x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way); |
486 | } |
487 | |
488 | # endif // _LIBCPP_STD_VER <= 17 |
489 | |
490 | template <class _Tp, size_t _Size, __enable_if_t<_Size == 0 || __is_swappable_v<_Tp>, int> = 0> |
491 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(array<_Tp, _Size>& __x, array<_Tp, _Size>& __y) |
492 | _NOEXCEPT_(noexcept(__x.swap(__y))) { |
493 | __x.swap(__y); |
494 | } |
495 | |
496 | template <class _Tp, size_t _Size> |
497 | struct tuple_size<array<_Tp, _Size> > : public integral_constant<size_t, _Size> {}; |
498 | |
499 | template <size_t _Ip, class _Tp, size_t _Size> |
500 | struct tuple_element<_Ip, array<_Tp, _Size> > { |
501 | static_assert(_Ip < _Size, "Index out of bounds in std::tuple_element<> (std::array)" ); |
502 | using type _LIBCPP_NODEBUG = _Tp; |
503 | }; |
504 | |
505 | template <size_t _Ip, class _Tp, size_t _Size> |
506 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp& get(array<_Tp, _Size>& __a) _NOEXCEPT { |
507 | static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array)" ); |
508 | return __a.__elems_[_Ip]; |
509 | } |
510 | |
511 | template <size_t _Ip, class _Tp, size_t _Size> |
512 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& get(const array<_Tp, _Size>& __a) _NOEXCEPT { |
513 | static_assert(_Ip < _Size, "Index out of bounds in std::get<> (const std::array)" ); |
514 | return __a.__elems_[_Ip]; |
515 | } |
516 | |
517 | template <size_t _Ip, class _Tp, size_t _Size> |
518 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp&& get(array<_Tp, _Size>&& __a) _NOEXCEPT { |
519 | static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array &&)" ); |
520 | return std::move(__a.__elems_[_Ip]); |
521 | } |
522 | |
523 | template <size_t _Ip, class _Tp, size_t _Size> |
524 | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp&& get(const array<_Tp, _Size>&& __a) _NOEXCEPT { |
525 | static_assert(_Ip < _Size, "Index out of bounds in std::get<> (const std::array &&)" ); |
526 | return std::move(__a.__elems_[_Ip]); |
527 | } |
528 | |
529 | # if _LIBCPP_STD_VER >= 20 |
530 | |
531 | template <typename _Tp, size_t _Size, size_t... _Index> |
532 | _LIBCPP_HIDE_FROM_ABI constexpr array<remove_cv_t<_Tp>, _Size> |
533 | __to_array_lvalue_impl(_Tp (&__arr)[_Size], index_sequence<_Index...>) { |
534 | return {{__arr[_Index]...}}; |
535 | } |
536 | |
537 | template <typename _Tp, size_t _Size, size_t... _Index> |
538 | _LIBCPP_HIDE_FROM_ABI constexpr array<remove_cv_t<_Tp>, _Size> |
539 | __to_array_rvalue_impl(_Tp (&&__arr)[_Size], index_sequence<_Index...>) { |
540 | return {{std::move(__arr[_Index])...}}; |
541 | } |
542 | |
543 | template <typename _Tp, size_t _Size> |
544 | _LIBCPP_HIDE_FROM_ABI constexpr array<remove_cv_t<_Tp>, _Size> |
545 | to_array(_Tp (&__arr)[_Size]) noexcept(is_nothrow_constructible_v<_Tp, _Tp&>) { |
546 | static_assert(!is_array_v<_Tp>, "[array.creation]/1: to_array does not accept multidimensional arrays." ); |
547 | static_assert(is_constructible_v<_Tp, _Tp&>, "[array.creation]/1: to_array requires copy constructible elements." ); |
548 | return std::__to_array_lvalue_impl(__arr, make_index_sequence<_Size>()); |
549 | } |
550 | |
551 | template <typename _Tp, size_t _Size> |
552 | _LIBCPP_HIDE_FROM_ABI constexpr array<remove_cv_t<_Tp>, _Size> |
553 | to_array(_Tp (&&__arr)[_Size]) noexcept(is_nothrow_move_constructible_v<_Tp>) { |
554 | static_assert(!is_array_v<_Tp>, "[array.creation]/4: to_array does not accept multidimensional arrays." ); |
555 | static_assert(is_move_constructible_v<_Tp>, "[array.creation]/4: to_array requires move constructible elements." ); |
556 | return std::__to_array_rvalue_impl(std::move(__arr), make_index_sequence<_Size>()); |
557 | } |
558 | |
559 | # endif // _LIBCPP_STD_VER >= 20 |
560 | |
561 | _LIBCPP_END_NAMESPACE_STD |
562 | |
563 | _LIBCPP_POP_MACROS |
564 | |
565 | # if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
566 | # include <algorithm> |
567 | # include <concepts> |
568 | # include <cstdlib> |
569 | # include <iterator> |
570 | # include <new> |
571 | # include <optional> |
572 | # include <type_traits> |
573 | # include <utility> |
574 | # endif |
575 | #endif // __cplusplus < 201103L && defined(_LIBCPP_USE_FROZEN_CXX03_HEADERS) |
576 | |
577 | #endif // _LIBCPP_ARRAY |
578 | |