Where Online Learning is simpler!
The C and C++ Include Header Files
/usr/include/c++/13/tuple
$ cat -n /usr/include/c++/13/tuple 1 //
-*- 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 //
. 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
36 #else 37 38 #include
// for std::pair 39 #include
// for std::allocator_arg_t 40 #include
// for std::tuple_size etc. 41 #include
// for std::__invoke 42 #if __cplusplus > 201703L 43 # include
44 # include
// 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
58 class tuple; 59 60 template
61 struct __is_empty_non_tuple : is_empty<_Tp> { }; 62 63 // Using EBO for elements that are tuples causes ambiguous base errors. 64 template
65 struct __is_empty_non_tuple
> : false_type { }; 66 67 // Use the Empty Base-class Optimization for empty, non-final types. 68 template
69 using __empty_not_final 70 = __conditional_t<__is_final(_Tp), false_type, 71 __is_empty_non_tuple<_Tp>>; 72 73 template
::value> 75 struct _Head_base; 76 77 #if __has_cpp_attribute(__no_unique_address__) 78 template
79 struct _Head_base<_Idx, _Head, true> 80 { 81 constexpr _Head_base() 82 : _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
91 constexpr _Head_base(_UHead&& __h) 92 : _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
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
104 _GLIBCXX20_CONSTEXPR 105 _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a) 106 : _M_head_impl(*__a._M_a) { } 107 108 template
109 _GLIBCXX20_CONSTEXPR 110 _Head_base(__uses_alloc0, _UHead&& __uhead) 111 : _M_head_impl(std::forward<_UHead>(__uhead)) { } 112 113 template
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
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 _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
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
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
155 _GLIBCXX20_CONSTEXPR 156 _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a) 157 : _Head(allocator_arg, *__a._M_a) { } 158 159 template
160 _GLIBCXX20_CONSTEXPR 161 _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a) 162 : _Head(*__a._M_a) { } 163 164 template
165 _GLIBCXX20_CONSTEXPR 166 _Head_base(__uses_alloc0, _UHead&& __uhead) 167 : _Head(std::forward<_UHead>(__uhead)) { } 168 169 template
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
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
188 struct _Head_base<_Idx, _Head, false> 189 { 190 constexpr _Head_base() 191 : _M_head_impl() { } 192 193 constexpr _Head_base(const _Head& __h) 194 : _M_head_impl(__h) { } 195 196 constexpr _Head_base(const _Head_base&) = default; 197 constexpr _Head_base(_Head_base&&) = default; 198 199 template
200 constexpr _Head_base(_UHead&& __h) 201 : _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
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
213 _GLIBCXX20_CONSTEXPR 214 _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a) 215 : _M_head_impl(*__a._M_a) { } 216 217 template
218 _GLIBCXX20_CONSTEXPR 219 _Head_base(__uses_alloc0, _UHead&& __uhead) 220 : _M_head_impl(std::forward<_UHead>(__uhead)) { } 221 222 template
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
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 _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; } 235 236 static constexpr const _Head& 237 _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
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
259 struct _Tuple_impl<_Idx, _Head, _Tail...> 260 : public _Tuple_impl<_Idx + 1, _Tail...>, 261 private _Head_base<_Idx, _Head> 262 { 263 template
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 _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } 270 271 static constexpr const _Head& 272 _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } 273 274 static constexpr _Inherited& 275 _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 constexpr _Tuple_impl() 281 : _Inherited(), _Base() { } 282 283 explicit constexpr 284 _Tuple_impl(const _Head& __head, const _Tail&... __tail) 285 : _Inherited(__tail...), _Base(__head) 286 { } 287 288 template
> 290 explicit constexpr 291 _Tuple_impl(_UHead&& __head, _UTail&&... __tail) 292 : _Inherited(std::forward<_UTail>(__tail)...), 293 _Base(std::forward<_UHead>(__head)) 294 { } 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 _Tuple_impl(_Tuple_impl&&) = default; 303 304 template
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
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
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
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
334 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) 335 { } 336 #endif // C++23 337 338 template
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
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
> 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
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
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
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
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
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
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
420 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) 421 { } 422 #endif // C++23 423 424 template
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
435 _GLIBCXX20_CONSTEXPR 436 void 437 _M_assign(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) 438 { 439 _M_head(*this) = std::forward<_UHead> 440 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)); 441 _M_tail(*this)._M_assign( 442 std::move(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))); 443 } 444 445 #if __cplusplus > 202002L 446 template
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
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
489 struct _Tuple_impl<_Idx, _Head> 490 : private _Head_base<_Idx, _Head> 491 { 492 template
friend struct _Tuple_impl; 493 494 typedef _Head_base<_Idx, _Head> _Base; 495 496 static constexpr _Head& 497 _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } 498 499 static constexpr const _Head& 500 _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } 501 502 constexpr 503 _Tuple_impl() 504 : _Base() { } 505 506 explicit constexpr 507 _Tuple_impl(const _Head& __head) 508 : _Base(__head) 509 { } 510 511 template
512 explicit constexpr 513 _Tuple_impl(_UHead&& __head) 514 : _Base(std::forward<_UHead>(__head)) 515 { } 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 _Tuple_impl(_Tuple_impl&& __in) 528 noexcept(is_nothrow_move_constructible<_Head>::value) 529 : _Base(static_cast<_Base&&>(__in)) 530 { } 531 #endif 532 533 template
534 constexpr 535 _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in) 536 : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in)) 537 { } 538 539 template
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
547 constexpr 548 _Tuple_impl(_Tuple_impl<_Idx, _UHead>& __in) 549 : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in)) 550 { } 551 552 template
553 constexpr 554 _Tuple_impl(const _Tuple_impl<_Idx, _UHead>&& __in) 555 : _Base(std::forward
(_Tuple_impl<_Idx, _UHead>::_M_head(__in))) 556 { } 557 #endif // C++23 558 559 template
560 _GLIBCXX20_CONSTEXPR 561 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a) 562 : _Base(__tag, __use_alloc<_Head>(__a)) 563 { } 564 565 template
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
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
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
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
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
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
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
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
(_Tuple_impl<_Idx, _UHead>::_M_head(__in))) 626 { } 627 #endif // C++23 628 629 template
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
638 _GLIBCXX20_CONSTEXPR 639 void 640 _M_assign(_Tuple_impl<_Idx, _UHead>&& __in) 641 { 642 _M_head(*this) 643 = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)); 644 } 645 646 #if __cplusplus > 202002L 647 template
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
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
685 struct _TupleConstraints 686 { 687 template
688 using __constructible = __and_
...>; 689 690 template
691 using __convertible = __and_
...>; 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
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
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_
... 718 >::value; 719 } 720 721 static constexpr bool __is_explicitly_default_constructible() 722 { 723 return __and_
..., 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
733 struct _TupleConstraints
734 { 735 template
736 static constexpr bool __is_implicitly_constructible() 737 { return false; } 738 739 template
740 static constexpr bool __is_explicitly_constructible() 741 { return false; } 742 }; 743 744 /// Primary class template, tuple 745 template
746 class tuple : public _Tuple_impl<0, _Elements...> 747 { 748 typedef _Tuple_impl<0, _Elements...> _Inherited; 749 750 template
751 using _TCC = _TupleConstraints<_Cond, _Elements...>; 752 753 // Constraint for non-explicit default constructor 754 template
755 using _ImplicitDefaultCtor = __enable_if_t< 756 _TCC<_Dummy>::__is_implicitly_default_constructible(), 757 bool>; 758 759 // Constraint for explicit default constructor 760 template
761 using _ExplicitDefaultCtor = __enable_if_t< 762 _TCC<_Dummy>::__is_explicitly_default_constructible(), 763 bool>; 764 765 // Constraint for non-explicit constructors 766 template
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
773 using _ExplicitCtor = __enable_if_t< 774 _TCC<_Cond>::template __is_explicitly_constructible<_Args...>(), 775 bool>; 776 777 template
778 static constexpr 779 __enable_if_t
780 __assignable() 781 { return __and_
...>::value; } 782 783 // Condition for noexcept-specifier of an assignment operator. 784 template
785 static constexpr bool __nothrow_assignable() 786 { 787 return 788 __and_
...>::value; 789 } 790 791 // Condition for noexcept-specifier of a constructor. 792 template
793 static constexpr bool __nothrow_constructible() 794 { 795 return 796 __and_
...>::value; 797 } 798 799 // Constraint for tuple(_UTypes&&...) where sizeof...(_UTypes) == 1. 800 template
801 static constexpr bool __valid_args() 802 { 803 return sizeof...(_Elements) == 1 804 && !is_same
>::value; 805 } 806 807 // Constraint for tuple(_UTypes&&...) where sizeof...(_UTypes) > 1. 808 template
809 static constexpr bool __valid_args() 810 { return (sizeof...(_Tail) + 2) == sizeof...(_Elements); } 811 812 /* Constraint for constructors with a tuple
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
, is_constructible_v
, 819 * and is_same_v
are all false. 820 */ 821 template
> 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
829 struct _UseOtherCtor<_Tuple, tuple<_Tp>, tuple<_Up>> 830 : __or_
, 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
835 struct _UseOtherCtor<_Tuple, tuple<_Tp>, tuple<_Tp>> 836 : true_type 837 { }; 838 839 // Return true iff sizeof...(Types) == 1 && tuple_size_v
== 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
843 static constexpr bool __use_other_ctor() 844 { return _UseOtherCtor<_Tuple>::value; } 845 846 #if __cplusplus > 202002L 847 template
848 static constexpr bool __constructible 849 = _TCC
::template __constructible<_Args...>::value; 850 851 template
852 static constexpr bool __convertible 853 = _TCC
::template __convertible<_Args...>::value; 854 #endif // C++23 855 856 public: 857 template
::value> = true> 859 constexpr 860 tuple() 861 noexcept(__and_
...>::value) 862 : _Inherited() { } 863 864 template
::value> = false> 866 explicit constexpr 867 tuple() 868 noexcept(__and_
...>::value) 869 : _Inherited() { } 870 871 template
= 1), 872 _ImplicitCtor<_NotEmpty, const _Elements&...> = true> 873 constexpr 874 tuple(const _Elements&... __elements) 875 noexcept(__nothrow_constructible
()) 876 : _Inherited(__elements...) { } 877 878 template
= 1), 879 _ExplicitCtor<_NotEmpty, const _Elements&...> = false> 880 explicit constexpr 881 tuple(const _Elements&... __elements) 882 noexcept(__nothrow_constructible
()) 883 : _Inherited(__elements...) { } 884 885 template
(), 887 _ImplicitCtor<_Valid, _UElements...> = true> 888 constexpr 889 tuple(_UElements&&... __elements) 890 noexcept(__nothrow_constructible<_UElements...>()) 891 : _Inherited(std::forward<_UElements>(__elements)...) { } 892 893 template
(), 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 constexpr tuple(tuple&&) = default; 904 905 template
&>(), 908 _ImplicitCtor<_Valid, const _UElements&...> = true> 909 constexpr 910 tuple(const tuple<_UElements...>& __in) 911 noexcept(__nothrow_constructible
()) 912 : _Inherited(static_cast
&>(__in)) 913 { } 914 915 template
&>(), 918 _ExplicitCtor<_Valid, const _UElements&...> = false> 919 explicit constexpr 920 tuple(const tuple<_UElements...>& __in) 921 noexcept(__nothrow_constructible
()) 922 : _Inherited(static_cast
&>(__in)) 923 { } 924 925 template
&&>(), 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
&&>(), 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
945 requires (sizeof...(_Elements) == sizeof...(_UElements)) 946 && (!__use_other_ctor
&>()) 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
956 requires (sizeof...(_Elements) == sizeof...(_UElements)) 957 && (!__use_other_ctor
&&>()) 958 && __constructible
959 explicit(!__convertible
) 960 constexpr 961 tuple(const tuple<_UElements...>&& __in) 962 noexcept(__nothrow_constructible
()) 963 : _Inherited(static_cast
&&>(__in)) { } 964 #endif // C++23 965 966 // Allocator-extended constructors. 967 968 template
::value> = true> 970 _GLIBCXX20_CONSTEXPR 971 tuple(allocator_arg_t __tag, const _Alloc& __a) 972 : _Inherited(__tag, __a) { } 973 974 template
::value> = false> 976 _GLIBCXX20_CONSTEXPR 977 explicit 978 tuple(allocator_arg_t __tag, const _Alloc& __a) 979 : _Inherited(__tag, __a) { } 980 981 template
= 1), 982 _ImplicitCtor<_NotEmpty, const _Elements&...> = true> 983 _GLIBCXX20_CONSTEXPR 984 tuple(allocator_arg_t __tag, const _Alloc& __a, 985 const _Elements&... __elements) 986 : _Inherited(__tag, __a, __elements...) { } 987 988 template
= 1), 989 _ExplicitCtor<_NotEmpty, const _Elements&...> = false> 990 _GLIBCXX20_CONSTEXPR 991 explicit 992 tuple(allocator_arg_t __tag, const _Alloc& __a, 993 const _Elements&... __elements) 994 : _Inherited(__tag, __a, __elements...) { } 995 996 template
(), 998 _ImplicitCtor<_Valid, _UElements...> = true> 999 _GLIBCXX20_CONSTEXPR 1000 tuple(allocator_arg_t __tag, const _Alloc& __a, 1001 _UElements&&... __elements) 1002 : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...) 1003 { } 1004 1005 template
(), 1007 _ExplicitCtor<_Valid, _UElements...> = false> 1008 _GLIBCXX20_CONSTEXPR 1009 explicit 1010 tuple(allocator_arg_t __tag, const _Alloc& __a, 1011 _UElements&&... __elements) 1012 : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...) 1013 { } 1014 1015 template
1016 _GLIBCXX20_CONSTEXPR 1017 tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) 1018 : _Inherited(__tag, __a, static_cast
(__in)) { } 1019 1020 template
1021 _GLIBCXX20_CONSTEXPR 1022 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) 1023 : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { } 1024 1025 template
&>(), 1028 _ImplicitCtor<_Valid, const _UElements&...> = true> 1029 _GLIBCXX20_CONSTEXPR 1030 tuple(allocator_arg_t __tag, const _Alloc& __a, 1031 const tuple<_UElements...>& __in) 1032 : _Inherited(__tag, __a, 1033 static_cast
&>(__in)) 1034 { } 1035 1036 template
&>(), 1039 _ExplicitCtor<_Valid, const _UElements&...> = false> 1040 _GLIBCXX20_CONSTEXPR 1041 explicit 1042 tuple(allocator_arg_t __tag, const _Alloc& __a, 1043 const tuple<_UElements...>& __in) 1044 : _Inherited(__tag, __a, 1045 static_cast
&>(__in)) 1046 { } 1047 1048 template
&&>(), 1051 _ImplicitCtor<_Valid, _UElements...> = true> 1052 _GLIBCXX20_CONSTEXPR 1053 tuple(allocator_arg_t __tag, const _Alloc& __a, 1054 tuple<_UElements...>&& __in) 1055 : _Inherited(__tag, __a, 1056 static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) 1057 { } 1058 1059 template
&&>(), 1062 _ExplicitCtor<_Valid, _UElements...> = false> 1063 _GLIBCXX20_CONSTEXPR 1064 explicit 1065 tuple(allocator_arg_t __tag, const _Alloc& __a, 1066 tuple<_UElements...>&& __in) 1067 : _Inherited(__tag, __a, 1068 static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) 1069 { } 1070 1071 #if __cplusplus > 202002L 1072 template
1073 requires (sizeof...(_Elements) == sizeof...(_UElements)) 1074 && (!__use_other_ctor
&>()) 1075 && __constructible<_UElements&...> 1076 explicit(!__convertible<_UElements&...>) 1077 constexpr 1078 tuple(allocator_arg_t __tag, const _Alloc& __a, 1079 tuple<_UElements...>& __in) 1080 : _Inherited(__tag, __a, 1081 static_cast<_Tuple_impl<0, _UElements...>&>(__in)) 1082 { } 1083 1084 template
1085 requires (sizeof...(_Elements) == sizeof...(_UElements)) 1086 && (!__use_other_ctor
>()) 1087 && __constructible
1088 explicit(!__convertible
) 1089 constexpr 1090 tuple(allocator_arg_t __tag, const _Alloc& __a, 1091 const tuple<_UElements...>&& __in) 1092 : _Inherited(__tag, __a, 1093 static_cast
&&>(__in)) 1094 { } 1095 #endif // C++23 1096 1097 // tuple assignment 1098 1099 _GLIBCXX20_CONSTEXPR 1100 tuple& 1101 operator=(__conditional_t<__assignable
(), 1102 const tuple&, 1103 const __nonesuch&> __in) 1104 noexcept(__nothrow_assignable
()) 1105 { 1106 this->_M_assign(__in); 1107 return *this; 1108 } 1109 1110 _GLIBCXX20_CONSTEXPR 1111 tuple& 1112 operator=(__conditional_t<__assignable<_Elements...>(), 1113 tuple&&, 1114 __nonesuch&&> __in) 1115 noexcept(__nothrow_assignable<_Elements...>()) 1116 { 1117 this->_M_assign(std::move(__in)); 1118 return *this; 1119 } 1120 1121 template
1122 _GLIBCXX20_CONSTEXPR 1123 __enable_if_t<__assignable
(), tuple&> 1124 operator=(const tuple<_UElements...>& __in) 1125 noexcept(__nothrow_assignable
()) 1126 { 1127 this->_M_assign(__in); 1128 return *this; 1129 } 1130 1131 template
1132 _GLIBCXX20_CONSTEXPR 1133 __enable_if_t<__assignable<_UElements...>(), tuple&> 1134 operator=(tuple<_UElements...>&& __in) 1135 noexcept(__nothrow_assignable<_UElements...>()) 1136 { 1137 this->_M_assign(std::move(__in)); 1138 return *this; 1139 } 1140 1141 #if __cplusplus > 202002L 1142 constexpr const tuple& 1143 operator=(const tuple& __in) const 1144 requires (is_copy_assignable_v
&& ...) 1145 { 1146 this->_M_assign(__in); 1147 return *this; 1148 } 1149 1150 constexpr const tuple& 1151 operator=(tuple&& __in) const 1152 requires (is_assignable_v
&& ...) 1153 { 1154 this->_M_assign(std::move(__in)); 1155 return *this; 1156 } 1157 1158 template
1159 constexpr const tuple& 1160 operator=(const tuple<_UElements...>& __in) const 1161 requires (sizeof...(_Elements) == sizeof...(_UElements)) 1162 && (is_assignable_v
&& ...) 1163 { 1164 this->_M_assign(__in); 1165 return *this; 1166 } 1167 1168 template
1169 constexpr const tuple& 1170 operator=(tuple<_UElements...>&& __in) const 1171 requires (sizeof...(_Elements) == sizeof...(_UElements)) 1172 && (is_assignable_v
&& ...) 1173 { 1174 this->_M_assign(std::move(__in)); 1175 return *this; 1176 } 1177 #endif // C++23 1178 1179 // tuple swap 1180 _GLIBCXX20_CONSTEXPR 1181 void 1182 swap(tuple& __in) 1183 noexcept(__and_<__is_nothrow_swappable<_Elements>...>::value) 1184 { _Inherited::_M_swap(__in); } 1185 1186 #if __cplusplus > 202002L 1187 // As an extension, we constrain the const swap member function in order 1188 // to continue accepting explicit instantiation of tuples whose elements 1189 // are not all const swappable. Without this constraint, such an 1190 // explicit instantiation would also instantiate the ill-formed body of 1191 // this function and yield a hard error. This constraint shouldn't 1192 // affect the behavior of valid programs. 1193 constexpr void 1194 swap(const tuple& __in) const 1195 noexcept(__and_v<__is_nothrow_swappable
...>) 1196 requires (is_swappable_v
&& ...) 1197 { _Inherited::_M_swap(__in); } 1198 #endif // C++23 1199 }; 1200 1201 #if __cpp_deduction_guides >= 201606 1202 template
1203 tuple(_UTypes...) -> tuple<_UTypes...>; 1204 template
1205 tuple(pair<_T1, _T2>) -> tuple<_T1, _T2>; 1206 template
1207 tuple(allocator_arg_t, _Alloc, _UTypes...) -> tuple<_UTypes...>; 1208 template
1209 tuple(allocator_arg_t, _Alloc, pair<_T1, _T2>) -> tuple<_T1, _T2>; 1210 template
1211 tuple(allocator_arg_t, _Alloc, tuple<_UTypes...>) -> tuple<_UTypes...>; 1212 #endif 1213 1214 // Explicit specialization, zero-element tuple. 1215 template<> 1216 class tuple<> 1217 { 1218 public: 1219 _GLIBCXX20_CONSTEXPR 1220 void swap(tuple&) noexcept { /* no-op */ } 1221 #if __cplusplus > 202002L 1222 constexpr void swap(const tuple&) const noexcept { /* no-op */ } 1223 #endif 1224 // We need the default since we're going to define no-op 1225 // allocator constructors. 1226 tuple() = default; 1227 // No-op allocator constructors. 1228 template
1229 _GLIBCXX20_CONSTEXPR 1230 tuple(allocator_arg_t, const _Alloc&) noexcept { } 1231 template
1232 _GLIBCXX20_CONSTEXPR 1233 tuple(allocator_arg_t, const _Alloc&, const tuple&) noexcept { } 1234 }; 1235 1236 /// Partial specialization, 2-element tuple. 1237 /// Includes construction and assignment from a pair. 1238 template
1239 class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2> 1240 { 1241 typedef _Tuple_impl<0, _T1, _T2> _Inherited; 1242 1243 // Constraint for non-explicit default constructor 1244 template
1245 using _ImplicitDefaultCtor = __enable_if_t< 1246 _TupleConstraints<_Dummy, _U1, _U2>:: 1247 __is_implicitly_default_constructible(), 1248 bool>; 1249 1250 // Constraint for explicit default constructor 1251 template
1252 using _ExplicitDefaultCtor = __enable_if_t< 1253 _TupleConstraints<_Dummy, _U1, _U2>:: 1254 __is_explicitly_default_constructible(), 1255 bool>; 1256 1257 template
1258 using _TCC = _TupleConstraints<_Dummy, _T1, _T2>; 1259 1260 // Constraint for non-explicit constructors 1261 template
1262 using _ImplicitCtor = __enable_if_t< 1263 _TCC<_Cond>::template __is_implicitly_constructible<_U1, _U2>(), 1264 bool>; 1265 1266 // Constraint for non-explicit constructors 1267 template
1268 using _ExplicitCtor = __enable_if_t< 1269 _TCC<_Cond>::template __is_explicitly_constructible<_U1, _U2>(), 1270 bool>; 1271 1272 template
1273 static constexpr bool __assignable() 1274 { 1275 return __and_
, 1276 is_assignable<_T2&, _U2>>::value; 1277 } 1278 1279 template
1280 static constexpr bool __nothrow_assignable() 1281 { 1282 return __and_
, 1283 is_nothrow_assignable<_T2&, _U2>>::value; 1284 } 1285 1286 template
1287 static constexpr bool __nothrow_constructible() 1288 { 1289 return __and_
, 1290 is_nothrow_constructible<_T2, _U2>>::value; 1291 } 1292 1293 static constexpr bool __nothrow_default_constructible() 1294 { 1295 return __and_
, 1296 is_nothrow_default_constructible<_T2>>::value; 1297 } 1298 1299 template
1300 static constexpr bool __is_alloc_arg() 1301 { return is_same<__remove_cvref_t<_U1>, allocator_arg_t>::value; } 1302 1303 #if __cplusplus > 202002L 1304 template
1305 static constexpr bool __constructible 1306 = _TCC
::template __constructible<_U1, _U2>::value; 1307 1308 template
1309 static constexpr bool __convertible 1310 = _TCC
::template __convertible<_U1, _U2>::value; 1311 #endif // C++23 1312 1313 public: 1314 template
= true> 1316 constexpr 1317 tuple() 1318 noexcept(__nothrow_default_constructible()) 1319 : _Inherited() { } 1320 1321 template
= false> 1323 explicit constexpr 1324 tuple() 1325 noexcept(__nothrow_default_constructible()) 1326 : _Inherited() { } 1327 1328 template
= true> 1330 constexpr 1331 tuple(const _T1& __a1, const _T2& __a2) 1332 noexcept(__nothrow_constructible
()) 1333 : _Inherited(__a1, __a2) { } 1334 1335 template
= false> 1337 explicit constexpr 1338 tuple(const _T1& __a1, const _T2& __a2) 1339 noexcept(__nothrow_constructible
()) 1340 : _Inherited(__a1, __a2) { } 1341 1342 template
(), _U1, _U2> = true> 1344 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 template
(), _U1, _U2> = false> 1351 explicit constexpr 1352 tuple(_U1&& __a1, _U2&& __a2) 1353 noexcept(__nothrow_constructible<_U1, _U2>()) 1354 : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } 1355 1356 constexpr tuple(const tuple&) = default; 1357 1358 constexpr tuple(tuple&&) = default; 1359 1360 template
= true> 1362 constexpr 1363 tuple(const tuple<_U1, _U2>& __in) 1364 noexcept(__nothrow_constructible
()) 1365 : _Inherited(static_cast
&>(__in)) { } 1366 1367 template
= false> 1369 explicit constexpr 1370 tuple(const tuple<_U1, _U2>& __in) 1371 noexcept(__nothrow_constructible
()) 1372 : _Inherited(static_cast
&>(__in)) { } 1373 1374 template
= true> 1376 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 template
= false> 1383 explicit constexpr 1384 tuple(tuple<_U1, _U2>&& __in) 1385 noexcept(__nothrow_constructible<_U1, _U2>()) 1386 : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } 1387 1388 #if __cplusplus > 202002L 1389 template
1390 requires __constructible<_U1&, _U2&> 1391 explicit(!__convertible<_U1&, _U2&>) 1392 constexpr 1393 tuple(tuple<_U1, _U2>& __in) 1394 noexcept(__nothrow_constructible<_U1&, _U2&>()) 1395 : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&>(__in)) { } 1396 1397 template
1398 requires __constructible
1399 explicit(!__convertible
) 1400 constexpr 1401 tuple(const tuple<_U1, _U2>&& __in) 1402 noexcept(__nothrow_constructible
()) 1403 : _Inherited(static_cast
&&>(__in)) { } 1404 #endif // C++23 1405 1406 template
= true> 1408 constexpr 1409 tuple(const pair<_U1, _U2>& __in) 1410 noexcept(__nothrow_constructible
()) 1411 : _Inherited(__in.first, __in.second) { } 1412 1413 template
= false> 1415 explicit constexpr 1416 tuple(const pair<_U1, _U2>& __in) 1417 noexcept(__nothrow_constructible
()) 1418 : _Inherited(__in.first, __in.second) { } 1419 1420 template
= true> 1422 constexpr 1423 tuple(pair<_U1, _U2>&& __in) 1424 noexcept(__nothrow_constructible<_U1, _U2>()) 1425 : _Inherited(std::forward<_U1>(__in.first), 1426 std::forward<_U2>(__in.second)) { } 1427 1428 template
= false> 1430 explicit constexpr 1431 tuple(pair<_U1, _U2>&& __in) 1432 noexcept(__nothrow_constructible<_U1, _U2>()) 1433 : _Inherited(std::forward<_U1>(__in.first), 1434 std::forward<_U2>(__in.second)) { } 1435 1436 #if __cplusplus > 202002L 1437 template
1438 requires __constructible<_U1&, _U2&> 1439 explicit(!__convertible<_U1&, _U2&>) 1440 constexpr 1441 tuple(pair<_U1, _U2>& __in) 1442 noexcept(__nothrow_constructible<_U1&, _U2&>()) 1443 : _Inherited(__in.first, __in.second) { } 1444 1445 template
1446 requires __constructible
1447 explicit(!__convertible
) 1448 constexpr 1449 tuple(const pair<_U1, _U2>&& __in) 1450 noexcept(__nothrow_constructible
()) 1451 : _Inherited(std::forward
(__in.first), 1452 std::forward
(__in.second)) { } 1453 #endif // C++23 1454 1455 // Allocator-extended constructors. 1456 1457 template
::value, _T1, _T2> = true> 1459 _GLIBCXX20_CONSTEXPR 1460 tuple(allocator_arg_t __tag, const _Alloc& __a) 1461 : _Inherited(__tag, __a) { } 1462 1463 template
::value, _T1, _T2> = false> 1465 _GLIBCXX20_CONSTEXPR 1466 explicit 1467 tuple(allocator_arg_t __tag, const _Alloc& __a) 1468 : _Inherited(__tag, __a) { } 1469 1470 template
= true> 1472 _GLIBCXX20_CONSTEXPR 1473 tuple(allocator_arg_t __tag, const _Alloc& __a, 1474 const _T1& __a1, const _T2& __a2) 1475 : _Inherited(__tag, __a, __a1, __a2) { } 1476 1477 template
= false> 1479 explicit 1480 _GLIBCXX20_CONSTEXPR 1481 tuple(allocator_arg_t __tag, const _Alloc& __a, 1482 const _T1& __a1, const _T2& __a2) 1483 : _Inherited(__tag, __a, __a1, __a2) { } 1484 1485 template
= true> 1487 _GLIBCXX20_CONSTEXPR 1488 tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2) 1489 : _Inherited(__tag, __a, std::forward<_U1>(__a1), 1490 std::forward<_U2>(__a2)) { } 1491 1492 template
= false> 1494 explicit 1495 _GLIBCXX20_CONSTEXPR 1496 tuple(allocator_arg_t __tag, const _Alloc& __a, 1497 _U1&& __a1, _U2&& __a2) 1498 : _Inherited(__tag, __a, std::forward<_U1>(__a1), 1499 std::forward<_U2>(__a2)) { } 1500 1501 template
1502 _GLIBCXX20_CONSTEXPR 1503 tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) 1504 : _Inherited(__tag, __a, static_cast
(__in)) { } 1505 1506 template
1507 _GLIBCXX20_CONSTEXPR 1508 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) 1509 : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { } 1510 1511 template