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