1 1.1 mrg // <array> -*- C++ -*- 2 1.1 mrg 3 1.12 mrg // Copyright (C) 2007-2022 Free Software Foundation, Inc. 4 1.1 mrg // 5 1.1 mrg // This file is part of the GNU ISO C++ Library. This library is free 6 1.1 mrg // software; you can redistribute it and/or modify it under the 7 1.1 mrg // terms of the GNU General Public License as published by the 8 1.1 mrg // Free Software Foundation; either version 3, or (at your option) 9 1.1 mrg // any later version. 10 1.1 mrg 11 1.1 mrg // This library is distributed in the hope that it will be useful, 12 1.1 mrg // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 1.1 mrg // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 1.1 mrg // GNU General Public License for more details. 15 1.1 mrg 16 1.1 mrg // Under Section 7 of GPL version 3, you are granted additional 17 1.1 mrg // permissions described in the GCC Runtime Library Exception, version 18 1.1 mrg // 3.1, as published by the Free Software Foundation. 19 1.1 mrg 20 1.1 mrg // You should have received a copy of the GNU General Public License and 21 1.1 mrg // a copy of the GCC Runtime Library Exception along with this program; 22 1.1 mrg // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 1.1 mrg // <http://www.gnu.org/licenses/>. 24 1.1 mrg 25 1.1 mrg /** @file include/array 26 1.1 mrg * This is a Standard C++ Library header. 27 1.1 mrg */ 28 1.1 mrg 29 1.1 mrg #ifndef _GLIBCXX_ARRAY 30 1.1 mrg #define _GLIBCXX_ARRAY 1 31 1.1 mrg 32 1.1 mrg #pragma GCC system_header 33 1.1 mrg 34 1.3 mrg #if __cplusplus < 201103L 35 1.1 mrg # include <bits/c++0x_warning.h> 36 1.1 mrg #else 37 1.1 mrg 38 1.12 mrg #include <compare> 39 1.12 mrg #include <initializer_list> 40 1.12 mrg 41 1.12 mrg #include <type_traits> 42 1.11 mrg #include <bits/functexcept.h> 43 1.3 mrg #include <bits/stl_algobase.h> 44 1.12 mrg #include <bits/range_access.h> // std::begin, std::end etc. 45 1.12 mrg #include <bits/utility.h> // std::index_sequence, std::tuple_size 46 1.12 mrg #include <debug/assertions.h> 47 1.3 mrg 48 1.3 mrg namespace std _GLIBCXX_VISIBILITY(default) 49 1.3 mrg { 50 1.12 mrg _GLIBCXX_BEGIN_NAMESPACE_VERSION 51 1.3 mrg 52 1.3 mrg template<typename _Tp, std::size_t _Nm> 53 1.3 mrg struct __array_traits 54 1.3 mrg { 55 1.3 mrg typedef _Tp _Type[_Nm]; 56 1.8 mrg typedef __is_swappable<_Tp> _Is_swappable; 57 1.8 mrg typedef __is_nothrow_swappable<_Tp> _Is_nothrow_swappable; 58 1.3 mrg 59 1.3 mrg static constexpr _Tp& 60 1.3 mrg _S_ref(const _Type& __t, std::size_t __n) noexcept 61 1.3 mrg { return const_cast<_Tp&>(__t[__n]); } 62 1.5 mrg 63 1.5 mrg static constexpr _Tp* 64 1.5 mrg _S_ptr(const _Type& __t) noexcept 65 1.5 mrg { return const_cast<_Tp*>(__t); } 66 1.3 mrg }; 67 1.3 mrg 68 1.3 mrg template<typename _Tp> 69 1.3 mrg struct __array_traits<_Tp, 0> 70 1.3 mrg { 71 1.3 mrg struct _Type { }; 72 1.8 mrg typedef true_type _Is_swappable; 73 1.8 mrg typedef true_type _Is_nothrow_swappable; 74 1.3 mrg 75 1.3 mrg static constexpr _Tp& 76 1.3 mrg _S_ref(const _Type&, std::size_t) noexcept 77 1.3 mrg { return *static_cast<_Tp*>(nullptr); } 78 1.5 mrg 79 1.5 mrg static constexpr _Tp* 80 1.5 mrg _S_ptr(const _Type&) noexcept 81 1.5 mrg { return nullptr; } 82 1.3 mrg }; 83 1.3 mrg 84 1.3 mrg /** 85 1.3 mrg * @brief A standard container for storing a fixed size sequence of elements. 86 1.3 mrg * 87 1.3 mrg * @ingroup sequences 88 1.3 mrg * 89 1.3 mrg * Meets the requirements of a <a href="tables.html#65">container</a>, a 90 1.3 mrg * <a href="tables.html#66">reversible container</a>, and a 91 1.3 mrg * <a href="tables.html#67">sequence</a>. 92 1.3 mrg * 93 1.3 mrg * Sets support random access iterators. 94 1.3 mrg * 95 1.3 mrg * @tparam Tp Type of element. Required to be a complete type. 96 1.11 mrg * @tparam Nm Number of elements. 97 1.3 mrg */ 98 1.3 mrg template<typename _Tp, std::size_t _Nm> 99 1.3 mrg struct array 100 1.3 mrg { 101 1.3 mrg typedef _Tp value_type; 102 1.3 mrg typedef value_type* pointer; 103 1.3 mrg typedef const value_type* const_pointer; 104 1.3 mrg typedef value_type& reference; 105 1.3 mrg typedef const value_type& const_reference; 106 1.3 mrg typedef value_type* iterator; 107 1.3 mrg typedef const value_type* const_iterator; 108 1.3 mrg typedef std::size_t size_type; 109 1.3 mrg typedef std::ptrdiff_t difference_type; 110 1.3 mrg typedef std::reverse_iterator<iterator> reverse_iterator; 111 1.3 mrg typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 112 1.3 mrg 113 1.3 mrg // Support for zero-sized arrays mandatory. 114 1.12 mrg typedef __array_traits<_Tp, _Nm> _AT_Type; 115 1.3 mrg typename _AT_Type::_Type _M_elems; 116 1.3 mrg 117 1.3 mrg // No explicit construct/copy/destroy for aggregate type. 118 1.3 mrg 119 1.3 mrg // DR 776. 120 1.11 mrg _GLIBCXX20_CONSTEXPR void 121 1.3 mrg fill(const value_type& __u) 122 1.3 mrg { std::fill_n(begin(), size(), __u); } 123 1.3 mrg 124 1.11 mrg _GLIBCXX20_CONSTEXPR void 125 1.3 mrg swap(array& __other) 126 1.8 mrg noexcept(_AT_Type::_Is_nothrow_swappable::value) 127 1.3 mrg { std::swap_ranges(begin(), end(), __other.begin()); } 128 1.3 mrg 129 1.3 mrg // Iterators. 130 1.12 mrg [[__gnu__::__const__, __nodiscard__]] 131 1.8 mrg _GLIBCXX17_CONSTEXPR iterator 132 1.3 mrg begin() noexcept 133 1.3 mrg { return iterator(data()); } 134 1.3 mrg 135 1.12 mrg [[__nodiscard__]] 136 1.8 mrg _GLIBCXX17_CONSTEXPR const_iterator 137 1.3 mrg begin() const noexcept 138 1.3 mrg { return const_iterator(data()); } 139 1.3 mrg 140 1.12 mrg [[__gnu__::__const__, __nodiscard__]] 141 1.8 mrg _GLIBCXX17_CONSTEXPR iterator 142 1.3 mrg end() noexcept 143 1.3 mrg { return iterator(data() + _Nm); } 144 1.3 mrg 145 1.12 mrg [[__nodiscard__]] 146 1.8 mrg _GLIBCXX17_CONSTEXPR const_iterator 147 1.3 mrg end() const noexcept 148 1.3 mrg { return const_iterator(data() + _Nm); } 149 1.3 mrg 150 1.12 mrg [[__gnu__::__const__, __nodiscard__]] 151 1.8 mrg _GLIBCXX17_CONSTEXPR reverse_iterator 152 1.3 mrg rbegin() noexcept 153 1.3 mrg { return reverse_iterator(end()); } 154 1.3 mrg 155 1.12 mrg [[__nodiscard__]] 156 1.8 mrg _GLIBCXX17_CONSTEXPR const_reverse_iterator 157 1.3 mrg rbegin() const noexcept 158 1.3 mrg { return const_reverse_iterator(end()); } 159 1.3 mrg 160 1.12 mrg [[__gnu__::__const__, __nodiscard__]] 161 1.8 mrg _GLIBCXX17_CONSTEXPR reverse_iterator 162 1.3 mrg rend() noexcept 163 1.3 mrg { return reverse_iterator(begin()); } 164 1.3 mrg 165 1.12 mrg [[__nodiscard__]] 166 1.8 mrg _GLIBCXX17_CONSTEXPR const_reverse_iterator 167 1.3 mrg rend() const noexcept 168 1.3 mrg { return const_reverse_iterator(begin()); } 169 1.3 mrg 170 1.12 mrg [[__nodiscard__]] 171 1.8 mrg _GLIBCXX17_CONSTEXPR const_iterator 172 1.3 mrg cbegin() const noexcept 173 1.3 mrg { return const_iterator(data()); } 174 1.3 mrg 175 1.12 mrg [[__nodiscard__]] 176 1.8 mrg _GLIBCXX17_CONSTEXPR const_iterator 177 1.3 mrg cend() const noexcept 178 1.3 mrg { return const_iterator(data() + _Nm); } 179 1.3 mrg 180 1.12 mrg [[__nodiscard__]] 181 1.8 mrg _GLIBCXX17_CONSTEXPR const_reverse_iterator 182 1.3 mrg crbegin() const noexcept 183 1.3 mrg { return const_reverse_iterator(end()); } 184 1.3 mrg 185 1.12 mrg [[__nodiscard__]] 186 1.8 mrg _GLIBCXX17_CONSTEXPR const_reverse_iterator 187 1.3 mrg crend() const noexcept 188 1.3 mrg { return const_reverse_iterator(begin()); } 189 1.3 mrg 190 1.3 mrg // Capacity. 191 1.12 mrg [[__gnu__::__const__, __nodiscard__]] 192 1.8 mrg constexpr size_type 193 1.3 mrg size() const noexcept { return _Nm; } 194 1.3 mrg 195 1.12 mrg [[__gnu__::__const__, __nodiscard__]] 196 1.8 mrg constexpr size_type 197 1.3 mrg max_size() const noexcept { return _Nm; } 198 1.3 mrg 199 1.12 mrg [[__gnu__::__const__, __nodiscard__]] 200 1.12 mrg constexpr bool 201 1.3 mrg empty() const noexcept { return size() == 0; } 202 1.3 mrg 203 1.3 mrg // Element access. 204 1.12 mrg [[__nodiscard__]] 205 1.8 mrg _GLIBCXX17_CONSTEXPR reference 206 1.5 mrg operator[](size_type __n) noexcept 207 1.12 mrg { 208 1.12 mrg __glibcxx_requires_subscript(__n); 209 1.12 mrg return _AT_Type::_S_ref(_M_elems, __n); 210 1.12 mrg } 211 1.3 mrg 212 1.12 mrg [[__nodiscard__]] 213 1.3 mrg constexpr const_reference 214 1.3 mrg operator[](size_type __n) const noexcept 215 1.12 mrg { 216 1.12 mrg #if __cplusplus >= 201402L 217 1.12 mrg __glibcxx_requires_subscript(__n); 218 1.12 mrg #endif 219 1.12 mrg return _AT_Type::_S_ref(_M_elems, __n); 220 1.12 mrg } 221 1.3 mrg 222 1.8 mrg _GLIBCXX17_CONSTEXPR reference 223 1.3 mrg at(size_type __n) 224 1.3 mrg { 225 1.3 mrg if (__n >= _Nm) 226 1.5 mrg std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) " 227 1.5 mrg ">= _Nm (which is %zu)"), 228 1.5 mrg __n, _Nm); 229 1.3 mrg return _AT_Type::_S_ref(_M_elems, __n); 230 1.3 mrg } 231 1.3 mrg 232 1.3 mrg constexpr const_reference 233 1.3 mrg at(size_type __n) const 234 1.3 mrg { 235 1.3 mrg // Result of conditional expression must be an lvalue so use 236 1.3 mrg // boolean ? lvalue : (throw-expr, lvalue) 237 1.3 mrg return __n < _Nm ? _AT_Type::_S_ref(_M_elems, __n) 238 1.5 mrg : (std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) " 239 1.5 mrg ">= _Nm (which is %zu)"), 240 1.5 mrg __n, _Nm), 241 1.3 mrg _AT_Type::_S_ref(_M_elems, 0)); 242 1.3 mrg } 243 1.3 mrg 244 1.12 mrg [[__nodiscard__]] 245 1.8 mrg _GLIBCXX17_CONSTEXPR reference 246 1.5 mrg front() noexcept 247 1.12 mrg { 248 1.12 mrg __glibcxx_requires_nonempty(); 249 1.12 mrg return *begin(); 250 1.12 mrg } 251 1.3 mrg 252 1.12 mrg [[__nodiscard__]] 253 1.8 mrg constexpr const_reference 254 1.5 mrg front() const noexcept 255 1.12 mrg { 256 1.12 mrg #if __cplusplus >= 201402L 257 1.12 mrg __glibcxx_requires_nonempty(); 258 1.12 mrg #endif 259 1.12 mrg return _AT_Type::_S_ref(_M_elems, 0); 260 1.12 mrg } 261 1.3 mrg 262 1.12 mrg [[__nodiscard__]] 263 1.8 mrg _GLIBCXX17_CONSTEXPR reference 264 1.5 mrg back() noexcept 265 1.12 mrg { 266 1.12 mrg __glibcxx_requires_nonempty(); 267 1.12 mrg return _Nm ? *(end() - 1) : *end(); 268 1.12 mrg } 269 1.3 mrg 270 1.12 mrg [[__nodiscard__]] 271 1.8 mrg constexpr const_reference 272 1.5 mrg back() const noexcept 273 1.8 mrg { 274 1.12 mrg #if __cplusplus >= 201402L 275 1.12 mrg __glibcxx_requires_nonempty(); 276 1.12 mrg #endif 277 1.8 mrg return _Nm ? _AT_Type::_S_ref(_M_elems, _Nm - 1) 278 1.3 mrg : _AT_Type::_S_ref(_M_elems, 0); 279 1.3 mrg } 280 1.3 mrg 281 1.12 mrg [[__gnu__::__const__, __nodiscard__]] 282 1.8 mrg _GLIBCXX17_CONSTEXPR pointer 283 1.3 mrg data() noexcept 284 1.5 mrg { return _AT_Type::_S_ptr(_M_elems); } 285 1.3 mrg 286 1.12 mrg [[__nodiscard__]] 287 1.8 mrg _GLIBCXX17_CONSTEXPR const_pointer 288 1.3 mrg data() const noexcept 289 1.5 mrg { return _AT_Type::_S_ptr(_M_elems); } 290 1.3 mrg }; 291 1.3 mrg 292 1.8 mrg #if __cpp_deduction_guides >= 201606 293 1.8 mrg template<typename _Tp, typename... _Up> 294 1.8 mrg array(_Tp, _Up...) 295 1.8 mrg -> array<enable_if_t<(is_same_v<_Tp, _Up> && ...), _Tp>, 296 1.8 mrg 1 + sizeof...(_Up)>; 297 1.8 mrg #endif 298 1.8 mrg 299 1.3 mrg // Array comparisons. 300 1.3 mrg template<typename _Tp, std::size_t _Nm> 301 1.12 mrg [[__nodiscard__]] 302 1.11 mrg _GLIBCXX20_CONSTEXPR 303 1.8 mrg inline bool 304 1.3 mrg operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 305 1.12 mrg { return std::__equal_aux1(__one.begin(), __one.end(), __two.begin()); } 306 1.3 mrg 307 1.11 mrg #if __cpp_lib_three_way_comparison && __cpp_lib_concepts 308 1.11 mrg template<typename _Tp, size_t _Nm> 309 1.12 mrg [[nodiscard]] 310 1.11 mrg constexpr __detail::__synth3way_t<_Tp> 311 1.11 mrg operator<=>(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b) 312 1.11 mrg { 313 1.11 mrg if constexpr (_Nm && __is_memcmp_ordered<_Tp>::__value) 314 1.12 mrg if (!std::__is_constant_evaluated()) 315 1.11 mrg { 316 1.11 mrg constexpr size_t __n = _Nm * sizeof(_Tp); 317 1.11 mrg return __builtin_memcmp(__a.data(), __b.data(), __n) <=> 0; 318 1.11 mrg } 319 1.11 mrg 320 1.11 mrg for (size_t __i = 0; __i < _Nm; ++__i) 321 1.11 mrg { 322 1.11 mrg auto __c = __detail::__synth3way(__a[__i], __b[__i]); 323 1.11 mrg if (__c != 0) 324 1.11 mrg return __c; 325 1.11 mrg } 326 1.11 mrg return strong_ordering::equal; 327 1.11 mrg } 328 1.11 mrg #else 329 1.3 mrg template<typename _Tp, std::size_t _Nm> 330 1.12 mrg [[__nodiscard__]] 331 1.11 mrg _GLIBCXX20_CONSTEXPR 332 1.3 mrg inline bool 333 1.3 mrg operator!=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 334 1.3 mrg { return !(__one == __two); } 335 1.3 mrg 336 1.3 mrg template<typename _Tp, std::size_t _Nm> 337 1.12 mrg [[__nodiscard__]] 338 1.11 mrg _GLIBCXX20_CONSTEXPR 339 1.3 mrg inline bool 340 1.3 mrg operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b) 341 1.8 mrg { 342 1.3 mrg return std::lexicographical_compare(__a.begin(), __a.end(), 343 1.8 mrg __b.begin(), __b.end()); 344 1.3 mrg } 345 1.3 mrg 346 1.3 mrg template<typename _Tp, std::size_t _Nm> 347 1.12 mrg [[__nodiscard__]] 348 1.11 mrg _GLIBCXX20_CONSTEXPR 349 1.3 mrg inline bool 350 1.3 mrg operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 351 1.3 mrg { return __two < __one; } 352 1.3 mrg 353 1.3 mrg template<typename _Tp, std::size_t _Nm> 354 1.12 mrg [[__nodiscard__]] 355 1.11 mrg _GLIBCXX20_CONSTEXPR 356 1.3 mrg inline bool 357 1.3 mrg operator<=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 358 1.3 mrg { return !(__one > __two); } 359 1.3 mrg 360 1.3 mrg template<typename _Tp, std::size_t _Nm> 361 1.12 mrg [[__nodiscard__]] 362 1.11 mrg _GLIBCXX20_CONSTEXPR 363 1.3 mrg inline bool 364 1.3 mrg operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two) 365 1.3 mrg { return !(__one < __two); } 366 1.11 mrg #endif // three_way_comparison && concepts 367 1.3 mrg 368 1.3 mrg // Specialized algorithms. 369 1.3 mrg template<typename _Tp, std::size_t _Nm> 370 1.11 mrg _GLIBCXX20_CONSTEXPR 371 1.8 mrg inline 372 1.8 mrg #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 373 1.8 mrg // Constrained free swap overload, see p0185r1 374 1.8 mrg typename enable_if< 375 1.12 mrg __array_traits<_Tp, _Nm>::_Is_swappable::value 376 1.8 mrg >::type 377 1.8 mrg #else 378 1.8 mrg void 379 1.8 mrg #endif 380 1.3 mrg swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two) 381 1.3 mrg noexcept(noexcept(__one.swap(__two))) 382 1.3 mrg { __one.swap(__two); } 383 1.3 mrg 384 1.8 mrg #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 385 1.8 mrg template<typename _Tp, std::size_t _Nm> 386 1.8 mrg typename enable_if< 387 1.12 mrg !__array_traits<_Tp, _Nm>::_Is_swappable::value>::type 388 1.8 mrg swap(array<_Tp, _Nm>&, array<_Tp, _Nm>&) = delete; 389 1.8 mrg #endif 390 1.8 mrg 391 1.3 mrg template<std::size_t _Int, typename _Tp, std::size_t _Nm> 392 1.12 mrg [[__nodiscard__]] 393 1.3 mrg constexpr _Tp& 394 1.3 mrg get(array<_Tp, _Nm>& __arr) noexcept 395 1.3 mrg { 396 1.8 mrg static_assert(_Int < _Nm, "array index is within bounds"); 397 1.12 mrg return __array_traits<_Tp, _Nm>::_S_ref(__arr._M_elems, _Int); 398 1.3 mrg } 399 1.3 mrg 400 1.3 mrg template<std::size_t _Int, typename _Tp, std::size_t _Nm> 401 1.12 mrg [[__nodiscard__]] 402 1.3 mrg constexpr _Tp&& 403 1.3 mrg get(array<_Tp, _Nm>&& __arr) noexcept 404 1.3 mrg { 405 1.8 mrg static_assert(_Int < _Nm, "array index is within bounds"); 406 1.12 mrg return std::move(std::get<_Int>(__arr)); 407 1.3 mrg } 408 1.3 mrg 409 1.3 mrg template<std::size_t _Int, typename _Tp, std::size_t _Nm> 410 1.12 mrg [[__nodiscard__]] 411 1.3 mrg constexpr const _Tp& 412 1.3 mrg get(const array<_Tp, _Nm>& __arr) noexcept 413 1.3 mrg { 414 1.8 mrg static_assert(_Int < _Nm, "array index is within bounds"); 415 1.12 mrg return __array_traits<_Tp, _Nm>::_S_ref(__arr._M_elems, _Int); 416 1.3 mrg } 417 1.3 mrg 418 1.9 mrg template<std::size_t _Int, typename _Tp, std::size_t _Nm> 419 1.12 mrg [[__nodiscard__]] 420 1.9 mrg constexpr const _Tp&& 421 1.9 mrg get(const array<_Tp, _Nm>&& __arr) noexcept 422 1.9 mrg { 423 1.9 mrg static_assert(_Int < _Nm, "array index is within bounds"); 424 1.12 mrg return std::move(std::get<_Int>(__arr)); 425 1.9 mrg } 426 1.9 mrg 427 1.12 mrg #if __cplusplus >= 202002L && __cpp_generic_lambdas >= 201707L 428 1.11 mrg #define __cpp_lib_to_array 201907L 429 1.11 mrg template<typename _Tp, size_t _Nm> 430 1.12 mrg [[nodiscard]] 431 1.11 mrg constexpr array<remove_cv_t<_Tp>, _Nm> 432 1.11 mrg to_array(_Tp (&__a)[_Nm]) 433 1.11 mrg noexcept(is_nothrow_constructible_v<_Tp, _Tp&>) 434 1.11 mrg { 435 1.11 mrg static_assert(!is_array_v<_Tp>); 436 1.11 mrg static_assert(is_constructible_v<_Tp, _Tp&>); 437 1.11 mrg if constexpr (is_constructible_v<_Tp, _Tp&>) 438 1.12 mrg { 439 1.12 mrg if constexpr (is_trivial_v<_Tp>) 440 1.12 mrg { 441 1.12 mrg array<remove_cv_t<_Tp>, _Nm> __arr; 442 1.12 mrg if (!__is_constant_evaluated() && _Nm != 0) 443 1.12 mrg __builtin_memcpy((void*)__arr.data(), (void*)__a, sizeof(__a)); 444 1.12 mrg else 445 1.12 mrg for (size_t __i = 0; __i < _Nm; ++__i) 446 1.12 mrg __arr._M_elems[__i] = __a[__i]; 447 1.12 mrg return __arr; 448 1.12 mrg } 449 1.12 mrg else 450 1.12 mrg return [&__a]<size_t... _Idx>(index_sequence<_Idx...>) { 451 1.12 mrg return array<remove_cv_t<_Tp>, _Nm>{{ __a[_Idx]... }}; 452 1.12 mrg }(make_index_sequence<_Nm>{}); 453 1.12 mrg } 454 1.12 mrg else 455 1.12 mrg __builtin_unreachable(); // FIXME: see PR c++/91388 456 1.11 mrg } 457 1.11 mrg 458 1.11 mrg template<typename _Tp, size_t _Nm> 459 1.12 mrg [[nodiscard]] 460 1.11 mrg constexpr array<remove_cv_t<_Tp>, _Nm> 461 1.11 mrg to_array(_Tp (&&__a)[_Nm]) 462 1.11 mrg noexcept(is_nothrow_move_constructible_v<_Tp>) 463 1.11 mrg { 464 1.11 mrg static_assert(!is_array_v<_Tp>); 465 1.11 mrg static_assert(is_move_constructible_v<_Tp>); 466 1.11 mrg if constexpr (is_move_constructible_v<_Tp>) 467 1.12 mrg { 468 1.12 mrg if constexpr (is_trivial_v<_Tp>) 469 1.12 mrg { 470 1.12 mrg array<remove_cv_t<_Tp>, _Nm> __arr; 471 1.12 mrg if (!__is_constant_evaluated() && _Nm != 0) 472 1.12 mrg __builtin_memcpy((void*)__arr.data(), (void*)__a, sizeof(__a)); 473 1.12 mrg else 474 1.12 mrg for (size_t __i = 0; __i < _Nm; ++__i) 475 1.12 mrg __arr._M_elems[__i] = __a[__i]; 476 1.12 mrg return __arr; 477 1.12 mrg } 478 1.12 mrg else 479 1.12 mrg return [&__a]<size_t... _Idx>(index_sequence<_Idx...>) { 480 1.12 mrg return array<remove_cv_t<_Tp>, _Nm>{{ std::move(__a[_Idx])... }}; 481 1.12 mrg }(make_index_sequence<_Nm>{}); 482 1.12 mrg } 483 1.12 mrg else 484 1.12 mrg __builtin_unreachable(); // FIXME: see PR c++/91388 485 1.11 mrg } 486 1.11 mrg #endif // C++20 487 1.11 mrg 488 1.3 mrg // Tuple interface to class template array. 489 1.3 mrg 490 1.5 mrg /// Partial specialization for std::array 491 1.12 mrg template<typename _Tp, size_t _Nm> 492 1.12 mrg struct tuple_size<array<_Tp, _Nm>> 493 1.12 mrg : public integral_constant<size_t, _Nm> { }; 494 1.3 mrg 495 1.5 mrg /// Partial specialization for std::array 496 1.12 mrg template<size_t _Ind, typename _Tp, size_t _Nm> 497 1.12 mrg struct tuple_element<_Ind, array<_Tp, _Nm>> 498 1.3 mrg { 499 1.12 mrg static_assert(_Ind < _Nm, "array index is in range"); 500 1.12 mrg using type = _Tp; 501 1.3 mrg }; 502 1.3 mrg 503 1.12 mrg #if __cplusplus >= 201703L 504 1.12 mrg template<typename _Tp, size_t _Nm> 505 1.12 mrg inline constexpr size_t tuple_size_v<array<_Tp, _Nm>> = _Nm; 506 1.12 mrg 507 1.12 mrg template<typename _Tp, size_t _Nm> 508 1.12 mrg inline constexpr size_t tuple_size_v<const array<_Tp, _Nm>> = _Nm; 509 1.12 mrg #endif 510 1.12 mrg 511 1.12 mrg template<typename _Tp, size_t _Nm> 512 1.12 mrg struct __is_tuple_like_impl<array<_Tp, _Nm>> : true_type 513 1.6 mrg { }; 514 1.6 mrg 515 1.3 mrg _GLIBCXX_END_NAMESPACE_VERSION 516 1.3 mrg } // namespace std 517 1.3 mrg 518 1.3 mrg #endif // C++11 519 1.1 mrg 520 1.1 mrg #endif // _GLIBCXX_ARRAY 521