274 KiB
274 KiB
<html lang="en">
<head>
</head>
</html>
LCOV - code coverage report | ||||||||||||||||||||||
![]() | ||||||||||||||||||||||
|
||||||||||||||||||||||
![]() |
Line data Source code 1 : // <tuple> -*- C++ -*- 2 : 3 : // Copyright (C) 2007-2023 Free Software Foundation, Inc. 4 : // 5 : // This file is part of the GNU ISO C++ Library. This library is free 6 : // software; you can redistribute it and/or modify it under the 7 : // terms of the GNU General Public License as published by the 8 : // Free Software Foundation; either version 3, or (at your option) 9 : // any later version. 10 : 11 : // This library is distributed in the hope that it will be useful, 12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 : // GNU General Public License for more details. 15 : 16 : // Under Section 7 of GPL version 3, you are granted additional 17 : // permissions described in the GCC Runtime Library Exception, version 18 : // 3.1, as published by the Free Software Foundation. 19 : 20 : // You should have received a copy of the GNU General Public License and 21 : // a copy of the GCC Runtime Library Exception along with this program; 22 : // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23 : // <http://www.gnu.org/licenses/>. 24 : 25 : /** @file include/tuple 26 : * This is a Standard C++ Library header. 27 : */ 28 : 29 : #ifndef _GLIBCXX_TUPLE 30 : #define _GLIBCXX_TUPLE 1 31 : 32 : #pragma GCC system_header 33 : 34 : #if __cplusplus < 201103L 35 : # include <bits/c++0x_warning.h> 36 : #else 37 : 38 : #include <bits/stl_pair.h> // for std::pair 39 : #include <bits/uses_allocator.h> // for std::allocator_arg_t 40 : #include <bits/utility.h> // for std::tuple_size etc. 41 : #include <bits/invoke.h> // for std::__invoke 42 : #if __cplusplus > 201703L 43 : # include <compare> 44 : # include <bits/ranges_util.h> // for std::ranges::subrange 45 : # define __cpp_lib_constexpr_tuple 201811L 46 : #endif 47 : 48 : namespace std _GLIBCXX_VISIBILITY(default) 49 : { 50 : _GLIBCXX_BEGIN_NAMESPACE_VERSION 51 : 52 : /** 53 : * @addtogroup utilities 54 : * @{ 55 : */ 56 : 57 : template<typename... _Elements> 58 : class tuple; 59 : 60 : template<typename _Tp> 61 : struct __is_empty_non_tuple : is_empty<_Tp> { }; 62 : 63 : // Using EBO for elements that are tuples causes ambiguous base errors. 64 : template<typename _El0, typename... _El> 65 : struct __is_empty_non_tuple<tuple<_El0, _El...>> : false_type { }; 66 : 67 : // Use the Empty Base-class Optimization for empty, non-final types. 68 : template<typename _Tp> 69 : using __empty_not_final 70 : = __conditional_t<__is_final(_Tp), false_type, 71 : __is_empty_non_tuple<_Tp>>; 72 : 73 : template<size_t _Idx, typename _Head, 74 : bool = __empty_not_final<_Head>::value> 75 : struct _Head_base; 76 : 77 : #if __has_cpp_attribute(__no_unique_address__) 78 : template<size_t _Idx, typename _Head> 79 : struct _Head_base<_Idx, _Head, true> 80 : { 81 2051824 : constexpr _Head_base() 82 2051824 : : _M_head_impl() { } 83 : 84 : constexpr _Head_base(const _Head& __h) 85 : : _M_head_impl(__h) { } 86 : 87 : constexpr _Head_base(const _Head_base&) = default; 88 : constexpr _Head_base(_Head_base&&) = default; 89 : 90 : template<typename _UHead> 91 198 : constexpr _Head_base(_UHead&& __h) 92 198 : : _M_head_impl(std::forward<_UHead>(__h)) { } 93 : 94 : _GLIBCXX20_CONSTEXPR 95 : _Head_base(allocator_arg_t, __uses_alloc0) 96 : : _M_head_impl() { } 97 : 98 : template<typename _Alloc> 99 : _GLIBCXX20_CONSTEXPR 100 : _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a) 101 : : _M_head_impl(allocator_arg, *__a._M_a) { } 102 : 103 : template<typename _Alloc> 104 : _GLIBCXX20_CONSTEXPR 105 : _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a) 106 : : _M_head_impl(*__a._M_a) { } 107 : 108 : template<typename _UHead> 109 : _GLIBCXX20_CONSTEXPR 110 : _Head_base(__uses_alloc0, _UHead&& __uhead) 111 : : _M_head_impl(std::forward<_UHead>(__uhead)) { } 112 : 113 : template<typename _Alloc, typename _UHead> 114 : _GLIBCXX20_CONSTEXPR 115 : _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead) 116 : : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) 117 : { } 118 : 119 : template<typename _Alloc, typename _UHead> 120 : _GLIBCXX20_CONSTEXPR 121 : _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead) 122 : : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { } 123 : 124 : static constexpr _Head& 125 43464 : _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; } 126 : 127 : static constexpr const _Head& 128 : _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; } 129 : 130 : [[__no_unique_address__]] _Head _M_head_impl; 131 : }; 132 : #else 133 : template<size_t _Idx, typename _Head> 134 : struct _Head_base<_Idx, _Head, true> 135 : : public _Head 136 : { 137 : constexpr _Head_base() 138 : : _Head() { } 139 : 140 : constexpr _Head_base(const _Head& __h) 141 : : _Head(__h) { } 142 : 143 : constexpr _Head_base(const _Head_base&) = default; 144 : constexpr _Head_base(_Head_base&&) = default; 145 : 146 : template<typename _UHead> 147 : constexpr _Head_base(_UHead&& __h) 148 : : _Head(std::forward<_UHead>(__h)) { } 149 : 150 : _GLIBCXX20_CONSTEXPR 151 : _Head_base(allocator_arg_t, __uses_alloc0) 152 : : _Head() { } 153 : 154 : template<typename _Alloc> 155 : _GLIBCXX20_CONSTEXPR 156 : _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a) 157 : : _Head(allocator_arg, *__a._M_a) { } 158 : 159 : template<typename _Alloc> 160 : _GLIBCXX20_CONSTEXPR 161 : _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a) 162 : : _Head(*__a._M_a) { } 163 : 164 : template<typename _UHead> 165 : _GLIBCXX20_CONSTEXPR 166 : _Head_base(__uses_alloc0, _UHead&& __uhead) 167 : : _Head(std::forward<_UHead>(__uhead)) { } 168 : 169 : template<typename _Alloc, typename _UHead> 170 : _GLIBCXX20_CONSTEXPR 171 : _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead) 172 : : _Head(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { } 173 : 174 : template<typename _Alloc, typename _UHead> 175 : _GLIBCXX20_CONSTEXPR 176 : _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead) 177 : : _Head(std::forward<_UHead>(__uhead), *__a._M_a) { } 178 : 179 : static constexpr _Head& 180 : _M_head(_Head_base& __b) noexcept { return __b; } 181 : 182 : static constexpr const _Head& 183 : _M_head(const _Head_base& __b) noexcept { return __b; } 184 : }; 185 : #endif 186 : 187 : template<size_t _Idx, typename _Head> 188 : struct _Head_base<_Idx, _Head, false> 189 : { 190 2051824 : constexpr _Head_base() 191 2051824 : : _M_head_impl() { } 192 : 193 8758190 : constexpr _Head_base(const _Head& __h) 194 8758190 : : _M_head_impl(__h) { } 195 : 196 : constexpr _Head_base(const _Head_base&) = default; 197 : constexpr _Head_base(_Head_base&&) = default; 198 : 199 : template<typename _UHead> 200 4736306 : constexpr _Head_base(_UHead&& __h) 201 4736306 : : _M_head_impl(std::forward<_UHead>(__h)) { } 202 : 203 : _GLIBCXX20_CONSTEXPR 204 : _Head_base(allocator_arg_t, __uses_alloc0) 205 : : _M_head_impl() { } 206 : 207 : template<typename _Alloc> 208 : _GLIBCXX20_CONSTEXPR 209 : _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a) 210 : : _M_head_impl(allocator_arg, *__a._M_a) { } 211 : 212 : template<typename _Alloc> 213 : _GLIBCXX20_CONSTEXPR 214 : _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a) 215 : : _M_head_impl(*__a._M_a) { } 216 : 217 : template<typename _UHead> 218 : _GLIBCXX20_CONSTEXPR 219 : _Head_base(__uses_alloc0, _UHead&& __uhead) 220 : : _M_head_impl(std::forward<_UHead>(__uhead)) { } 221 : 222 : template<typename _Alloc, typename _UHead> 223 : _GLIBCXX20_CONSTEXPR 224 : _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead) 225 : : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) 226 : { } 227 : 228 : template<typename _Alloc, typename _UHead> 229 : _GLIBCXX20_CONSTEXPR 230 : _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead) 231 : : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { } 232 : 233 : static constexpr _Head& 234 17228284 : _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; } 235 : 236 : static constexpr const _Head& 237 31996304 : _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; } 238 : 239 : _Head _M_head_impl; 240 : }; 241 : 242 : /** 243 : * Contains the actual implementation of the @c tuple template, stored 244 : * as a recursive inheritance hierarchy from the first element (most 245 : * derived class) to the last (least derived class). The @c Idx 246 : * parameter gives the 0-based index of the element stored at this 247 : * point in the hierarchy; we use it to implement a constant-time 248 : * get() operation. 249 : */ 250 : template<size_t _Idx, typename... _Elements> 251 : struct _Tuple_impl; 252 : 253 : /** 254 : * Recursive tuple implementation. Here we store the @c Head element 255 : * and derive from a @c Tuple_impl containing the remaining elements 256 : * (which contains the @c Tail). 257 : */ 258 : template<size_t _Idx, typename _Head, typename... _Tail> 259 : struct _Tuple_impl<_Idx, _Head, _Tail...> 260 : : public _Tuple_impl<_Idx + 1, _Tail...>, 261 : private _Head_base<_Idx, _Head> 262 : { 263 : template<size_t, typename...> friend struct _Tuple_impl; 264 : 265 : typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited; 266 : typedef _Head_base<_Idx, _Head> _Base; 267 : 268 : static constexpr _Head& 269 3736022 : _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } 270 : 271 : static constexpr const _Head& 272 31996304 : _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } 273 : 274 : static constexpr _Inherited& 275 1144 : _M_tail(_Tuple_impl& __t) noexcept { return __t; } 276 : 277 : static constexpr const _Inherited& 278 : _M_tail(const _Tuple_impl& __t) noexcept { return __t; } 279 : 280 2051824 : constexpr _Tuple_impl() 281 2051824 : : _Inherited(), _Base() { } 282 : 283 : explicit constexpr 284 572 : _Tuple_impl(const _Head& __head, const _Tail&... __tail) 285 572 : : _Inherited(__tail...), _Base(__head) 286 572 : { } 287 : 288 : template<typename _UHead, typename... _UTail, 289 : typename = __enable_if_t<sizeof...(_Tail) == sizeof...(_UTail)>> 290 : explicit constexpr 291 1216 : _Tuple_impl(_UHead&& __head, _UTail&&... __tail) 292 : : _Inherited(std::forward<_UTail>(__tail)...), 293 1216 : _Base(std::forward<_UHead>(__head)) 294 1216 : { } 295 : 296 : constexpr _Tuple_impl(const _Tuple_impl&) = default; 297 : 298 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 299 : // 2729. Missing SFINAE on std::pair::operator= 300 : _Tuple_impl& operator=(const _Tuple_impl&) = delete; 301 : 302 1210 : _Tuple_impl(_Tuple_impl&&) = default; 303 : 304 : template<typename... _UElements> 305 : constexpr 306 : _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in) 307 : : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)), 308 : _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) 309 : { } 310 : 311 : template<typename _UHead, typename... _UTails> 312 : constexpr 313 : _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) 314 : : _Inherited(std::move 315 : (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))), 316 : _Base(std::forward<_UHead> 317 : (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) 318 : { } 319 : 320 : #if __cplusplus > 202002L 321 : template<typename... _UElements> 322 : constexpr 323 : _Tuple_impl(_Tuple_impl<_Idx, _UElements...>& __in) 324 : : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)), 325 : _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) 326 : { } 327 : 328 : template<typename _UHead, typename... _UTails> 329 : constexpr 330 : _Tuple_impl(const _Tuple_impl<_Idx, _UHead, _UTails...>&& __in) 331 : : _Inherited(std::move 332 : (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))), 333 : _Base(std::forward<const _UHead> 334 : (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) 335 : { } 336 : #endif // C++23 337 : 338 : template<typename _Alloc> 339 : _GLIBCXX20_CONSTEXPR 340 : _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a) 341 : : _Inherited(__tag, __a), 342 : _Base(__tag, __use_alloc<_Head>(__a)) 343 : { } 344 : 345 : template<typename _Alloc> 346 : _GLIBCXX20_CONSTEXPR 347 : _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 348 : const _Head& __head, const _Tail&... __tail) 349 : : _Inherited(__tag, __a, __tail...), 350 : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) 351 : { } 352 : 353 : template<typename _Alloc, typename _UHead, typename... _UTail, 354 : typename = __enable_if_t<sizeof...(_Tail) == sizeof...(_UTail)>> 355 : _GLIBCXX20_CONSTEXPR 356 : _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 357 : _UHead&& __head, _UTail&&... __tail) 358 : : _Inherited(__tag, __a, std::forward<_UTail>(__tail)...), 359 : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), 360 : std::forward<_UHead>(__head)) 361 : { } 362 : 363 : template<typename _Alloc> 364 : _GLIBCXX20_CONSTEXPR 365 : _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 366 : const _Tuple_impl& __in) 367 : : _Inherited(__tag, __a, _M_tail(__in)), 368 : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) 369 : { } 370 : 371 : template<typename _Alloc> 372 : _GLIBCXX20_CONSTEXPR 373 : _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 374 : _Tuple_impl&& __in) 375 : : _Inherited(__tag, __a, std::move(_M_tail(__in))), 376 : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), 377 : std::forward<_Head>(_M_head(__in))) 378 : { } 379 : 380 : template<typename _Alloc, typename _UHead, typename... _UTails> 381 : _GLIBCXX20_CONSTEXPR 382 : _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 383 : const _Tuple_impl<_Idx, _UHead, _UTails...>& __in) 384 : : _Inherited(__tag, __a, 385 : _Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)), 386 : _Base(__use_alloc<_Head, _Alloc, const _UHead&>(__a), 387 : _Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)) 388 : { } 389 : 390 : template<typename _Alloc, typename _UHead, typename... _UTails> 391 : _GLIBCXX20_CONSTEXPR 392 : _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 393 : _Tuple_impl<_Idx, _UHead, _UTails...>&& __in) 394 : : _Inherited(__tag, __a, std::move 395 : (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))), 396 : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), 397 : std::forward<_UHead> 398 : (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) 399 : { } 400 : 401 : #if __cplusplus > 202002L 402 : template<typename _Alloc, typename _UHead, typename... _UTails> 403 : constexpr 404 : _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 405 : _Tuple_impl<_Idx, _UHead, _UTails...>& __in) 406 : : _Inherited(__tag, __a, 407 : _Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)), 408 : _Base(__use_alloc<_Head, _Alloc, _UHead&>(__a), 409 : _Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)) 410 : { } 411 : 412 : template<typename _Alloc, typename _UHead, typename... _UTails> 413 : constexpr 414 : _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 415 : const _Tuple_impl<_Idx, _UHead, _UTails...>&& __in) 416 : : _Inherited(__tag, __a, std::move 417 : (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))), 418 : _Base(__use_alloc<_Head, _Alloc, const _UHead>(__a), 419 : std::forward<const _UHead> 420 : (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) 421 : { } 422 : #endif // C++23 423 : 424 : template<typename... _UElements> 425 : _GLIBCXX20_CONSTEXPR 426 : void 427 : _M_assign(const _Tuple_impl<_Idx, _UElements...>& __in) 428 : { 429 : _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in); 430 : _M_tail(*this)._M_assign( 431 : _Tuple_impl<_Idx, _UElements...>::_M_tail(__in)); 432 : } 433 : 434 : template<typename _UHead, typename... _UTails> 435 : _GLIBCXX20_CONSTEXPR 436 : void 437 572 : _M_assign(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) 438 : { 439 572 : _M_head(*this) = std::forward<_UHead> 440 572 : (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)); 441 1144 : _M_tail(*this)._M_assign( 442 572 : std::move(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))); 443 572 : } 444 : 445 : #if __cplusplus > 202002L 446 : template<typename... _UElements> 447 : constexpr void 448 : _M_assign(const _Tuple_impl<_Idx, _UElements...>& __in) const 449 : { 450 : _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in); 451 : _M_tail(*this)._M_assign( 452 : _Tuple_impl<_Idx, _UElements...>::_M_tail(__in)); 453 : } 454 : 455 : template<typename _UHead, typename... _UTails> 456 : constexpr void 457 : _M_assign(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) const 458 : { 459 : _M_head(*this) = std::forward<_UHead> 460 : (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)); 461 : _M_tail(*this)._M_assign( 462 : std::move(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))); 463 : } 464 : #endif // C++23 465 : 466 : protected: 467 : _GLIBCXX20_CONSTEXPR 468 : void 469 : _M_swap(_Tuple_impl& __in) 470 : { 471 : using std::swap; 472 : swap(_M_head(*this), _M_head(__in)); 473 : _Inherited::_M_swap(_M_tail(__in)); 474 : } 475 : 476 : #if __cplusplus > 202002L 477 : constexpr void 478 : _M_swap(const _Tuple_impl& __in) const 479 : { 480 : using std::swap; 481 : swap(_M_head(*this), _M_head(__in)); 482 : _Inherited::_M_swap(_M_tail(__in)); 483 : } 484 : #endif // C++23 485 : }; 486 : 487 : // Basis case of inheritance recursion. 488 : template<size_t _Idx, typename _Head> 489 : struct _Tuple_impl<_Idx, _Head> 490 : : private _Head_base<_Idx, _Head> 491 : { 492 : template<size_t, typename...> friend struct _Tuple_impl; 493 : 494 : typedef _Head_base<_Idx, _Head> _Base; 495 : 496 : static constexpr _Head& 497 13535726 : _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } 498 : 499 : static constexpr const _Head& 500 0 : _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } 501 : 502 : constexpr 503 2051824 : _Tuple_impl() 504 2051824 : : _Base() { } 505 : 506 : explicit constexpr 507 8757332 : _Tuple_impl(const _Head& __head) 508 8757332 : : _Base(__head) 509 8757332 : { } 510 : 511 : template<typename _UHead> 512 : explicit constexpr 513 4735574 : _Tuple_impl(_UHead&& __head) 514 4735574 : : _Base(std::forward<_UHead>(__head)) 515 4735574 : { } 516 : 517 : constexpr _Tuple_impl(const _Tuple_impl&) = default; 518 : 519 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 520 : // 2729. Missing SFINAE on std::pair::operator= 521 : _Tuple_impl& operator=(const _Tuple_impl&) = delete; 522 : 523 : #if _GLIBCXX_INLINE_VERSION 524 : _Tuple_impl(_Tuple_impl&&) = default; 525 : #else 526 : constexpr 527 11887166 : _Tuple_impl(_Tuple_impl&& __in) 528 : noexcept(is_nothrow_move_constructible<_Head>::value) 529 11885956 : : _Base(static_cast<_Base&&>(__in)) 530 11887166 : { } 531 : #endif 532 : 533 : template<typename _UHead> 534 : constexpr 535 : _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in) 536 : : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in)) 537 : { } 538 : 539 : template<typename _UHead> 540 : constexpr 541 : _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in) 542 : : _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in))) 543 : { } 544 : 545 : #if __cplusplus > 202002L 546 : template<typename _UHead> 547 : constexpr 548 : _Tuple_impl(_Tuple_impl<_Idx, _UHead>& __in) 549 : : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in)) 550 : { } 551 : 552 : template<typename _UHead> 553 : constexpr 554 : _Tuple_impl(const _Tuple_impl<_Idx, _UHead>&& __in) 555 : : _Base(std::forward<const _UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in))) 556 : { } 557 : #endif // C++23 558 : 559 : template<typename _Alloc> 560 : _GLIBCXX20_CONSTEXPR 561 : _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a) 562 : : _Base(__tag, __use_alloc<_Head>(__a)) 563 : { } 564 : 565 : template<typename _Alloc> 566 : _GLIBCXX20_CONSTEXPR 567 : _Tuple_impl(allocator_arg_t, const _Alloc& __a, 568 : const _Head& __head) 569 : : _Base(__use_alloc<_Head, _Alloc, const _Head&>(__a), __head) 570 : { } 571 : 572 : template<typename _Alloc, typename _UHead> 573 : _GLIBCXX20_CONSTEXPR 574 : _Tuple_impl(allocator_arg_t, const _Alloc& __a, 575 : _UHead&& __head) 576 : : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), 577 : std::forward<_UHead>(__head)) 578 : { } 579 : 580 : template<typename _Alloc> 581 : _GLIBCXX20_CONSTEXPR 582 : _Tuple_impl(allocator_arg_t, const _Alloc& __a, 583 : const _Tuple_impl& __in) 584 : : _Base(__use_alloc<_Head, _Alloc, const _Head&>(__a), _M_head(__in)) 585 : { } 586 : 587 : template<typename _Alloc> 588 : _GLIBCXX20_CONSTEXPR 589 : _Tuple_impl(allocator_arg_t, const _Alloc& __a, 590 : _Tuple_impl&& __in) 591 : : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), 592 : std::forward<_Head>(_M_head(__in))) 593 : { } 594 : 595 : template<typename _Alloc, typename _UHead> 596 : _GLIBCXX20_CONSTEXPR 597 : _Tuple_impl(allocator_arg_t, const _Alloc& __a, 598 : const _Tuple_impl<_Idx, _UHead>& __in) 599 : : _Base(__use_alloc<_Head, _Alloc, const _UHead&>(__a), 600 : _Tuple_impl<_Idx, _UHead>::_M_head(__in)) 601 : { } 602 : 603 : template<typename _Alloc, typename _UHead> 604 : _GLIBCXX20_CONSTEXPR 605 : _Tuple_impl(allocator_arg_t, const _Alloc& __a, 606 : _Tuple_impl<_Idx, _UHead>&& __in) 607 : : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), 608 : std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in))) 609 : { } 610 : 611 : #if __cplusplus > 202002L 612 : template<typename _Alloc, typename _UHead> 613 : constexpr 614 : _Tuple_impl(allocator_arg_t, const _Alloc& __a, 615 : _Tuple_impl<_Idx, _UHead>& __in) 616 : : _Base(__use_alloc<_Head, _Alloc, _UHead&>(__a), 617 : _Tuple_impl<_Idx, _UHead>::_M_head(__in)) 618 : { } 619 : 620 : template<typename _Alloc, typename _UHead> 621 : constexpr 622 : _Tuple_impl(allocator_arg_t, const _Alloc& __a, 623 : const _Tuple_impl<_Idx, _UHead>&& __in) 624 : : _Base(__use_alloc<_Head, _Alloc, const _UHead>(__a), 625 : std::forward<const _UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in))) 626 : { } 627 : #endif // C++23 628 : 629 : template<typename _UHead> 630 : _GLIBCXX20_CONSTEXPR 631 : void 632 : _M_assign(const _Tuple_impl<_Idx, _UHead>& __in) 633 : { 634 : _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in); 635 : } 636 : 637 : template<typename _UHead> 638 : _GLIBCXX20_CONSTEXPR 639 : void 640 286 : _M_assign(_Tuple_impl<_Idx, _UHead>&& __in) 641 : { 642 286 : _M_head(*this) 643 286 : = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)); 644 286 : } 645 : 646 : #if __cplusplus > 202002L 647 : template<typename _UHead> 648 : constexpr void 649 : _M_assign(const _Tuple_impl<_Idx, _UHead>& __in) const 650 : { 651 : _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in); 652 : } 653 : 654 : template<typename _UHead> 655 : constexpr void 656 : _M_assign(_Tuple_impl<_Idx, _UHead>&& __in) const 657 : { 658 : _M_head(*this) 659 : = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)); 660 : } 661 : #endif // C++23 662 : 663 : protected: 664 : _GLIBCXX20_CONSTEXPR 665 : void 666 : _M_swap(_Tuple_impl& __in) 667 : { 668 : using std::swap; 669 : swap(_M_head(*this), _M_head(__in)); 670 : } 671 : 672 : #if __cplusplus > 202002L 673 : constexpr void 674 : _M_swap(const _Tuple_impl& __in) const 675 : { 676 : using std::swap; 677 : swap(_M_head(*this), _M_head(__in)); 678 : } 679 : #endif // C++23 680 : }; 681 : 682 : // Concept utility functions, reused in conditionally-explicit 683 : // constructors. 684 : template<bool, typename... _Types> 685 : struct _TupleConstraints 686 : { 687 : template<typename... _UTypes> 688 : using __constructible = __and_<is_constructible<_Types, _UTypes>...>; 689 : 690 : template<typename... _UTypes> 691 : using __convertible = __and_<is_convertible<_UTypes, _Types>...>; 692 : 693 : // Constraint for a non-explicit constructor. 694 : // True iff each Ti in _Types... can be constructed from Ui in _UTypes... 695 : // and every Ui is implicitly convertible to Ti. 696 : template<typename... _UTypes> 697 : static constexpr bool __is_implicitly_constructible() 698 : { 699 : return __and_<__constructible<_UTypes...>, 700 : __convertible<_UTypes...> 701 : >::value; 702 : } 703 : 704 : // Constraint for a non-explicit constructor. 705 : // True iff each Ti in _Types... can be constructed from Ui in _UTypes... 706 : // but not every Ui is implicitly convertible to Ti. 707 : template<typename... _UTypes> 708 : static constexpr bool __is_explicitly_constructible() 709 : { 710 : return __and_<__constructible<_UTypes...>, 711 : __not_<__convertible<_UTypes...>> 712 : >::value; 713 : } 714 : 715 : static constexpr bool __is_implicitly_default_constructible() 716 : { 717 : return __and_<std::__is_implicitly_default_constructible<_Types>... 718 : >::value; 719 : } 720 : 721 : static constexpr bool __is_explicitly_default_constructible() 722 : { 723 : return __and_<is_default_constructible<_Types>..., 724 : __not_<__and_< 725 : std::__is_implicitly_default_constructible<_Types>...> 726 : >>::value; 727 : } 728 : }; 729 : 730 : // Partial specialization used when a required precondition isn't met, 731 : // e.g. when sizeof...(_Types) != sizeof...(_UTypes). 732 : template<typename... _Types> 733 : struct _TupleConstraints<false, _Types...> 734 : { 735 : template<typename... _UTypes> 736 : static constexpr bool __is_implicitly_constructible() 737 : { return false; } 738 : 739 : template<typename... _UTypes> 740 : static constexpr bool __is_explicitly_constructible() 741 : { return false; } 742 : }; 743 : 744 : /// Primary class template, tuple 745 : template<typename... _Elements> 746 : class tuple : public _Tuple_impl<0, _Elements...> 747 : { 748 : typedef _Tuple_impl<0, _Elements...> _Inherited; 749 : 750 : template<bool _Cond> 751 : using _TCC = _TupleConstraints<_Cond, _Elements...>; 752 : 753 : // Constraint for non-explicit default constructor 754 : template<bool _Dummy> 755 : using _ImplicitDefaultCtor = __enable_if_t< 756 : _TCC<_Dummy>::__is_implicitly_default_constructible(), 757 : bool>; 758 : 759 : // Constraint for explicit default constructor 760 : template<bool _Dummy> 761 : using _ExplicitDefaultCtor = __enable_if_t< 762 : _TCC<_Dummy>::__is_explicitly_default_constructible(), 763 : bool>; 764 : 765 : // Constraint for non-explicit constructors 766 : template<bool _Cond, typename... _Args> 767 : using _ImplicitCtor = __enable_if_t< 768 : _TCC<_Cond>::template __is_implicitly_constructible<_Args...>(), 769 : bool>; 770 : 771 : // Constraint for non-explicit constructors 772 : template<bool _Cond, typename... _Args> 773 : using _ExplicitCtor = __enable_if_t< 774 : _TCC<_Cond>::template __is_explicitly_constructible<_Args...>(), 775 : bool>; 776 : 777 : template<typename... _UElements> 778 : static constexpr 779 : __enable_if_t<sizeof...(_UElements) == sizeof...(_Elements), bool> 780 : __assignable() 781 : { return __and_<is_assignable<_Elements&, _UElements>...>::value; } 782 : 783 : // Condition for noexcept-specifier of an assignment operator. 784 : template<typename... _UElements> 785 : static constexpr bool __nothrow_assignable() 786 : { 787 : return 788 : __and_<is_nothrow_assignable<_Elements&, _UElements>...>::value; 789 : } 790 : 791 : // Condition for noexcept-specifier of a constructor. 792 : template<typename... _UElements> 793 : static constexpr bool __nothrow_constructible() 794 : { 795 : return 796 : __and_<is_nothrow_constructible<_Elements, _UElements>...>::value; 797 : } 798 : 799 : // Constraint for tuple(_UTypes&&...) where sizeof...(_UTypes) == 1. 800 : template<typename _Up> 801 : static constexpr bool __valid_args() 802 : { 803 : return sizeof...(_Elements) == 1 804 : && !is_same<tuple, __remove_cvref_t<_Up>>::value; 805 : } 806 : 807 : // Constraint for tuple(_UTypes&&...) where sizeof...(_UTypes) > 1. 808 : template<typename, typename, typename... _Tail> 809 : static constexpr bool __valid_args() 810 : { return (sizeof...(_Tail) + 2) == sizeof...(_Elements); } 811 : 812 : /* Constraint for constructors with a tuple<UTypes...> parameter ensures 813 : * that the constructor is only viable when it would not interfere with 814 : * tuple(UTypes&&...) or tuple(const tuple&) or tuple(tuple&&). 815 : * Such constructors are only viable if: 816 : * either sizeof...(Types) != 1, 817 : * or (when Types... expands to T and UTypes... expands to U) 818 : * is_convertible_v<TUPLE, T>, is_constructible_v<T, TUPLE>, 819 : * and is_same_v<T, U> are all false. 820 : */ 821 : template<typename _Tuple, typename = tuple, 822 : typename = __remove_cvref_t<_Tuple>> 823 : struct _UseOtherCtor 824 : : false_type 825 : { }; 826 : // If TUPLE is convertible to the single element in *this, 827 : // then TUPLE should match tuple(UTypes&&...) instead. 828 : template<typename _Tuple, typename _Tp, typename _Up> 829 : struct _UseOtherCtor<_Tuple, tuple<_Tp>, tuple<_Up>> 830 : : __or_<is_convertible<_Tuple, _Tp>, is_constructible<_Tp, _Tuple>>::type 831 : { }; 832 : // If TUPLE and *this each have a single element of the same type, 833 : // then TUPLE should match a copy/move constructor instead. 834 : template<typename _Tuple, typename _Tp> 835 : struct _UseOtherCtor<_Tuple, tuple<_Tp>, tuple<_Tp>> 836 : : true_type 837 : { }; 838 : 839 : // Return true iff sizeof...(Types) == 1 && tuple_size_v<TUPLE> == 1 840 : // and the single element in Types can be initialized from TUPLE, 841 : // or is the same type as tuple_element_t<0, TUPLE>. 842 : template<typename _Tuple> 843 : static constexpr bool __use_other_ctor() 844 : { return _UseOtherCtor<_Tuple>::value; } 845 : 846 : #if __cplusplus > 202002L 847 : template<typename... _Args> 848 : static constexpr bool __constructible 849 : = _TCC<true>::template __constructible<_Args...>::value; 850 : 851 : template<typename... _Args> 852 : static constexpr bool __convertible 853 : = _TCC<true>::template __convertible<_Args...>::value; 854 : #endif // C++23 855 : 856 : public: 857 : template<typename _Dummy = void, 858 : _ImplicitDefaultCtor<is_void<_Dummy>::value> = true> 859 : constexpr 860 : tuple() 861 : noexcept(__and_<is_nothrow_default_constructible<_Elements>...>::value) 862 : : _Inherited() { } 863 : 864 : template<typename _Dummy = void, 865 : _ExplicitDefaultCtor<is_void<_Dummy>::value> = false> 866 : explicit constexpr 867 : tuple() 868 : noexcept(__and_<is_nothrow_default_constructible<_Elements>...>::value) 869 : : _Inherited() { } 870 : 871 : template<bool _NotEmpty = (sizeof...(_Elements) >= 1), 872 : _ImplicitCtor<_NotEmpty, const _Elements&...> = true> 873 : constexpr 874 8756886 : tuple(const _Elements&... __elements) 875 : noexcept(__nothrow_constructible<const _Elements&...>()) 876 8756886 : : _Inherited(__elements...) { } 877 : 878 : template<bool _NotEmpty = (sizeof...(_Elements) >= 1), 879 : _ExplicitCtor<_NotEmpty, const _Elements&...> = false> 880 : explicit constexpr 881 : tuple(const _Elements&... __elements) 882 : noexcept(__nothrow_constructible<const _Elements&...>()) 883 : : _Inherited(__elements...) { } 884 : 885 : template<typename... _UElements, 886 : bool _Valid = __valid_args<_UElements...>(), 887 : _ImplicitCtor<_Valid, _UElements...> = true> 888 : constexpr 889 4735376 : tuple(_UElements&&... __elements) 890 : noexcept(__nothrow_constructible<_UElements...>()) 891 4735376 : : _Inherited(std::forward<_UElements>(__elements)...) { } 892 : 893 : template<typename... _UElements, 894 : bool _Valid = __valid_args<_UElements...>(), 895 : _ExplicitCtor<_Valid, _UElements...> = false> 896 : explicit constexpr 897 : tuple(_UElements&&... __elements) 898 : noexcept(__nothrow_constructible<_UElements...>()) 899 : : _Inherited(std::forward<_UElements>(__elements)...) { } 900 : 901 : constexpr tuple(const tuple&) = default; 902 : 903 11885956 : constexpr tuple(tuple&&) = default; 904 : 905 : template<typename... _UElements, 906 : bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) 907 : && !__use_other_ctor<const tuple<_UElements...>&>(), 908 : _ImplicitCtor<_Valid, const _UElements&...> = true> 909 : constexpr 910 : tuple(const tuple<_UElements...>& __in) 911 : noexcept(__nothrow_constructible<const _UElements&...>()) 912 : : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) 913 : { } 914 : 915 : template<typename... _UElements, 916 : bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) 917 : && !__use_other_ctor<const tuple<_UElements...>&>(), 918 : _ExplicitCtor<_Valid, const _UElements&...> = false> 919 : explicit constexpr 920 : tuple(const tuple<_UElements...>& __in) 921 : noexcept(__nothrow_constructible<const _UElements&...>()) 922 : : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) 923 : { } 924 : 925 : template<typename... _UElements, 926 : bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) 927 : && !__use_other_ctor<tuple<_UElements...>&&>(), 928 : _ImplicitCtor<_Valid, _UElements...> = true> 929 : constexpr 930 : tuple(tuple<_UElements...>&& __in) 931 : noexcept(__nothrow_constructible<_UElements...>()) 932 : : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } 933 : 934 : template<typename... _UElements, 935 : bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) 936 : && !__use_other_ctor<tuple<_UElements...>&&>(), 937 : _ExplicitCtor<_Valid, _UElements...> = false> 938 : explicit constexpr 939 : tuple(tuple<_UElements...>&& __in) 940 : noexcept(__nothrow_constructible<_UElements...>()) 941 : : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } 942 : 943 : #if __cplusplus > 202002L 944 : template<typename... _UElements> 945 : requires (sizeof...(_Elements) == sizeof...(_UElements)) 946 : && (!__use_other_ctor<tuple<_UElements...>&>()) 947 : && __constructible<_UElements&...> 948 : explicit(!__convertible<_UElements&...>) 949 : constexpr 950 : tuple(tuple<_UElements...>& __in) 951 : noexcept(__nothrow_constructible<_UElements&...>()) 952 : : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&>(__in)) 953 : { } 954 : 955 : template<typename... _UElements> 956 : requires (sizeof...(_Elements) == sizeof...(_UElements)) 957 : && (!__use_other_ctor<const tuple<_UElements...>&&>()) 958 : && __constructible<const _UElements...> 959 : explicit(!__convertible<const _UElements...>) 960 : constexpr 961 : tuple(const tuple<_UElements...>&& __in) 962 : noexcept(__nothrow_constructible<const _UElements...>()) 963 : : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&&>(__in)) { } 964 : #endif // C++23 965 : 966 : // Allocator-extended constructors. 967 : 968 : template<typename _Alloc, 969 : _ImplicitDefaultCtor<is_object<_Alloc>::value> = true> 970 : _GLIBCXX20_CONSTEXPR 971 : tuple(allocator_arg_t __tag, const _Alloc& __a) 972 : : _Inherited(__tag, __a) { } 973 : 974 : template<typename _Alloc, bool _NotEmpty = (sizeof...(_Elements) >= 1), 975 : _ImplicitCtor<_NotEmpty, const _Elements&...> = true> 976 : _GLIBCXX20_CONSTEXPR 977 : tuple(allocator_arg_t __tag, const _Alloc& __a, 978 : const _Elements&... __elements) 979 : : _Inherited(__tag, __a, __elements...) { } 980 : 981 : template<typename _Alloc, bool _NotEmpty = (sizeof...(_Elements) >= 1), 982 : _ExplicitCtor<_NotEmpty, const _Elements&...> = false> 983 : _GLIBCXX20_CONSTEXPR 984 : explicit 985 : tuple(allocator_arg_t __tag, const _Alloc& __a, 986 : const _Elements&... __elements) 987 : : _Inherited(__tag, __a, __elements...) { } 988 : 989 : template<typename _Alloc, typename... _UElements, 990 : bool _Valid = __valid_args<_UElements...>(), 991 : _ImplicitCtor<_Valid, _UElements...> = true> 992 : _GLIBCXX20_CONSTEXPR 993 : tuple(allocator_arg_t __tag, const _Alloc& __a, 994 : _UElements&&... __elements) 995 : : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...) 996 : { } 997 : 998 : template<typename _Alloc, typename... _UElements, 999 : bool _Valid = __valid_args<_UElements...>(), 1000 : _ExplicitCtor<_Valid, _UElements...> = false> 1001 : _GLIBCXX20_CONSTEXPR 1002 : explicit 1003 : tuple(allocator_arg_t __tag, const _Alloc& __a, 1004 : _UElements&&... __elements) 1005 : : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...) 1006 : { } 1007 : 1008 : template<typename _Alloc> 1009 : _GLIBCXX20_CONSTEXPR 1010 : tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) 1011 : : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { } 1012 : 1013 : template<typename _Alloc> 1014 : _GLIBCXX20_CONSTEXPR 1015 : tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) 1016 : : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { } 1017 : 1018 : template<typename _Alloc, typename... _UElements, 1019 : bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) 1020 : && !__use_other_ctor<const tuple<_UElements...>&>(), 1021 : _ImplicitCtor<_Valid, const _UElements&...> = true> 1022 : _GLIBCXX20_CONSTEXPR 1023 : tuple(allocator_arg_t __tag, const _Alloc& __a, 1024 : const tuple<_UElements...>& __in) 1025 : : _Inherited(__tag, __a, 1026 : static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) 1027 : { } 1028 : 1029 : template<typename _Alloc, typename... _UElements, 1030 : bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) 1031 : && !__use_other_ctor<const tuple<_UElements...>&>(), 1032 : _ExplicitCtor<_Valid, const _UElements&...> = false> 1033 : _GLIBCXX20_CONSTEXPR 1034 : explicit 1035 : tuple(allocator_arg_t __tag, const _Alloc& __a, 1036 : const tuple<_UElements...>& __in) 1037 : : _Inherited(__tag, __a, 1038 : static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) 1039 : { } 1040 : 1041 : template<typename _Alloc, typename... _UElements, 1042 : bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) 1043 : && !__use_other_ctor<tuple<_UElements...>&&>(), 1044 : _ImplicitCtor<_Valid, _UElements...> = true> 1045 : _GLIBCXX20_CONSTEXPR 1046 : tuple(allocator_arg_t __tag, const _Alloc& __a, 1047 : tuple<_UElements...>&& __in) 1048 : : _Inherited(__tag, __a, 1049 : static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) 1050 : { } 1051 : 1052 : template<typename _Alloc, typename... _UElements, 1053 : bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) 1054 : && !__use_other_ctor<tuple<_UElements...>&&>(), 1055 : _ExplicitCtor<_Valid, _UElements...> = false> 1056 : _GLIBCXX20_CONSTEXPR 1057 : explicit 1058 : tuple(allocator_arg_t __tag, const _Alloc& __a, 1059 : tuple<_UElements...>&& __in) 1060 : : _Inherited(__tag, __a, 1061 : static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) 1062 : { } 1063 : 1064 : #if __cplusplus > 202002L 1065 : template<typename _Alloc, typename... _UElements> 1066 : requires (sizeof...(_Elements) == sizeof...(_UElements)) 1067 : && (!__use_other_ctor<tuple<_UElements...>&>()) 1068 : && __constructible<_UElements&...> 1069 : explicit(!__convertible<_UElements&...>) 1070 : constexpr 1071 : tuple(allocator_arg_t __tag, const _Alloc& __a, 1072 : tuple<_UElements...>& __in) 1073 : : _Inherited(__tag, __a, 1074 : static_cast<_Tuple_impl<0, _UElements...>&>(__in)) 1075 : { } 1076 : 1077 : template<typename _Alloc, typename... _UElements> 1078 : requires (sizeof...(_Elements) == sizeof...(_UElements)) 1079 : && (!__use_other_ctor<const tuple<_UElements...>>()) 1080 : && __constructible<const _UElements...> 1081 : explicit(!__convertible<const _UElements...>) 1082 : constexpr 1083 : tuple(allocator_arg_t __tag, const _Alloc& __a, 1084 : const tuple<_UElements...>&& __in) 1085 : : _Inherited(__tag, __a, 1086 : static_cast<const _Tuple_impl<0, _UElements...>&&>(__in)) 1087 : { } 1088 : #endif // C++23 1089 : 1090 : // tuple assignment 1091 : 1092 : _GLIBCXX20_CONSTEXPR 1093 : tuple& 1094 : operator=(__conditional_t<__assignable<const _Elements&...>(), 1095 : const tuple&, 1096 : const __nonesuch&> __in) 1097 : noexcept(__nothrow_assignable<const _Elements&...>()) 1098 : { 1099 : this->_M_assign(__in); 1100 : return *this; 1101 : } 1102 : 1103 : _GLIBCXX20_CONSTEXPR 1104 : tuple& 1105 : operator=(__conditional_t<__assignable<_Elements...>(), 1106 : tuple&&, 1107 : __nonesuch&&> __in) 1108 : noexcept(__nothrow_assignable<_Elements...>()) 1109 : { 1110 : this->_M_assign(std::move(__in)); 1111 : return *this; 1112 : } 1113 : 1114 : template<typename... _UElements> 1115 : _GLIBCXX20_CONSTEXPR 1116 : __enable_if_t<__assignable<const _UElements&...>(), tuple&> 1117 : operator=(const tuple<_UElements...>& __in) 1118 : noexcept(__nothrow_assignable<const _UElements&...>()) 1119 : { 1120 : this->_M_assign(__in); 1121 : return *this; 1122 : } 1123 : 1124 : template<typename... _UElements> 1125 : _GLIBCXX20_CONSTEXPR 1126 : __enable_if_t<__assignable<_UElements...>(), tuple&> 1127 286 : operator=(tuple<_UElements...>&& __in) 1128 : noexcept(__nothrow_assignable<_UElements...>()) 1129 : { 1130 286 : this->_M_assign(std::move(__in)); 1131 286 : return *this; 1132 : } 1133 : 1134 : #if __cplusplus > 202002L 1135 : constexpr const tuple& 1136 : operator=(const tuple& __in) const 1137 : requires (is_copy_assignable_v<const _Elements> && ...) 1138 : { 1139 : this->_M_assign(__in); 1140 : return *this; 1141 : } 1142 : 1143 : constexpr const tuple& 1144 : operator=(tuple&& __in) const 1145 : requires (is_assignable_v<const _Elements&, _Elements> && ...) 1146 : { 1147 : this->_M_assign(std::move(__in)); 1148 : return *this; 1149 : } 1150 : 1151 : template<typename... _UElements> 1152 : constexpr const tuple& 1153 : operator=(const tuple<_UElements...>& __in) const 1154 : requires (sizeof...(_Elements) == sizeof...(_UElements)) 1155 : && (is_assignable_v<const _Elements&, const _UElements&> && ...) 1156 : { 1157 : this->_M_assign(__in); 1158 : return *this; 1159 : } 1160 : 1161 : template<typename... _UElements> 1162 : constexpr const tuple& 1163 : operator=(tuple<_UElements...>&& __in) const 1164 : requires (sizeof...(_Elements) == sizeof...(_UElements)) 1165 : && (is_assignable_v<const _Elements&, _UElements> && ...) 1166 : { 1167 : this->_M_assign(std::move(__in)); 1168 : return *this; 1169 : } 1170 : #endif // C++23 1171 : 1172 : // tuple swap 1173 : _GLIBCXX20_CONSTEXPR 1174 : void 1175 : swap(tuple& __in) 1176 : noexcept(__and_<__is_nothrow_swappable<_Elements>...>::value) 1177 : { _Inherited::_M_swap(__in); } 1178 : 1179 : #if __cplusplus > 202002L 1180 : // As an extension, we constrain the const swap member function in order 1181 : // to continue accepting explicit instantiation of tuples whose elements 1182 : // are not all const swappable. Without this constraint, such an 1183 : // explicit instantiation would also instantiate the ill-formed body of 1184 : // this function and yield a hard error. This constraint shouldn't 1185 : // affect the behavior of valid programs. 1186 : constexpr void 1187 : swap(const tuple& __in) const 1188 : noexcept(__and_v<__is_nothrow_swappable<const _Elements>...>) 1189 : requires (is_swappable_v<const _Elements> && ...) 1190 : { _Inherited::_M_swap(__in); } 1191 : #endif // C++23 1192 : }; 1193 : 1194 : #if __cpp_deduction_guides >= 201606 1195 : template<typename... _UTypes> 1196 : tuple(_UTypes...) -> tuple<_UTypes...>; 1197 : template<typename _T1, typename _T2> 1198 : tuple(pair<_T1, _T2>) -> tuple<_T1, _T2>; 1199 : template<typename _Alloc, typename... _UTypes> 1200 : tuple(allocator_arg_t, _Alloc, _UTypes...) -> tuple<_UTypes...>; 1201 : template<typename _Alloc, typename _T1, typename _T2> 1202 : tuple(allocator_arg_t, _Alloc, pair<_T1, _T2>) -> tuple<_T1, _T2>; 1203 : template<typename _Alloc, typename... _UTypes> 1204 : tuple(allocator_arg_t, _Alloc, tuple<_UTypes...>) -> tuple<_UTypes...>; 1205 : #endif 1206 : 1207 : // Explicit specialization, zero-element tuple. 1208 : template<> 1209 : class tuple<> 1210 : { 1211 : public: 1212 : _GLIBCXX20_CONSTEXPR 1213 : void swap(tuple&) noexcept { /* no-op */ } 1214 : #if __cplusplus > 202002L 1215 : constexpr void swap(const tuple&) const noexcept { /* no-op */ } 1216 : #endif 1217 : // We need the default since we're going to define no-op 1218 : // allocator constructors. 1219 : tuple() = default; 1220 : // No-op allocator constructors. 1221 : template<typename _Alloc> 1222 : _GLIBCXX20_CONSTEXPR 1223 : tuple(allocator_arg_t, const _Alloc&) noexcept { } 1224 : template<typename _Alloc> 1225 : _GLIBCXX20_CONSTEXPR 1226 : tuple(allocator_arg_t, const _Alloc&, const tuple&) noexcept { } 1227 : }; 1228 : 1229 : /// Partial specialization, 2-element tuple. 1230 : /// Includes construction and assignment from a pair. 1231 : template<typename _T1, typename _T2> 1232 : class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2> 1233 : { 1234 : typedef _Tuple_impl<0, _T1, _T2> _Inherited; 1235 : 1236 : // Constraint for non-explicit default constructor 1237 : template<bool _Dummy, typename _U1, typename _U2> 1238 : using _ImplicitDefaultCtor = __enable_if_t< 1239 : _TupleConstraints<_Dummy, _U1, _U2>:: 1240 : __is_implicitly_default_constructible(), 1241 : bool>; 1242 : 1243 : // Constraint for explicit default constructor 1244 : template<bool _Dummy, typename _U1, typename _U2> 1245 : using _ExplicitDefaultCtor = __enable_if_t< 1246 : _TupleConstraints<_Dummy, _U1, _U2>:: 1247 : __is_explicitly_default_constructible(), 1248 : bool>; 1249 : 1250 : template<bool _Dummy> 1251 : using _TCC = _TupleConstraints<_Dummy, _T1, _T2>; 1252 : 1253 : // Constraint for non-explicit constructors 1254 : template<bool _Cond, typename _U1, typename _U2> 1255 : using _ImplicitCtor = __enable_if_t< 1256 : _TCC<_Cond>::template __is_implicitly_constructible<_U1, _U2>(), 1257 : bool>; 1258 : 1259 : // Constraint for non-explicit constructors 1260 : template<bool _Cond, typename _U1, typename _U2> 1261 : using _ExplicitCtor = __enable_if_t< 1262 : _TCC<_Cond>::template __is_explicitly_constructible<_U1, _U2>(), 1263 : bool>; 1264 : 1265 : template<typename _U1, typename _U2> 1266 : static constexpr bool __assignable() 1267 : { 1268 : return __and_<is_assignable<_T1&, _U1>, 1269 : is_assignable<_T2&, _U2>>::value; 1270 : } 1271 : 1272 : template<typename _U1, typename _U2> 1273 : static constexpr bool __nothrow_assignable() 1274 : { 1275 : return __and_<is_nothrow_assignable<_T1&, _U1>, 1276 : is_nothrow_assignable<_T2&, _U2>>::value; 1277 : } 1278 : 1279 : template<typename _U1, typename _U2> 1280 : static constexpr bool __nothrow_constructible() 1281 : { 1282 : return __and_<is_nothrow_constructible<_T1, _U1>, 1283 : is_nothrow_constructible<_T2, _U2>>::value; 1284 : } 1285 : 1286 : static constexpr bool __nothrow_default_constructible() 1287 : { 1288 : return __and_<is_nothrow_default_constructible<_T1>, 1289 : is_nothrow_default_constructible<_T2>>::value; 1290 : } 1291 : 1292 : template<typename _U1> 1293 : static constexpr bool __is_alloc_arg() 1294 : { return is_same<__remove_cvref_t<_U1>, allocator_arg_t>::value; } 1295 : 1296 : #if __cplusplus > 202002L 1297 : template<typename _U1, typename _U2> 1298 : static constexpr bool __constructible 1299 : = _TCC<true>::template __constructible<_U1, _U2>::value; 1300 : 1301 : template<typename _U1, typename _U2> 1302 : static constexpr bool __convertible 1303 : = _TCC<true>::template __convertible<_U1, _U2>::value; 1304 : #endif // C++23 1305 : 1306 : public: 1307 : template<bool _Dummy = true, 1308 : _ImplicitDefaultCtor<_Dummy, _T1, _T2> = true> 1309 : constexpr 1310 2051824 : tuple() 1311 : noexcept(__nothrow_default_constructible()) 1312 2051824 : : _Inherited() { } 1313 : 1314 : template<bool _Dummy = true, 1315 : _ExplicitDefaultCtor<_Dummy, _T1, _T2> = false> 1316 : explicit constexpr 1317 : tuple() 1318 : noexcept(__nothrow_default_constructible()) 1319 : : _Inherited() { } 1320 : 1321 : template<bool _Dummy = true, 1322 : _ImplicitCtor<_Dummy, const _T1&, const _T2&> = true> 1323 : constexpr 1324 : tuple(const _T1& __a1, const _T2& __a2) 1325 : noexcept(__nothrow_constructible<const _T1&, const _T2&>()) 1326 : : _Inherited(__a1, __a2) { } 1327 : 1328 : template<bool _Dummy = true, 1329 : _ExplicitCtor<_Dummy, const _T1&, const _T2&> = false> 1330 : explicit constexpr 1331 : tuple(const _T1& __a1, const _T2& __a2) 1332 : noexcept(__nothrow_constructible<const _T1&, const _T2&>()) 1333 : : _Inherited(__a1, __a2) { } 1334 : 1335 : template<typename _U1, typename _U2, 1336 : _ImplicitCtor<!__is_alloc_arg<_U1>(), _U1, _U2> = true> 1337 : constexpr 1338 644 : tuple(_U1&& __a1, _U2&& __a2) 1339 : noexcept(__nothrow_constructible<_U1, _U2>()) 1340 644 : : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } 1341 : 1342 : template<typename _U1, typename _U2, 1343 : _ExplicitCtor<!__is_alloc_arg<_U1>(), _U1, _U2> = false> 1344 : explicit constexpr 1345 : tuple(_U1&& __a1, _U2&& __a2) 1346 : noexcept(__nothrow_constructible<_U1, _U2>()) 1347 : : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } 1348 : 1349 : constexpr tuple(const tuple&) = default; 1350 : 1351 1210 : constexpr tuple(tuple&&) = default; 1352 : 1353 : template<typename _U1, typename _U2, 1354 : _ImplicitCtor<true, const _U1&, const _U2&> = true> 1355 : constexpr 1356 : tuple(const tuple<_U1, _U2>& __in) 1357 : noexcept(__nothrow_constructible<const _U1&, const _U2&>()) 1358 : : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { } 1359 : 1360 : template<typename _U1, typename _U2, 1361 : _ExplicitCtor<true, const _U1&, const _U2&> = false> 1362 : explicit constexpr 1363 : tuple(const tuple<_U1, _U2>& __in) 1364 : noexcept(__nothrow_constructible<const _U1&, const _U2&>()) 1365 : : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { } 1366 : 1367 : template<typename _U1, typename _U2, 1368 : _ImplicitCtor<true, _U1, _U2> = true> 1369 : constexpr 1370 : tuple(tuple<_U1, _U2>&& __in) 1371 : noexcept(__nothrow_constructible<_U1, _U2>()) 1372 : : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } 1373 : 1374 : template<typename _U1, typename _U2, 1375 : _ExplicitCtor<true, _U1, _U2> = false> 1376 : explicit constexpr 1377 : tuple(tuple<_U1, _U2>&& __in) 1378 : noexcept(__nothrow_constructible<_U1, _U2>()) 1379 : : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } 1380 : 1381 : #if __cplusplus > 202002L 1382 : template<typename _U1, typename _U2> 1383 : requires __constructible<_U1&, _U2&> 1384 : explicit(!__convertible<_U1&, _U2&>) 1385 : constexpr 1386 : tuple(tuple<_U1, _U2>& __in) 1387 : noexcept(__nothrow_constructible<_U1&, _U2&>()) 1388 : : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&>(__in)) { } 1389 : 1390 : template<typename _U1, typename _U2> 1391 : requires __constructible<const _U1, const _U2> 1392 : explicit(!__convertible<const _U1, const _U2>) 1393 : constexpr 1394 : tuple(const tuple<_U1, _U2>&& __in) 1395 : noexcept(__nothrow_constructible<const _U1, const _U2>()) 1396 : : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&&>(__in)) { } 1397 : #endif // C++23 1398 : 1399 : template<typename _U1, typename _U2, 1400 : _ImplicitCtor<true, const _U1&, const _U2&> = true> 1401 : constexpr 1402 : tuple(const pair<_U1, _U2>& __in) 1403 : noexcept(__nothrow_constructible<const _U1&, const _U2&>()) 1404 : : _Inherited(__in.first, __in.second) { } 1405 : 1406 : template<typename _U1, typename _U2, 1407 : _ExplicitCtor<true, const _U1&, const _U2&> = false> 1408 : explicit constexpr 1409 : tuple(const pair<_U1, _U2>& __in) 1410 : noexcept(__nothrow_constructible<const _U1&, const _U2&>()) 1411 : : _Inherited(__in.first, __in.second) { } 1412 : 1413 : template<typename _U1, typename _U2, 1414 : _ImplicitCtor<true, _U1, _U2> = true> 1415 : constexpr 1416 : tuple(pair<_U1, _U2>&& __in) 1417 : noexcept(__nothrow_constructible<_U1, _U2>()) 1418 : : _Inherited(std::forward<_U1>(__in.first), 1419 : std::forward<_U2>(__in.second)) { } 1420 : 1421 : template<typename _U1, typename _U2, 1422 : _ExplicitCtor<true, _U1, _U2> = false> 1423 : explicit constexpr 1424 : tuple(pair<_U1, _U2>&& __in) 1425 : noexcept(__nothrow_constructible<_U1, _U2>()) 1426 : : _Inherited(std::forward<_U1>(__in.first), 1427 : std::forward<_U2>(__in.second)) { } 1428 : 1429 : #if __cplusplus > 202002L 1430 : template<typename _U1, typename _U2> 1431 : requires __constructible<_U1&, _U2&> 1432 : explicit(!__convertible<_U1&, _U2&>) 1433 : constexpr 1434 : tuple(pair<_U1, _U2>& __in) 1435 : noexcept(__nothrow_constructible<_U1&, _U2&>()) 1436 : : _Inherited(__in.first, __in.second) { } 1437 : 1438 : template<typename _U1, typename _U2> 1439 : requires __constructible<const _U1, const _U2> 1440 : explicit(!__convertible<const _U1, const _U2>) 1441 : constexpr 1442 : tuple(const pair<_U1, _U2>&& __in) 1443 : noexcept(__nothrow_constructible<const _U1, const _U2>()) 1444 : : _Inherited(std::forward<const _U1>(__in.first), 1445 : std::forward<const _U2>(__in.second)) { } 1446 : #endif // C++23 1447 : 1448 : // Allocator-extended constructors. 1449 : 1450 : template<typename _Alloc, 1451 : _ImplicitDefaultCtor<is_object<_Alloc>::value, _T1, _T2> = true> 1452 : _GLIBCXX20_CONSTEXPR 1453 : tuple(allocator_arg_t __tag, const _Alloc& __a) 1454 : : _Inherited(__tag, __a) { } 1455 : 1456 : template<typename _Alloc, bool _Dummy = true, 1457 : _ImplicitCtor<_Dummy, const _T1&, const _T2&> = true> 1458 : _GLIBCXX20_CONSTEXPR 1459 : tuple(allocator_arg_t __tag, const _Alloc& __a, 1460 : const _T1& __a1, const _T2& __a2) 1461 : : _Inherited(__tag, __a, __a1, __a2) { } 1462 : 1463 : template<typename _Alloc, bool _Dummy = true, 1464 : _ExplicitCtor<_Dummy, const _T1&, const _T2&> = false> 1465 : explicit 1466 : _GLIBCXX20_CONSTEXPR 1467 : tuple(allocator_arg_t __tag, const _Alloc& __a, 1468 : const _T1& __a1, const _T2& __a2) 1469 : : _Inherited(__tag, __a, __a1, __a2) { } 1470 : 1471 : template<typename _Alloc, typename _U1, typename _U2, 1472 : _ImplicitCtor<true, _U1, _U2> = true> 1473 : _GLIBCXX20_CONSTEXPR 1474 : tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2) 1475 : : _Inherited(__tag, __a, std::forward<_U1>(__a1), 1476 : std::forward<_U2>(__a2)) { } 1477 : 1478 : template<typename _Alloc, typename _U1, typename _U2, 1479 : _ExplicitCtor<true, _U1, _U2> = false> 1480 : explicit 1481 : _GLIBCXX20_CONSTEXPR 1482 : tuple(allocator_arg_t __tag, const _Alloc& __a, 1483 : _U1&& __a1, _U2&& __a2) 1484 : : _Inherited(__tag, __a, std::forward<_U1>(__a1), 1485 : std::forward<_U2>(__a2)) { } 1486 : 1487 : template<typename _Alloc> 1488 : _GLIBCXX20_CONSTEXPR 1489 : tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) 1490 : : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { } 1491 : 1492 : template<typename _Alloc> 1493 : _GLIBCXX20_CONSTEXPR 1494 : tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) 1495 : : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { } 1496 : 1497 : template<typename _Alloc, typename _U1, typename _U2, 1498 : _ImplicitCtor<true, const _U1&, const _U2&> = true> 1499 : _GLIBCXX20_CONSTEXPR 1500 : tuple(allocator_arg_t __tag, const _Alloc& __a, 1501 : const tuple<_U1, _U2>& __in) 1502 : : _Inherited(__tag, __a, 1503 : static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) 1504 : { } 1505 : 1506 : template<typename _Alloc, typename _U1, typename _U2, 1507 : _ExplicitCtor<true, const _U1&, const _U2&> = false> 1508 : explicit 1509 : _GLIBCXX20_CONSTEXPR 1510 : tuple(allocator_arg_t __tag, const _Alloc& __a, 1511 : const tuple<_U1, _U2>& __in) 1512 : : _Inherited(__tag, __a, 1513 : static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) 1514 : { } 1515 : 1516 : template<typename _Alloc, typename _U1, typename _U2, 1517 : _ImplicitCtor<true, _U1, _U2> = true> 1518 : _GLIBCXX20_CONSTEXPR 1519 : tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in) 1520 : : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) 1521 : { } 1522 : 1523 : template<typename _Alloc, typename _U1, typename _U2, 1524 : _ExplicitCtor<true, _U1, _U2> = false> 1525 : explicit 1526 : _GLIBCXX20_CONSTEXPR 1527 : tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in) 1528 : : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) 1529 : { } 1530 : 1531 : #if __cplusplus > 202002L 1532 : template<typename _Alloc, typename _U1, typename _U2> 1533 : requires __constructible<_U1&, _U2&> 1534 : explicit(!__convertible<_U1&, _U2&>) 1535 : constexpr 1536 : tuple(allocator_arg_t __tag, const _Alloc& __a, 1537 : tuple<_U1, _U2>& __in) 1538 : : _Inherited(__tag, __a, 1539 : static_cast<_Tuple_impl<0, _U1, _U2>&>(__in)) 1540 : { } 1541 : 1542 : template<typename _Alloc, typename _U1, typename _U2> 1543 : requires __constructible<const _U1, const _U2> 1544 : explicit(!__convertible<const _U1, const _U2>) 1545 : constexpr 1546 : tuple(allocator_arg_t __tag, const _Alloc& __a, 1547 : const tuple<_U1, _U2>&& __in) 1548 : : _Inherited(__tag, __a, 1549 : static_cast<const _Tuple_impl<0, _U1, _U2>&&>(__in)) 1550 : { } 1551 : #endif // C++23 1552 : 1553 : template<typename _Alloc, typename _U1, typename _U2, 1554 : _ImplicitCtor<true, const _U1&, const _U2&> = true> 1555 : _GLIBCXX20_CONSTEXPR 1556 : tuple(allocator_arg_t __tag, const _Alloc& __a, 1557 : const pair<_U1, _U2>& __in) 1558 : : _Inherited(__tag, __a, __in.first, __in.second) { } 1559 : 1560 : template<typename _Alloc, typename _U1, typename _U2, 1561 : _ExplicitCtor<true, const _U1&, const _U2&> = false> 1562 : explicit 1563 : _GLIBCXX20_CONSTEXPR 1564 : tuple(allocator_arg_t __tag, const _Alloc& __a, 1565 : const pair<_U1, _U2>& __in) 1566 : : _Inherited(__tag, __a, __in.first, __in.second) { } 1567 : 1568 : template<typename _Alloc, typename _U1, typename _U2, 1569 : _ImplicitCtor<true, _U1, _U2> = true> 1570 : _GLIBCXX20_CONSTEXPR 1571 : tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in) 1572 : : _Inherited(__tag, __a, std::forward<_U1>(__in.first), 1573 : std::forward<_U2>(__in.second)) { } 1574 : 1575 : template<typename _Alloc, typename _U1, typename _U2, 1576 : _ExplicitCtor<true, _U1, _U2> = false> 1577 : explicit 1578 : _GLIBCXX20_CONSTEXPR 1579 : tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in) 1580 : : _Inherited(__tag, __a, std::forward<_U1>(__in.first), 1581 : std::forward<_U2>(__in.second)) { } 1582 : 1583 : #if __cplusplus > 202002L 1584 : template<typename _Alloc, typename _U1, typename _U2> 1585 : requires __constructible<_U1&, _U2&> 1586 : explicit(!__convertible<_U1&, _U2&>) 1587 : constexpr 1588 : tuple(allocator_arg_t __tag, const _Alloc& __a, 1589 : pair<_U1, _U2>& __in) 1590 : : _Inherited(__tag, __a, __in.first, __in.second) { } 1591 : 1592 : template<typename _Alloc, typename _U1, typename _U2> 1593 : requires __constructible<const _U1, const _U2> 1594 : explicit(!__convertible<const _U1, const _U2>) 1595 : constexpr 1596 : tuple(allocator_arg_t __tag, const _Alloc& __a, const pair<_U1, _U2>&& __in) 1597 : : _Inherited(__tag, __a, std::forward<const _U1>(__in.first), 1598 : std::forward<const _U2>(__in.second)) { } 1599 : #endif // C++23 1600 : 1601 : // Tuple assignment. 1602 : 1603 : _GLIBCXX20_CONSTEXPR 1604 : tuple& 1605 : operator=(__conditional_t<__assignable<const _T1&, const _T2&>(), 1606 : const tuple&, 1607 : const __nonesuch&> __in) 1608 : noexcept(__nothrow_assignable<const _T1&, const _T2&>()) 1609 : { 1610 : this->_M_assign(__in); 1611 : return *this; 1612 : } 1613 : 1614 : _GLIBCXX20_CONSTEXPR 1615 : tuple& 1616 : operator=(__conditional_t<__assignable<_T1, _T2>(), 1617 : tuple&&, 1618 : __nonesuch&&> __in) 1619 : noexcept(__nothrow_assignable<_T1, _T2>()) 1620 : { 1621 : this->_M_assign(std::move(__in)); 1622 : return *this; 1623 : } 1624 : 1625 : template<typename _U1, typename _U2> 1626 : _GLIBCXX20_CONSTEXPR 1627 : __enable_if_t<__assignable<const _U1&, const _U2&>(), tuple&> 1628 : operator=(const tuple<_U1, _U2>& __in) 1629 : noexcept(__nothrow_assignable<const _U1&, const _U2&>()) 1630 : { 1631 : this->_M_assign(__in); 1632 : return *this; 1633 : } 1634 : 1635 : template<typename _U1, typename _U2> 1636 : _GLIBCXX20_CONSTEXPR 1637 : __enable_if_t<__assignable<_U1, _U2>(), tuple&> 1638 : operator=(tuple<_U1, _U2>&& __in) 1639 : noexcept(__nothrow_assignable<_U1, _U2>()) 1640 : { 1641 : this->_M_assign(std::move(__in)); 1642 : return *this; 1643 : } 1644 : 1645 : #if __cplusplus > 202002L 1646 : constexpr const tuple& 1647 : operator=(const tuple& __in) const 1648 : requires is_copy_assignable_v<const _T1> && is_copy_assignable_v<const _T2> 1649 : { 1650 : this->_M_assign(__in); 1651 : return *this; 1652 : } 1653 : 1654 : constexpr const tuple& 1655 : operator=(tuple&& __in) const 1656 : requires is_assignable_v<const _T1&, _T1> && is_assignable_v<const _T2, _T2> 1657 : { 1658 : this->_M_assign(std::move(__in)); 1659 : return *this; 1660 : } 1661 : 1662 : template<typename _U1, typename _U2> 1663 : constexpr const tuple& 1664 : operator=(const tuple<_U1, _U2>& __in) const 1665 : requires is_assignable_v<const _T1&, const _U1&> 1666 : && is_assignable_v<const _T2&, const _U2&> 1667 : { 1668 : this->_M_assign(__in); 1669 : return *this; 1670 : } 1671 : 1672 : template<typename _U1, typename _U2> 1673 : constexpr const tuple& 1674 : operator=(tuple<_U1, _U2>&& __in) const 1675 : requires is_assignable_v<const _T1&, _U1> 1676 : && is_assignable_v<const _T2&, _U2> 1677 : { 1678 : this->_M_assign(std::move(__in)); 1679 : return *this; 1680 : } 1681 : #endif // C++23 1682 : 1683 : template<typename _U1, typename _U2> 1684 : _GLIBCXX20_CONSTEXPR 1685 : __enable_if_t<__assignable<const _U1&, const _U2&>(), tuple&> 1686 : operator=(const pair<_U1, _U2>& __in) 1687 : noexcept(__nothrow_assignable<const _U1&, const _U2&>()) 1688 : { 1689 : this->_M_head(*this) = __in.first; 1690 : this->_M_tail(*this)._M_head(*this) = __in.second; 1691 : return *this; 1692 : } 1693 : 1694 : template<typename _U1, typename _U2> 1695 : _GLIBCXX20_CONSTEXPR 1696 : __enable_if_t<__assignable<_U1, _U2>(), tuple&> 1697 : operator=(pair<_U1, _U2>&& __in) 1698 : noexcept(__nothrow_assignable<_U1, _U2>()) 1699 : { 1700 : this->_M_head(*this) = std::forward<_U1>(__in.first); 1701 : this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second); 1702 : return *this; 1703 : } 1704 : 1705 : #if __cplusplus > 202002L 1706 : template<typename _U1, typename _U2> 1707 : constexpr const tuple& 1708 : operator=(const pair<_U1, _U2>& __in) const 1709 : requires is_assignable_v<const _T1&, const _U1&> 1710 : && is_assignable_v<const _T2&, const _U2&> 1711 : { 1712 : this->_M_head(*this) = __in.first; 1713 : this->_M_tail(*this)._M_head(*this) = __in.second; 1714 : return *this; 1715 : } 1716 : 1717 : template<typename _U1, typename _U2> 1718 : constexpr const tuple& 1719 : operator=(pair<_U1, _U2>&& __in) const 1720 : requires is_assignable_v<const _T1&, _U1> 1721 : && is_assignable_v<const _T2&, _U2> 1722 : { 1723 : this->_M_head(*this) = std::forward<_U1>(__in.first); 1724 : this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second); 1725 : return *this; 1726 : } 1727 : #endif // C++23 1728 : 1729 : _GLIBCXX20_CONSTEXPR 1730 : void 1731 : swap(tuple& __in) 1732 : noexcept(__and_<__is_nothrow_swappable<_T1>, 1733 : __is_nothrow_swappable<_T2>>::value) 1734 : { _Inherited::_M_swap(__in); } 1735 : 1736 : #if __cplusplus > 202002L 1737 : constexpr void 1738 : swap(const tuple& __in) const 1739 : noexcept(__and_v<__is_nothrow_swappable<const _T1>, 1740 : __is_nothrow_swappable<const _T2>>) 1741 : requires is_swappable_v<const _T1> && is_swappable_v<const _T2> 1742 : { _Inherited::_M_swap(__in); } 1743 : #endif // C++23 1744 : }; 1745 : 1746 : 1747 : /// class tuple_size 1748 : template<typename... _Elements> 1749 : struct tuple_size<tuple<_Elements...>> 1750 : : public integral_constant<size_t, sizeof...(_Elements)> { }; 1751 : 1752 : #if __cplusplus >= 201703L 1753 : template<typename... _Types> 1754 : inline constexpr size_t tuple_size_v<tuple<_Types...>> 1755 : = sizeof...(_Types); 1756 : 1757 : template<typename... _Types> 1758 : inline constexpr size_t tuple_size_v<const tuple<_Types...>> 1759 : = sizeof...(_Types); 1760 : #endif 1761 : 1762 : /// Trait to get the Ith element type from a tuple. 1763 : template<size_t __i, typename... _Types> 1764 : struct tuple_element<__i, tuple<_Types...>> 1765 : { 1766 : static_assert(__i < sizeof...(_Types), "tuple index must be in range"); 1767 : 1768 : using type = typename _Nth_type<__i, _Types...>::type; 1769 : }; 1770 : 1771 : template<size_t __i, typename _Head, typename... _Tail> 1772 : constexpr _Head& 1773 17270032 : __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 1774 17270032 : { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 1775 : 1776 : template<size_t __i, typename _Head, typename... _Tail> 1777 : constexpr const _Head& 1778 31996304 : __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 1779 31996304 : { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 1780 : 1781 : // Deleted overload to improve diagnostics for invalid indices 1782 : template<size_t __i, typename... _Types> 1783 : __enable_if_t<(__i >= sizeof...(_Types))> 1784 : __get_helper(const tuple<_Types...>&) = delete; 1785 : 1786 : /// Return a reference to the ith element of a tuple. 1787 : template<size_t __i, typename... _Elements> 1788 : constexpr __tuple_element_t<__i, tuple<_Elements...>>& 1789 15664298 : get(tuple<_Elements...>& __t) noexcept 1790 15664298 : { return std::__get_helper<__i>(__t); } 1791 : 1792 : /// Return a const reference to the ith element of a const tuple. 1793 : template<size_t __i, typename... _Elements> 1794 : constexpr const __tuple_element_t<__i, tuple<_Elements...>>& 1795 31996304 : get(const tuple<_Elements...>& __t) noexcept 1796 31996304 : { return std::__get_helper<__i>(__t); } 1797 : 1798 : /// Return an rvalue reference to the ith element of a tuple rvalue. 1799 : template<size_t __i, typename... _Elements> 1800 : constexpr __tuple_element_t<__i, tuple<_Elements...>>&& 1801 1605734 : get(tuple<_Elements...>&& __t) noexcept 1802 : { 1803 : typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type; 1804 1605734 : return std::forward<__element_type>(std::__get_helper<__i>(__t)); 1805 : } 1806 : 1807 : /// Return a const rvalue reference to the ith element of a const tuple rvalue. 1808 : template<size_t __i, typename... _Elements> 1809 : constexpr const __tuple_element_t<__i, tuple<_Elements...>>&& 1810 : get(const tuple<_Elements...>&& __t) noexcept 1811 : { 1812 : typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type; 1813 : return std::forward<const __element_type>(std::__get_helper<__i>(__t)); 1814 : } 1815 : 1816 : /// @cond undocumented 1817 : // Deleted overload chosen for invalid indices. 1818 : template<size_t __i, typename... _Elements> 1819 : constexpr __enable_if_t<(__i >= sizeof...(_Elements))> 1820 : get(const tuple<_Elements...>&) = delete; 1821 : /// @endcond 1822 : 1823 : #if __cplusplus >= 201402L 1824 : 1825 : #define __cpp_lib_tuples_by_type 201304L 1826 : 1827 : /// Return a reference to the unique element of type _Tp of a tuple. 1828 : template <typename _Tp, typename... _Types> 1829 : constexpr _Tp& 1830 : get(tuple<_Types...>& __t) noexcept 1831 : { 1832 : constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>(); 1833 : static_assert(__idx < sizeof...(_Types), 1834 : "the type T in std::get<T> must occur exactly once in the tuple"); 1835 : return std::__get_helper<__idx>(__t); 1836 : } 1837 : 1838 : /// Return a reference to the unique element of type _Tp of a tuple rvalue. 1839 : template <typename _Tp, typename... _Types> 1840 : constexpr _Tp&& 1841 : get(tuple<_Types...>&& __t) noexcept 1842 : { 1843 : constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>(); 1844 : static_assert(__idx < sizeof...(_Types), 1845 : "the type T in std::get<T> must occur exactly once in the tuple"); 1846 : return std::forward<_Tp>(std::__get_helper<__idx>(__t)); 1847 : } 1848 : 1849 : /// Return a const reference to the unique element of type _Tp of a tuple. 1850 : template <typename _Tp, typename... _Types> 1851 : constexpr const _Tp& 1852 : get(const tuple<_Types...>& __t) noexcept 1853 : { 1854 : constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>(); 1855 : static_assert(__idx < sizeof...(_Types), 1856 : "the type T in std::get<T> must occur exactly once in the tuple"); 1857 : return std::__get_helper<__idx>(__t); 1858 : } 1859 : 1860 : /// Return a const reference to the unique element of type _Tp of 1861 : /// a const tuple rvalue. 1862 : template <typename _Tp, typename... _Types> 1863 : constexpr const _Tp&& 1864 : get(const tuple<_Types...>&& __t) noexcept 1865 : { 1866 : constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>(); 1867 : static_assert(__idx < sizeof...(_Types), 1868 : "the type T in std::get<T> must occur exactly once in the tuple"); 1869 : return std::forward<const _Tp>(std::__get_helper<__idx>(__t)); 1870 : } 1871 : #endif 1872 : 1873 : // This class performs the comparison operations on tuples 1874 : template<typename _Tp, typename _Up, size_t __i, size_t __size> 1875 : struct __tuple_compare 1876 : { 1877 : static constexpr bool 1878 0 : __eq(const _Tp& __t, const _Up& __u) 1879 : { 1880 0 : return bool(std::get<__i>(__t) == std::get<__i>(__u)) 1881 0 : && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u); 1882 : } 1883 : 1884 : static constexpr bool 1885 : __less(const _Tp& __t, const _Up& __u) 1886 : { 1887 : return bool(std::get<__i>(__t) < std::get<__i>(__u)) 1888 : || (!bool(std::get<__i>(__u) < std::get<__i>(__t)) 1889 : && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u)); 1890 : } 1891 : }; 1892 : 1893 : template<typename _Tp, typename _Up, size_t __size> 1894 : struct __tuple_compare<_Tp, _Up, __size, __size> 1895 : { 1896 : static constexpr bool 1897 0 : __eq(const _Tp&, const _Up&) { return true; } 1898 : 1899 : static constexpr bool 1900 : __less(const _Tp&, const _Up&) { return false; } 1901 : }; 1902 : 1903 : template<typename... _TElements, typename... _UElements> 1904 : constexpr bool 1905 0 : operator==(const tuple<_TElements...>& __t, 1906 : const tuple<_UElements...>& __u) 1907 : { 1908 : static_assert(sizeof...(_TElements) == sizeof...(_UElements), 1909 : "tuple objects can only be compared if they have equal sizes."); 1910 : using __compare = __tuple_compare<tuple<_TElements...>, 1911 : tuple<_UElements...>, 1912 : 0, sizeof...(_TElements)>; 1913 0 : return __compare::__eq(__t, __u); 1914 : } 1915 : 1916 : #if __cpp_lib_three_way_comparison 1917 : template<typename _Cat, typename _Tp, typename _Up> 1918 : constexpr _Cat 1919 : __tuple_cmp(const _Tp&, const _Up&, index_sequence<>) 1920 : { return _Cat::equivalent; } 1921 : 1922 : template<typename _Cat, typename _Tp, typename _Up, 1923 : size_t _Idx0, size_t... _Idxs> 1924 : constexpr _Cat 1925 : __tuple_cmp(const _Tp& __t, const _Up& __u, 1926 : index_sequence<_Idx0, _Idxs...>) 1927 : { 1928 : auto __c 1929 : = __detail::__synth3way(std::get<_Idx0>(__t), std::get<_Idx0>(__u)); 1930 : if (__c != 0) 1931 : return __c; 1932 : return std::__tuple_cmp<_Cat>(__t, __u, index_sequence<_Idxs...>()); 1933 : } 1934 : 1935 : template<typename... _Tps, typename... _Ups> 1936 : constexpr 1937 : common_comparison_category_t<__detail::__synth3way_t<_Tps, _Ups>...> 1938 : operator<=>(const tuple<_Tps...>& __t, const tuple<_Ups...>& __u) 1939 : { 1940 : using _Cat 1941 : = common_comparison_category_t<__detail::__synth3way_t<_Tps, _Ups>...>; 1942 : return std::__tuple_cmp<_Cat>(__t, __u, index_sequence_for<_Tps...>()); 1943 : } 1944 : #else 1945 : template<typename... _TElements, typename... _UElements> 1946 : constexpr bool 1947 : operator<(const tuple<_TElements...>& __t, 1948 : const tuple<_UElements...>& __u) 1949 : { 1950 : static_assert(sizeof...(_TElements) == sizeof...(_UElements), 1951 : "tuple objects can only be compared if they have equal sizes."); 1952 : using __compare = __tuple_compare<tuple<_TElements...>, 1953 : tuple<_UElements...>, 1954 : 0, sizeof...(_TElements)>; 1955 : return __compare::__less(__t, __u); 1956 : } 1957 : 1958 : template<typename... _TElements, typename... _UElements> 1959 : constexpr bool 1960 : operator!=(const tuple<_TElements...>& __t, 1961 : const tuple<_UElements...>& __u) 1962 : { return !(__t == __u); } 1963 : 1964 : template<typename... _TElements, typename... _UElements> 1965 : constexpr bool 1966 : operator>(const tuple<_TElements...>& __t, 1967 : const tuple<_UElements...>& __u) 1968 : { return __u < __t; } 1969 : 1970 : template<typename... _TElements, typename... _UElements> 1971 : constexpr bool 1972 : operator<=(const tuple<_TElements...>& __t, 1973 : const tuple<_UElements...>& __u) 1974 : { return !(__u < __t); } 1975 : 1976 : template<typename... _TElements, typename... _UElements> 1977 : constexpr bool 1978 : operator>=(const tuple<_TElements...>& __t, 1979 : const tuple<_UElements...>& __u) 1980 : { return !(__t < __u); } 1981 : #endif // three_way_comparison 1982 : 1983 : // NB: DR 705. 1984 : /// Create a tuple containing copies of the arguments 1985 : template<typename... _Elements> 1986 : constexpr tuple<typename __decay_and_strip<_Elements>::__type...> 1987 : make_tuple(_Elements&&... __args) 1988 : { 1989 : typedef tuple<typename __decay_and_strip<_Elements>::__type...> 1990 : __result_type; 1991 : return __result_type(std::forward<_Elements>(__args)...); 1992 : } 1993 : 1994 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 1995 : // 2275. Why is forward_as_tuple not constexpr? 1996 : /// Create a tuple of lvalue or rvalue references to the arguments 1997 : template<typename... _Elements> 1998 : constexpr tuple<_Elements&&...> 1999 3129356 : forward_as_tuple(_Elements&&... __args) noexcept 2000 3129356 : { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); } 2001 : 2002 : // Declarations of std::array and its std::get overloads, so that 2003 : // std::tuple_cat can use them if <tuple> is included before <array>. 2004 : 2005 : template<typename _Tp, size_t _Nm> struct array; 2006 : 2007 : template<size_t _Int, typename _Tp, size_t _Nm> 2008 : constexpr _Tp& 2009 : get(array<_Tp, _Nm>&) noexcept; 2010 : 2011 : template<size_t _Int, typename _Tp, size_t _Nm> 2012 : constexpr _Tp&& 2013 : get(array<_Tp, _Nm>&&) noexcept; 2014 : 2015 : template<size_t _Int, typename _Tp, size_t _Nm> 2016 : constexpr const _Tp& 2017 : get(const array<_Tp, _Nm>&) noexcept; 2018 : 2019 : template<size_t _Int, typename _Tp, size_t _Nm> 2020 : constexpr const _Tp&& 2021 : get(const array<_Tp, _Nm>&&) noexcept; 2022 : 2023 : /// @cond undocumented 2024 : template<size_t, typename, typename, size_t> 2025 : struct __make_tuple_impl; 2026 : 2027 : template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm> 2028 : struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm> 2029 : : __make_tuple_impl<_Idx + 1, 2030 : tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>, 2031 : _Tuple, _Nm> 2032 : { }; 2033 : 2034 : template<size_t _Nm, typename _Tuple, typename... _Tp> 2035 : struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm> 2036 : { 2037 : typedef tuple<_Tp...> __type; 2038 : }; 2039 : 2040 : template<typename _Tuple> 2041 : struct __do_make_tuple 2042 : : __make_tuple_impl<0, tuple<>, _Tuple, tuple_size<_Tuple>::value> 2043 : { }; 2044 : 2045 : // Returns the std::tuple equivalent of a tuple-like type. 2046 : template<typename _Tuple> 2047 : struct __make_tuple 2048 : : public __do_make_tuple<__remove_cvref_t<_Tuple>> 2049 : { }; 2050 : 2051 : // Combines several std::tuple's into a single one. 2052 : template<typename...> 2053 : struct __combine_tuples; 2054 : 2055 : template<> 2056 : struct __combine_tuples<> 2057 : { 2058 : typedef tuple<> __type; 2059 : }; 2060 : 2061 : template<typename... _Ts> 2062 : struct __combine_tuples<tuple<_Ts...>> 2063 : { 2064 : typedef tuple<_Ts...> __type; 2065 : }; 2066 : 2067 : template<typename... _T1s, typename... _T2s, typename... _Rem> 2068 : struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...> 2069 : { 2070 : typedef typename __combine_tuples<tuple<_T1s..., _T2s...>, 2071 : _Rem...>::__type __type; 2072 : }; 2073 : 2074 : // Computes the result type of tuple_cat given a set of tuple-like types. 2075 : template<typename... _Tpls> 2076 : struct __tuple_cat_result 2077 : { 2078 : typedef typename __combine_tuples 2079 : <typename __make_tuple<_Tpls>::__type...>::__type __type; 2080 : }; 2081 : 2082 : // Helper to determine the index set for the first tuple-like 2083 : // type of a given set. 2084 : template<typename...> 2085 : struct __make_1st_indices; 2086 : 2087 : template<> 2088 : struct __make_1st_indices<> 2089 : { 2090 : typedef _Index_tuple<> __type; 2091 : }; 2092 : 2093 : template<typename _Tp, typename... _Tpls> 2094 : struct __make_1st_indices<_Tp, _Tpls...> 2095 : { 2096 : typedef typename _Build_index_tuple<tuple_size< 2097 : typename remove_reference<_Tp>::type>::value>::__type __type; 2098 : }; 2099 : 2100 : // Performs the actual concatenation by step-wise expanding tuple-like 2101 : // objects into the elements, which are finally forwarded into the 2102 : // result tuple. 2103 : template<typename _Ret, typename _Indices, typename... _Tpls> 2104 : struct __tuple_concater; 2105 : 2106 : template<typename _Ret, size_t... _Is, typename _Tp, typename... _Tpls> 2107 : struct __tuple_concater<_Ret, _Index_tuple<_Is...>, _Tp, _Tpls...> 2108 : { 2109 : template<typename... _Us> 2110 : static constexpr _Ret 2111 : _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us) 2112 : { 2113 : typedef typename __make_1st_indices<_Tpls...>::__type __idx; 2114 : typedef __tuple_concater<_Ret, __idx, _Tpls...> __next; 2115 : return __next::_S_do(std::forward<_Tpls>(__tps)..., 2116 : std::forward<_Us>(__us)..., 2117 : std::get<_Is>(std::forward<_Tp>(__tp))...); 2118 : } 2119 : }; 2120 : 2121 : template<typename _Ret> 2122 : struct __tuple_concater<_Ret, _Index_tuple<>> 2123 : { 2124 : template<typename... _Us> 2125 : static constexpr _Ret 2126 : _S_do(_Us&&... __us) 2127 : { 2128 : return _Ret(std::forward<_Us>(__us)...); 2129 : } 2130 : }; 2131 : 2132 : template<typename... _Tps> 2133 : struct __is_tuple_like_impl<tuple<_Tps...>> : true_type 2134 : { }; 2135 : /// @endcond 2136 : 2137 : /// Create a `tuple` containing all elements from multiple tuple-like objects 2138 : template<typename... _Tpls, typename = typename 2139 : enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type> 2140 : constexpr auto 2141 : tuple_cat(_Tpls&&... __tpls) 2142 : -> typename __tuple_cat_result<_Tpls...>::__type 2143 : { 2144 : typedef typename __tuple_cat_result<_Tpls...>::__type __ret; 2145 : typedef typename __make_1st_indices<_Tpls...>::__type __idx; 2146 : typedef __tuple_concater<__ret, __idx, _Tpls...> __concater; 2147 : return __concater::_S_do(std::forward<_Tpls>(__tpls)...); 2148 : } 2149 : 2150 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 2151 : // 2301. Why is tie not constexpr? 2152 : /// Return a tuple of lvalue references bound to the arguments 2153 : template<typename... _Elements> 2154 : constexpr tuple<_Elements&...> 2155 286 : tie(_Elements&... __args) noexcept 2156 286 : { return tuple<_Elements&...>(__args...); } 2157 : 2158 : /// Exchange the values of two tuples 2159 : template<typename... _Elements> 2160 : _GLIBCXX20_CONSTEXPR 2161 : inline 2162 : #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 2163 : // Constrained free swap overload, see p0185r1 2164 : typename enable_if<__and_<__is_swappable<_Elements>...>::value 2165 : >::type 2166 : #else 2167 : void 2168 : #endif 2169 : swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y) 2170 : noexcept(noexcept(__x.swap(__y))) 2171 : { __x.swap(__y); } 2172 : 2173 : #if __cplusplus > 202002L 2174 : template<typename... _Elements> 2175 : requires (is_swappable_v<const _Elements> && ...) 2176 : constexpr void 2177 : swap(const tuple<_Elements...>& __x, const tuple<_Elements...>& __y) 2178 : noexcept(noexcept(__x.swap(__y))) 2179 : { __x.swap(__y); } 2180 : #endif // C++23 2181 : 2182 : #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 2183 : /// Exchange the values of two const tuples (if const elements can be swapped) 2184 : template<typename... _Elements> 2185 : _GLIBCXX20_CONSTEXPR 2186 : typename enable_if<!__and_<__is_swappable<_Elements>...>::value>::type 2187 : swap(tuple<_Elements...>&, tuple<_Elements...>&) = delete; 2188 : #endif 2189 : 2190 : // A class (and instance) which can be used in 'tie' when an element 2191 : // of a tuple is not required. 2192 : // _GLIBCXX14_CONSTEXPR 2193 : // 2933. PR for LWG 2773 could be clearer 2194 : struct _Swallow_assign 2195 : { 2196 : template<class _Tp> 2197 : _GLIBCXX14_CONSTEXPR const _Swallow_assign& 2198 : operator=(const _Tp&) const 2199 : { return *this; } 2200 : }; 2201 : 2202 : // _GLIBCXX_RESOLVE_LIB_DEFECTS 2203 : // 2773. Making std::ignore constexpr 2204 : /** Used with `std::tie` to ignore an element of a tuple 2205 : * 2206 : * When using `std::tie` to assign the elements of a tuple to variables, 2207 : * unwanted elements can be ignored by using `std::ignore`. For example: 2208 : * 2209 : * ``` 2210 : * int x, y; 2211 : * std::tie(x, std::ignore, y) = std::make_tuple(1, 2, 3); 2212 : * ``` 2213 : * 2214 : * This assignment will perform `x=1; std::ignore=2; y=3;` which results 2215 : * in the second element being ignored. 2216 : * 2217 : * @since C++11 2218 : */ 2219 : _GLIBCXX17_INLINE constexpr _Swallow_assign ignore{}; 2220 : 2221 : /// Partial specialization for tuples 2222 : template<typename... _Types, typename _Alloc> 2223 : struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { }; 2224 : 2225 : // See stl_pair.h... 2226 : /** "piecewise construction" using a tuple of arguments for each member. 2227 : * 2228 : * @param __first Arguments for the first member of the pair. 2229 : * @param __second Arguments for the second member of the pair. 2230 : * 2231 : * The elements of each tuple will be used as the constructor arguments 2232 : * for the data members of the pair. 2233 : */ 2234 : template<class _T1, class _T2> 2235 : template<typename... _Args1, typename... _Args2> 2236 : _GLIBCXX20_CONSTEXPR 2237 : inline 2238 10538856 : pair<_T1, _T2>:: 2239 : pair(piecewise_construct_t, 2240 : tuple<_Args1...> __first, tuple<_Args2...> __second) 2241 : : pair(__first, __second, 2242 : typename _Build_index_tuple<sizeof...(_Args1)>::__type(), 2243 10538856 : typename _Build_index_tuple<sizeof...(_Args2)>::__type()) 2244 10538856 : { } 2245 : 2246 : template<class _T1, class _T2> 2247 : template<typename... _Args1, size_t... _Indexes1, 2248 : typename... _Args2, size_t... _Indexes2> 2249 : _GLIBCXX20_CONSTEXPR inline 2250 10538856 : pair<_T1, _T2>:: 2251 : pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2, 2252 : _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>) 2253 10538856 : : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...), 2254 10538856 : second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...) 2255 10538856 : { } 2256 : 2257 : #if __cplusplus >= 201703L 2258 : 2259 : // Unpack a std::tuple into a type trait and use its value. 2260 : // For cv std::tuple<_Up> the result is _Trait<_Tp, cv _Up...>::value. 2261 : // For cv std::tuple<_Up>& the result is _Trait<_Tp, cv _Up&...>::value. 2262 : // Otherwise the result is false (because we don't know if std::get throws). 2263 : template<template<typename...> class _Trait, typename _Tp, typename _Tuple> 2264 : inline constexpr bool __unpack_std_tuple = false; 2265 : 2266 : template<template<typename...> class _Trait, typename _Tp, typename... _Up> 2267 : inline constexpr bool __unpack_std_tuple<_Trait, _Tp, tuple<_Up...>> 2268 : = _Trait<_Tp, _Up...>::value; 2269 : 2270 : template<template<typename...> class _Trait, typename _Tp, typename... _Up> 2271 : inline constexpr bool __unpack_std_tuple<_Trait, _Tp, tuple<_Up...>&> 2272 : = _Trait<_Tp, _Up&...>::value; 2273 : 2274 : template<template<typename...> class _Trait, typename _Tp, typename... _Up> 2275 : inline constexpr bool __unpack_std_tuple<_Trait, _Tp, const tuple<_Up...>> 2276 : = _Trait<_Tp, const _Up...>::value; 2277 : 2278 : template<template<typename...> class _Trait, typename _Tp, typename... _Up> 2279 : inline constexpr bool __unpack_std_tuple<_Trait, _Tp, const tuple<_Up...>&> 2280 : = _Trait<_Tp, const _Up&...>::value; 2281 : 2282 : # define __cpp_lib_apply 201603L 2283 : 2284 : template <typename _Fn, typename _Tuple, size_t... _Idx> 2285 : constexpr decltype(auto) 2286 : __apply_impl(_Fn&& __f, _Tuple&& __t, index_sequence<_Idx...>) 2287 : { 2288 : return std::__invoke(std::forward<_Fn>(__f), 2289 : std::get<_Idx>(std::forward<_Tuple>(__t))...); 2290 : } 2291 : 2292 : template <typename _Fn, typename _Tuple> 2293 : constexpr decltype(auto) 2294 : apply(_Fn&& __f, _Tuple&& __t) 2295 : noexcept(__unpack_std_tuple<is_nothrow_invocable, _Fn, _Tuple>) 2296 : { 2297 : using _Indices 2298 : = make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>; 2299 : return std::__apply_impl(std::forward<_Fn>(__f), 2300 : std::forward<_Tuple>(__t), 2301 : _Indices{}); 2302 : } 2303 : 2304 : #define __cpp_lib_make_from_tuple 201606L 2305 : 2306 : template <typename _Tp, typename _Tuple, size_t... _Idx> 2307 : constexpr _Tp 2308 : __make_from_tuple_impl(_Tuple&& __t, index_sequence<_Idx...>) 2309 : { return _Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...); } 2310 : 2311 : template <typename _Tp, typename _Tuple> 2312 : constexpr _Tp 2313 : make_from_tuple(_Tuple&& __t) 2314 : noexcept(__unpack_std_tuple<is_nothrow_constructible, _Tp, _Tuple>) 2315 : { 2316 : constexpr size_t __n = tuple_size_v<remove_reference_t<_Tuple>>; 2317 : #if __has_builtin(__reference_constructs_from_temporary) 2318 : if constexpr (__n == 1) 2319 : { 2320 : using _Elt = decltype(std::get<0>(std::declval<_Tuple>())); 2321 : static_assert(!__reference_constructs_from_temporary(_Tp, _Elt)); 2322 : } 2323 : #endif 2324 : return __make_from_tuple_impl<_Tp>(std::forward<_Tuple>(__t), 2325 : make_index_sequence<__n>{}); 2326 : } 2327 : #endif // C++17 2328 : 2329 : #if __cplusplus > 202002L 2330 : template<typename... _TTypes, typename... _UTypes, 2331 : template<typename> class _TQual, template<typename> class _UQual> 2332 : requires requires { typename tuple<common_reference_t<_TQual<_TTypes>, _UQual<_UTypes>>...>; } 2333 : struct basic_common_reference<tuple<_TTypes...>, tuple<_UTypes...>, _TQual, _UQual> 2334 : { using type = tuple<common_reference_t<_TQual<_TTypes>, _UQual<_UTypes>>...>; }; 2335 : 2336 : template<typename... _TTypes, typename... _UTypes> 2337 : requires requires { typename tuple<common_type_t<_TTypes, _UTypes>...>; } 2338 : struct common_type<tuple<_TTypes...>, tuple<_UTypes...>> 2339 : { using type = tuple<common_type_t<_TTypes, _UTypes>...>; }; 2340 : #endif // C++23 2341 : 2342 : /// @} 2343 : 2344 : _GLIBCXX_END_NAMESPACE_VERSION 2345 : } // namespace std 2346 : 2347 : #endif // C++11 2348 : 2349 : #endif // _GLIBCXX_TUPLE |
![]() |
Generated by: LCOV version 2.0-1 |
</html>