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