/src/llvm-project-18.1.8.build/include/c++/v1/array
Line | Count | Source (jump to first uncovered line) |
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/empty.h> |
135 | | #include <__utility/integer_sequence.h> |
136 | | #include <__utility/move.h> |
137 | | #include <__utility/unreachable.h> |
138 | | #include <stdexcept> |
139 | | #include <version> |
140 | | |
141 | | // standard-mandated includes |
142 | | |
143 | | // [iterator.range] |
144 | | #include <__iterator/access.h> |
145 | | #include <__iterator/data.h> |
146 | | #include <__iterator/empty.h> |
147 | | #include <__iterator/reverse_access.h> |
148 | | #include <__iterator/size.h> |
149 | | |
150 | | // [array.syn] |
151 | | #include <compare> |
152 | | #include <initializer_list> |
153 | | |
154 | | // [tuple.helper] |
155 | | #include <__tuple/tuple_element.h> |
156 | | #include <__tuple/tuple_size.h> |
157 | | |
158 | | #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) |
159 | | # pragma GCC system_header |
160 | | #endif |
161 | | |
162 | | _LIBCPP_PUSH_MACROS |
163 | | #include <__undef_macros> |
164 | | |
165 | | _LIBCPP_BEGIN_NAMESPACE_STD |
166 | | |
167 | | template <class _Tp, size_t _Size> |
168 | | struct _LIBCPP_TEMPLATE_VIS array { |
169 | | // types: |
170 | | using __self = array; |
171 | | using value_type = _Tp; |
172 | | using reference = value_type&; |
173 | | using const_reference = const value_type&; |
174 | | using iterator = value_type*; |
175 | | using const_iterator = const value_type*; |
176 | | using pointer = value_type*; |
177 | | using const_pointer = const value_type*; |
178 | | using size_type = size_t; |
179 | | using difference_type = ptrdiff_t; |
180 | | using reverse_iterator = std::reverse_iterator<iterator>; |
181 | | using const_reverse_iterator = std::reverse_iterator<const_iterator>; |
182 | | |
183 | | _Tp __elems_[_Size]; |
184 | | |
185 | | // No explicit construct/copy/destroy for aggregate type |
186 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void fill(const value_type& __u) { |
187 | | std::fill_n(data(), _Size, __u); |
188 | | } |
189 | | |
190 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(array& __a) |
191 | | _NOEXCEPT_(__is_nothrow_swappable<_Tp>::value) { |
192 | | std::swap_ranges(data(), data() + _Size, __a.data()); |
193 | | } |
194 | | |
195 | | // iterators: |
196 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator begin() _NOEXCEPT { return iterator(data()); } |
197 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator begin() const _NOEXCEPT { |
198 | | return const_iterator(data()); |
199 | | } |
200 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator end() _NOEXCEPT { return iterator(data() + _Size); } |
201 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator end() const _NOEXCEPT { |
202 | | return const_iterator(data() + _Size); |
203 | | } |
204 | | |
205 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rbegin() _NOEXCEPT { |
206 | | return reverse_iterator(end()); |
207 | | } |
208 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator rbegin() const _NOEXCEPT { |
209 | | return const_reverse_iterator(end()); |
210 | | } |
211 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rend() _NOEXCEPT { |
212 | | return reverse_iterator(begin()); |
213 | | } |
214 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator rend() const _NOEXCEPT { |
215 | | return const_reverse_iterator(begin()); |
216 | | } |
217 | | |
218 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cbegin() const _NOEXCEPT { return begin(); } |
219 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cend() const _NOEXCEPT { return end(); } |
220 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator crbegin() const _NOEXCEPT { |
221 | | return rbegin(); |
222 | | } |
223 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator crend() const _NOEXCEPT { return rend(); } |
224 | | |
225 | | // capacity: |
226 | 0 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT { return _Size; } |
227 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT { return _Size; } |
228 | | _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT { |
229 | | return _Size == 0; |
230 | | } |
231 | | |
232 | | // element access: |
233 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator[](size_type __n) _NOEXCEPT { |
234 | | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < _Size, "out-of-bounds access in std::array<T, N>"); |
235 | | return __elems_[__n]; |
236 | | } |
237 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference operator[](size_type __n) const _NOEXCEPT { |
238 | | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < _Size, "out-of-bounds access in std::array<T, N>"); |
239 | | return __elems_[__n]; |
240 | | } |
241 | | |
242 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference at(size_type __n) { |
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 | | if (__n >= _Size) |
250 | | __throw_out_of_range("array::at"); |
251 | | return __elems_[__n]; |
252 | | } |
253 | | |
254 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference front() _NOEXCEPT { return (*this)[0]; } |
255 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference front() const _NOEXCEPT { return (*this)[0]; } |
256 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference back() _NOEXCEPT { return (*this)[_Size - 1]; } |
257 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference back() const _NOEXCEPT { |
258 | | return (*this)[_Size - 1]; |
259 | | } |
260 | | |
261 | 0 | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 value_type* data() _NOEXCEPT { return __elems_; } |
262 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const value_type* data() const _NOEXCEPT { return __elems_; } |
263 | | }; |
264 | | |
265 | | template <class _Tp> |
266 | | struct _LIBCPP_TEMPLATE_VIS array<_Tp, 0> { |
267 | | // types: |
268 | | typedef array __self; |
269 | | typedef _Tp value_type; |
270 | | typedef value_type& reference; |
271 | | typedef const value_type& const_reference; |
272 | | typedef value_type* iterator; |
273 | | typedef const value_type* const_iterator; |
274 | | typedef value_type* pointer; |
275 | | typedef const value_type* const_pointer; |
276 | | typedef size_t size_type; |
277 | | typedef ptrdiff_t difference_type; |
278 | | typedef std::reverse_iterator<iterator> reverse_iterator; |
279 | | typedef std::reverse_iterator<const_iterator> const_reverse_iterator; |
280 | | |
281 | | typedef __conditional_t<is_const<_Tp>::value, const __empty, __empty> _EmptyType; |
282 | | |
283 | | struct _ArrayInStructT { |
284 | | _Tp __data_[1]; |
285 | | }; |
286 | | _ALIGNAS_TYPE(_ArrayInStructT) _EmptyType __elems_[sizeof(_ArrayInStructT)]; |
287 | | |
288 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 value_type* data() _NOEXCEPT { return nullptr; } |
289 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const value_type* data() const _NOEXCEPT { return nullptr; } |
290 | | |
291 | | // No explicit construct/copy/destroy for aggregate type |
292 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void fill(const value_type&) { |
293 | | static_assert(!is_const<_Tp>::value, "cannot fill zero-sized array of type 'const T'"); |
294 | | } |
295 | | |
296 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(array&) _NOEXCEPT { |
297 | | static_assert(!is_const<_Tp>::value, "cannot swap zero-sized array of type 'const T'"); |
298 | | } |
299 | | |
300 | | // iterators: |
301 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator begin() _NOEXCEPT { return iterator(data()); } |
302 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator begin() const _NOEXCEPT { |
303 | | return const_iterator(data()); |
304 | | } |
305 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 iterator end() _NOEXCEPT { return iterator(data()); } |
306 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator end() const _NOEXCEPT { |
307 | | return const_iterator(data()); |
308 | | } |
309 | | |
310 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rbegin() _NOEXCEPT { |
311 | | return reverse_iterator(end()); |
312 | | } |
313 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator rbegin() const _NOEXCEPT { |
314 | | return const_reverse_iterator(end()); |
315 | | } |
316 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reverse_iterator rend() _NOEXCEPT { |
317 | | return reverse_iterator(begin()); |
318 | | } |
319 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator rend() const _NOEXCEPT { |
320 | | return const_reverse_iterator(begin()); |
321 | | } |
322 | | |
323 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cbegin() const _NOEXCEPT { return begin(); } |
324 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_iterator cend() const _NOEXCEPT { return end(); } |
325 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator crbegin() const _NOEXCEPT { |
326 | | return rbegin(); |
327 | | } |
328 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 const_reverse_iterator crend() const _NOEXCEPT { return rend(); } |
329 | | |
330 | | // capacity: |
331 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type size() const _NOEXCEPT { return 0; } |
332 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR size_type max_size() const _NOEXCEPT { return 0; } |
333 | | _LIBCPP_NODISCARD_AFTER_CXX17 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool empty() const _NOEXCEPT { return true; } |
334 | | |
335 | | // element access: |
336 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference operator[](size_type) _NOEXCEPT { |
337 | | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::operator[] on a zero-sized array"); |
338 | | __libcpp_unreachable(); |
339 | | } |
340 | | |
341 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference operator[](size_type) const _NOEXCEPT { |
342 | | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::operator[] on a zero-sized array"); |
343 | | __libcpp_unreachable(); |
344 | | } |
345 | | |
346 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference at(size_type) { |
347 | | __throw_out_of_range("array<T, 0>::at"); |
348 | | __libcpp_unreachable(); |
349 | | } |
350 | | |
351 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference at(size_type) const { |
352 | | __throw_out_of_range("array<T, 0>::at"); |
353 | | __libcpp_unreachable(); |
354 | | } |
355 | | |
356 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference front() _NOEXCEPT { |
357 | | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::front() on a zero-sized array"); |
358 | | __libcpp_unreachable(); |
359 | | } |
360 | | |
361 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference front() const _NOEXCEPT { |
362 | | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::front() on a zero-sized array"); |
363 | | __libcpp_unreachable(); |
364 | | } |
365 | | |
366 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 reference back() _NOEXCEPT { |
367 | | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::back() on a zero-sized array"); |
368 | | __libcpp_unreachable(); |
369 | | } |
370 | | |
371 | | _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const_reference back() const _NOEXCEPT { |
372 | | _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(false, "cannot call array<T, 0>::back() on a zero-sized array"); |
373 | | __libcpp_unreachable(); |
374 | | } |
375 | | }; |
376 | | |
377 | | #if _LIBCPP_STD_VER >= 17 |
378 | | template <class _Tp, class... _Args, class = enable_if_t<__all<_IsSame<_Tp, _Args>::value...>::value> > |
379 | | array(_Tp, _Args...) -> array<_Tp, 1 + sizeof...(_Args)>; |
380 | | #endif |
381 | | |
382 | | template <class _Tp, size_t _Size> |
383 | | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 bool |
384 | | operator==(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) { |
385 | | return std::equal(__x.begin(), __x.end(), __y.begin()); |
386 | | } |
387 | | |
388 | | #if _LIBCPP_STD_VER <= 17 |
389 | | |
390 | | template <class _Tp, size_t _Size> |
391 | | inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) { |
392 | | return !(__x == __y); |
393 | | } |
394 | | |
395 | | template <class _Tp, size_t _Size> |
396 | | inline _LIBCPP_HIDE_FROM_ABI bool operator<(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) { |
397 | | return std::lexicographical_compare(__x.begin(), __x.end(), __y.begin(), __y.end()); |
398 | | } |
399 | | |
400 | | template <class _Tp, size_t _Size> |
401 | | inline _LIBCPP_HIDE_FROM_ABI bool operator>(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) { |
402 | | return __y < __x; |
403 | | } |
404 | | |
405 | | template <class _Tp, size_t _Size> |
406 | | inline _LIBCPP_HIDE_FROM_ABI bool operator<=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) { |
407 | | return !(__y < __x); |
408 | | } |
409 | | |
410 | | template <class _Tp, size_t _Size> |
411 | | inline _LIBCPP_HIDE_FROM_ABI bool operator>=(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) { |
412 | | return !(__x < __y); |
413 | | } |
414 | | |
415 | | #else // _LIBCPP_STD_VER <= 17 |
416 | | |
417 | | template <class _Tp, size_t _Size> |
418 | | _LIBCPP_HIDE_FROM_ABI constexpr __synth_three_way_result<_Tp> |
419 | | operator<=>(const array<_Tp, _Size>& __x, const array<_Tp, _Size>& __y) { |
420 | | return std::lexicographical_compare_three_way( |
421 | | __x.begin(), __x.end(), __y.begin(), __y.end(), std::__synth_three_way<_Tp, _Tp>); |
422 | | } |
423 | | |
424 | | #endif // _LIBCPP_STD_VER <= 17 |
425 | | |
426 | | template <class _Tp, size_t _Size, __enable_if_t<_Size == 0 || __is_swappable<_Tp>::value, int> = 0> |
427 | | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void swap(array<_Tp, _Size>& __x, array<_Tp, _Size>& __y) |
428 | | _NOEXCEPT_(noexcept(__x.swap(__y))) { |
429 | | __x.swap(__y); |
430 | | } |
431 | | |
432 | | template <class _Tp, size_t _Size> |
433 | | struct _LIBCPP_TEMPLATE_VIS tuple_size<array<_Tp, _Size> > : public integral_constant<size_t, _Size> {}; |
434 | | |
435 | | template <size_t _Ip, class _Tp, size_t _Size> |
436 | | struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, array<_Tp, _Size> > { |
437 | | static_assert(_Ip < _Size, "Index out of bounds in std::tuple_element<> (std::array)"); |
438 | | typedef _Tp type; |
439 | | }; |
440 | | |
441 | | template <size_t _Ip, class _Tp, size_t _Size> |
442 | | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp& get(array<_Tp, _Size>& __a) _NOEXCEPT { |
443 | | static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array)"); |
444 | | return __a.__elems_[_Ip]; |
445 | | } |
446 | | |
447 | | template <size_t _Ip, class _Tp, size_t _Size> |
448 | | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp& get(const array<_Tp, _Size>& __a) _NOEXCEPT { |
449 | | static_assert(_Ip < _Size, "Index out of bounds in std::get<> (const std::array)"); |
450 | | return __a.__elems_[_Ip]; |
451 | | } |
452 | | |
453 | | template <size_t _Ip, class _Tp, size_t _Size> |
454 | | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp&& get(array<_Tp, _Size>&& __a) _NOEXCEPT { |
455 | | static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array &&)"); |
456 | | return std::move(__a.__elems_[_Ip]); |
457 | | } |
458 | | |
459 | | template <size_t _Ip, class _Tp, size_t _Size> |
460 | | inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Tp&& get(const array<_Tp, _Size>&& __a) _NOEXCEPT { |
461 | | static_assert(_Ip < _Size, "Index out of bounds in std::get<> (const std::array &&)"); |
462 | | return std::move(__a.__elems_[_Ip]); |
463 | | } |
464 | | |
465 | | #if _LIBCPP_STD_VER >= 20 |
466 | | |
467 | | template <typename _Tp, size_t _Size, size_t... _Index> |
468 | | _LIBCPP_HIDE_FROM_ABI constexpr array<remove_cv_t<_Tp>, _Size> |
469 | | __to_array_lvalue_impl(_Tp (&__arr)[_Size], index_sequence<_Index...>) { |
470 | | return {{__arr[_Index]...}}; |
471 | | } |
472 | | |
473 | | template <typename _Tp, size_t _Size, size_t... _Index> |
474 | | _LIBCPP_HIDE_FROM_ABI constexpr array<remove_cv_t<_Tp>, _Size> |
475 | | __to_array_rvalue_impl(_Tp (&&__arr)[_Size], index_sequence<_Index...>) { |
476 | | return {{std::move(__arr[_Index])...}}; |
477 | | } |
478 | | |
479 | | template <typename _Tp, size_t _Size> |
480 | | _LIBCPP_HIDE_FROM_ABI constexpr array<remove_cv_t<_Tp>, _Size> |
481 | | to_array(_Tp (&__arr)[_Size]) noexcept(is_nothrow_constructible_v<_Tp, _Tp&>) { |
482 | | static_assert(!is_array_v<_Tp>, "[array.creation]/1: to_array does not accept multidimensional arrays."); |
483 | | static_assert(is_constructible_v<_Tp, _Tp&>, "[array.creation]/1: to_array requires copy constructible elements."); |
484 | | return std::__to_array_lvalue_impl(__arr, make_index_sequence<_Size>()); |
485 | | } |
486 | | |
487 | | template <typename _Tp, size_t _Size> |
488 | | _LIBCPP_HIDE_FROM_ABI constexpr array<remove_cv_t<_Tp>, _Size> |
489 | | to_array(_Tp (&&__arr)[_Size]) noexcept(is_nothrow_move_constructible_v<_Tp>) { |
490 | | static_assert(!is_array_v<_Tp>, "[array.creation]/4: to_array does not accept multidimensional arrays."); |
491 | | static_assert(is_move_constructible_v<_Tp>, "[array.creation]/4: to_array requires move constructible elements."); |
492 | | return std::__to_array_rvalue_impl(std::move(__arr), make_index_sequence<_Size>()); |
493 | | } |
494 | | |
495 | | #endif // _LIBCPP_STD_VER >= 20 |
496 | | |
497 | | _LIBCPP_END_NAMESPACE_STD |
498 | | |
499 | | _LIBCPP_POP_MACROS |
500 | | |
501 | | #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 |
502 | | # include <algorithm> |
503 | | # include <concepts> |
504 | | # include <cstdlib> |
505 | | # include <iterator> |
506 | | # include <type_traits> |
507 | | # include <utility> |
508 | | #endif |
509 | | |
510 | | #endif // _LIBCPP_ARRAY |