1// <tuple> -*- C++ -*- 2 3// Copyright (C) 2007-2021 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 <utility> 39#include <array> 40#include <bits/uses_allocator.h> 41#include <bits/invoke.h> 42#if __cplusplus > 201703L 43# include <compare> 44# define __cpp_lib_constexpr_tuple 201811L 45#endif 46 47namespace std _GLIBCXX_VISIBILITY(default) 48{ 49_GLIBCXX_BEGIN_NAMESPACE_VERSION 50 51 /** 52 * @addtogroup utilities 53 * @{ 54 */ 55 56 template<typename... _Elements> 57 class tuple; 58 59 template<typename _Tp> 60 struct __is_empty_non_tuple : is_empty<_Tp> { }; 61 62 // Using EBO for elements that are tuples causes ambiguous base errors. 63 template<typename _El0, typename... _El> 64 struct __is_empty_non_tuple<tuple<_El0, _El...>> : false_type { }; 65 66 // Use the Empty Base-class Optimization for empty, non-final types. 67 template<typename _Tp> 68 using __empty_not_final 69 = typename conditional<__is_final(_Tp), false_type, 70 __is_empty_non_tuple<_Tp>>::type; 71 72 template<size_t _Idx, typename _Head, 73 bool = __empty_not_final<_Head>::value> 74 struct _Head_base; 75 76#if __has_cpp_attribute(__no_unique_address__) 77 template<size_t _Idx, typename _Head> 78 struct _Head_base<_Idx, _Head, true> 79 { 80 constexpr _Head_base() 81 : _M_head_impl() { } 82 83 constexpr _Head_base(const _Head& __h) 84 : _M_head_impl(__h) { } 85 86 constexpr _Head_base(const _Head_base&) = default; 87 constexpr _Head_base(_Head_base&&) = default; 88 89 template<typename _UHead> 90 constexpr _Head_base(_UHead&& __h) 91 : _M_head_impl(std::forward<_UHead>(__h)) { } 92 93 _GLIBCXX20_CONSTEXPR 94 _Head_base(allocator_arg_t, __uses_alloc0) 95 : _M_head_impl() { } 96 97 template<typename _Alloc> 98 _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a) 99 : _M_head_impl(allocator_arg, *__a._M_a) { } 100 101 template<typename _Alloc> 102 _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a) 103 : _M_head_impl(*__a._M_a) { } 104 105 template<typename _UHead> 106 _GLIBCXX20_CONSTEXPR 107 _Head_base(__uses_alloc0, _UHead&& __uhead) 108 : _M_head_impl(std::forward<_UHead>(__uhead)) { } 109 110 template<typename _Alloc, typename _UHead> 111 _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead) 112 : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) 113 { } 114 115 template<typename _Alloc, typename _UHead> 116 _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead) 117 : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { } 118 119 static constexpr _Head& 120 _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; } 121 122 static constexpr const _Head& 123 _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; } 124 125 [[__no_unique_address__]] _Head _M_head_impl; 126 }; 127#else 128 template<size_t _Idx, typename _Head> 129 struct _Head_base<_Idx, _Head, true> 130 : public _Head 131 { 132 constexpr _Head_base() 133 : _Head() { } 134 135 constexpr _Head_base(const _Head& __h) 136 : _Head(__h) { } 137 138 constexpr _Head_base(const _Head_base&) = default; 139 constexpr _Head_base(_Head_base&&) = default; 140 141 template<typename _UHead> 142 constexpr _Head_base(_UHead&& __h) 143 : _Head(std::forward<_UHead>(__h)) { } 144 145 _Head_base(allocator_arg_t, __uses_alloc0) 146 : _Head() { } 147 148 template<typename _Alloc> 149 _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a) 150 : _Head(allocator_arg, *__a._M_a) { } 151 152 template<typename _Alloc> 153 _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a) 154 : _Head(*__a._M_a) { } 155 156 template<typename _UHead> 157 _Head_base(__uses_alloc0, _UHead&& __uhead) 158 : _Head(std::forward<_UHead>(__uhead)) { } 159 160 template<typename _Alloc, typename _UHead> 161 _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead) 162 : _Head(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { } 163 164 template<typename _Alloc, typename _UHead> 165 _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead) 166 : _Head(std::forward<_UHead>(__uhead), *__a._M_a) { } 167 168 static constexpr _Head& 169 _M_head(_Head_base& __b) noexcept { return __b; } 170 171 static constexpr const _Head& 172 _M_head(const _Head_base& __b) noexcept { return __b; } 173 }; 174#endif 175 176 template<size_t _Idx, typename _Head> 177 struct _Head_base<_Idx, _Head, false> 178 { 179 constexpr _Head_base() 180 : _M_head_impl() { } 181 182 constexpr _Head_base(const _Head& __h) 183 : _M_head_impl(__h) { } 184 185 constexpr _Head_base(const _Head_base&) = default; 186 constexpr _Head_base(_Head_base&&) = default; 187 188 template<typename _UHead> 189 constexpr _Head_base(_UHead&& __h) 190 : _M_head_impl(std::forward<_UHead>(__h)) { } 191 192 _GLIBCXX20_CONSTEXPR 193 _Head_base(allocator_arg_t, __uses_alloc0) 194 : _M_head_impl() { } 195 196 template<typename _Alloc> 197 _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a) 198 : _M_head_impl(allocator_arg, *__a._M_a) { } 199 200 template<typename _Alloc> 201 _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a) 202 : _M_head_impl(*__a._M_a) { } 203 204 template<typename _UHead> 205 _GLIBCXX20_CONSTEXPR 206 _Head_base(__uses_alloc0, _UHead&& __uhead) 207 : _M_head_impl(std::forward<_UHead>(__uhead)) { } 208 209 template<typename _Alloc, typename _UHead> 210 _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead) 211 : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) 212 { } 213 214 template<typename _Alloc, typename _UHead> 215 _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead) 216 : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { } 217 218 static constexpr _Head& 219 _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; } 220 221 static constexpr const _Head& 222 _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; } 223 224 _Head _M_head_impl; 225 }; 226 227 /** 228 * Contains the actual implementation of the @c tuple template, stored 229 * as a recursive inheritance hierarchy from the first element (most 230 * derived class) to the last (least derived class). The @c Idx 231 * parameter gives the 0-based index of the element stored at this 232 * point in the hierarchy; we use it to implement a constant-time 233 * get() operation. 234 */ 235 template<size_t _Idx, typename... _Elements> 236 struct _Tuple_impl; 237 238 /** 239 * Recursive tuple implementation. Here we store the @c Head element 240 * and derive from a @c Tuple_impl containing the remaining elements 241 * (which contains the @c Tail). 242 */ 243 template<size_t _Idx, typename _Head, typename... _Tail> 244 struct _Tuple_impl<_Idx, _Head, _Tail...> 245 : public _Tuple_impl<_Idx + 1, _Tail...>, 246 private _Head_base<_Idx, _Head> 247 { 248 template<size_t, typename...> friend struct _Tuple_impl; 249 250 typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited; 251 typedef _Head_base<_Idx, _Head> _Base; 252 253 static constexpr _Head& 254 _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } 255 256 static constexpr const _Head& 257 _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } 258 259 static constexpr _Inherited& 260 _M_tail(_Tuple_impl& __t) noexcept { return __t; } 261 262 static constexpr const _Inherited& 263 _M_tail(const _Tuple_impl& __t) noexcept { return __t; } 264 265 constexpr _Tuple_impl() 266 : _Inherited(), _Base() { } 267 268 explicit constexpr 269 _Tuple_impl(const _Head& __head, const _Tail&... __tail) 270 : _Inherited(__tail...), _Base(__head) 271 { } 272 273 template<typename _UHead, typename... _UTail, 274 typename = __enable_if_t<sizeof...(_Tail) == sizeof...(_UTail)>> 275 explicit constexpr 276 _Tuple_impl(_UHead&& __head, _UTail&&... __tail) 277 : _Inherited(std::forward<_UTail>(__tail)...), 278 _Base(std::forward<_UHead>(__head)) 279 { } 280 281 constexpr _Tuple_impl(const _Tuple_impl&) = default; 282 283 // _GLIBCXX_RESOLVE_LIB_DEFECTS 284 // 2729. Missing SFINAE on std::pair::operator= 285 _Tuple_impl& operator=(const _Tuple_impl&) = delete; 286 287 constexpr 288 _Tuple_impl(_Tuple_impl&& __in) 289 noexcept(__and_<is_nothrow_move_constructible<_Head>, 290 is_nothrow_move_constructible<_Inherited>>::value) 291 : _Inherited(std::move(_M_tail(__in))), 292 _Base(std::forward<_Head>(_M_head(__in))) 293 { } 294 295 template<typename... _UElements> 296 constexpr 297 _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in) 298 : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)), 299 _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) 300 { } 301 302 template<typename _UHead, typename... _UTails> 303 constexpr 304 _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) 305 : _Inherited(std::move 306 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))), 307 _Base(std::forward<_UHead> 308 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) 309 { } 310 311 template<typename _Alloc> 312 _GLIBCXX20_CONSTEXPR 313 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a) 314 : _Inherited(__tag, __a), 315 _Base(__tag, __use_alloc<_Head>(__a)) 316 { } 317 318 template<typename _Alloc> 319 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 320 const _Head& __head, const _Tail&... __tail) 321 : _Inherited(__tag, __a, __tail...), 322 _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) 323 { } 324 325 template<typename _Alloc, typename _UHead, typename... _UTail, 326 typename = __enable_if_t<sizeof...(_Tail) == sizeof...(_UTail)>> 327 _GLIBCXX20_CONSTEXPR 328 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 329 _UHead&& __head, _UTail&&... __tail) 330 : _Inherited(__tag, __a, std::forward<_UTail>(__tail)...), 331 _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), 332 std::forward<_UHead>(__head)) 333 { } 334 335 template<typename _Alloc> 336 _GLIBCXX20_CONSTEXPR 337 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 338 const _Tuple_impl& __in) 339 : _Inherited(__tag, __a, _M_tail(__in)), 340 _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) 341 { } 342 343 template<typename _Alloc> 344 _GLIBCXX20_CONSTEXPR 345 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 346 _Tuple_impl&& __in) 347 : _Inherited(__tag, __a, std::move(_M_tail(__in))), 348 _Base(__use_alloc<_Head, _Alloc, _Head>(__a), 349 std::forward<_Head>(_M_head(__in))) 350 { } 351 352 template<typename _Alloc, typename _UHead, typename... _UTails> 353 _GLIBCXX20_CONSTEXPR 354 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 355 const _Tuple_impl<_Idx, _UHead, _UTails...>& __in) 356 : _Inherited(__tag, __a, 357 _Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)), 358 _Base(__use_alloc<_Head, _Alloc, const _UHead&>(__a), 359 _Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)) 360 { } 361 362 template<typename _Alloc, typename _UHead, typename... _UTails> 363 _GLIBCXX20_CONSTEXPR 364 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 365 _Tuple_impl<_Idx, _UHead, _UTails...>&& __in) 366 : _Inherited(__tag, __a, std::move 367 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))), 368 _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), 369 std::forward<_UHead> 370 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) 371 { } 372 373 template<typename... _UElements> 374 _GLIBCXX20_CONSTEXPR 375 void 376 _M_assign(const _Tuple_impl<_Idx, _UElements...>& __in) 377 { 378 _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in); 379 _M_tail(*this)._M_assign( 380 _Tuple_impl<_Idx, _UElements...>::_M_tail(__in)); 381 } 382 383 template<typename _UHead, typename... _UTails> 384 _GLIBCXX20_CONSTEXPR 385 void 386 _M_assign(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) 387 { 388 _M_head(*this) = std::forward<_UHead> 389 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)); 390 _M_tail(*this)._M_assign( 391 std::move(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))); 392 } 393 394 protected: 395 _GLIBCXX20_CONSTEXPR 396 void 397 _M_swap(_Tuple_impl& __in) 398 { 399 using std::swap; 400 swap(_M_head(*this), _M_head(__in)); 401 _Inherited::_M_swap(_M_tail(__in)); 402 } 403 }; 404 405 // Basis case of inheritance recursion. 406 template<size_t _Idx, typename _Head> 407 struct _Tuple_impl<_Idx, _Head> 408 : private _Head_base<_Idx, _Head> 409 { 410 template<size_t, typename...> friend struct _Tuple_impl; 411 412 typedef _Head_base<_Idx, _Head> _Base; 413 414 static constexpr _Head& 415 _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } 416 417 static constexpr const _Head& 418 _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } 419 420 constexpr 421 _Tuple_impl() 422 : _Base() { } 423 424 explicit constexpr 425 _Tuple_impl(const _Head& __head) 426 : _Base(__head) 427 { } 428 429 template<typename _UHead> 430 explicit constexpr 431 _Tuple_impl(_UHead&& __head) 432 : _Base(std::forward<_UHead>(__head)) 433 { } 434 435 constexpr _Tuple_impl(const _Tuple_impl&) = default; 436 437 // _GLIBCXX_RESOLVE_LIB_DEFECTS 438 // 2729. Missing SFINAE on std::pair::operator= 439 _Tuple_impl& operator=(const _Tuple_impl&) = delete; 440 441 constexpr 442 _Tuple_impl(_Tuple_impl&& __in) 443 noexcept(is_nothrow_move_constructible<_Head>::value) 444 : _Base(std::forward<_Head>(_M_head(__in))) 445 { } 446 447 template<typename _UHead> 448 constexpr 449 _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in) 450 : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in)) 451 { } 452 453 template<typename _UHead> 454 constexpr 455 _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in) 456 : _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in))) 457 { } 458 459 template<typename _Alloc> 460 _GLIBCXX20_CONSTEXPR 461 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a) 462 : _Base(__tag, __use_alloc<_Head>(__a)) 463 { } 464 465 template<typename _Alloc> 466 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 467 const _Head& __head) 468 : _Base(__use_alloc<_Head, _Alloc, const _Head&>(__a), __head) 469 { } 470 471 template<typename _Alloc, typename _UHead> 472 _GLIBCXX20_CONSTEXPR 473 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 474 _UHead&& __head) 475 : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), 476 std::forward<_UHead>(__head)) 477 { } 478 479 template<typename _Alloc> 480 _GLIBCXX20_CONSTEXPR 481 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 482 const _Tuple_impl& __in) 483 : _Base(__use_alloc<_Head, _Alloc, const _Head&>(__a), _M_head(__in)) 484 { } 485 486 template<typename _Alloc> 487 _GLIBCXX20_CONSTEXPR 488 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 489 _Tuple_impl&& __in) 490 : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), 491 std::forward<_Head>(_M_head(__in))) 492 { } 493 494 template<typename _Alloc, typename _UHead> 495 _GLIBCXX20_CONSTEXPR 496 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 497 const _Tuple_impl<_Idx, _UHead>& __in) 498 : _Base(__use_alloc<_Head, _Alloc, const _UHead&>(__a), 499 _Tuple_impl<_Idx, _UHead>::_M_head(__in)) 500 { } 501 502 template<typename _Alloc, typename _UHead> 503 _GLIBCXX20_CONSTEXPR 504 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 505 _Tuple_impl<_Idx, _UHead>&& __in) 506 : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), 507 std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in))) 508 { } 509 510 template<typename _UHead> 511 _GLIBCXX20_CONSTEXPR 512 void 513 _M_assign(const _Tuple_impl<_Idx, _UHead>& __in) 514 { 515 _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in); 516 } 517 518 template<typename _UHead> 519 _GLIBCXX20_CONSTEXPR 520 void 521 _M_assign(_Tuple_impl<_Idx, _UHead>&& __in) 522 { 523 _M_head(*this) 524 = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)); 525 } 526 527 protected: 528 _GLIBCXX20_CONSTEXPR 529 void 530 _M_swap(_Tuple_impl& __in) 531 { 532 using std::swap; 533 swap(_M_head(*this), _M_head(__in)); 534 } 535 }; 536 537 // Concept utility functions, reused in conditionally-explicit 538 // constructors. 539 template<bool, typename... _Types> 540 struct _TupleConstraints 541 { 542 template<typename _Tp, typename _Up> // Workaround for PR 96592 543 using is_constructible 544 = __bool_constant<__is_constructible(_Tp, _Up)>; 545 546 // Constraint for a non-explicit constructor. 547 // True iff each Ti in _Types... can be constructed from Ui in _UTypes... 548 // and every Ui is implicitly convertible to Ti. 549 template<typename... _UTypes> 550 static constexpr bool __is_implicitly_constructible() 551 { 552 return __and_<is_constructible<_Types, _UTypes>..., 553 is_convertible<_UTypes, _Types>... 554 >::value; 555 } 556 557 // Constraint for a non-explicit constructor. 558 // True iff each Ti in _Types... can be constructed from Ui in _UTypes... 559 // but not every Ui is implicitly convertible to Ti. 560 template<typename... _UTypes> 561 static constexpr bool __is_explicitly_constructible() 562 { 563 return __and_<is_constructible<_Types, _UTypes>..., 564 __not_<__and_<is_convertible<_UTypes, _Types>...>> 565 >::value; 566 } 567 568 static constexpr bool __is_implicitly_default_constructible() 569 { 570 return __and_<std::__is_implicitly_default_constructible<_Types>... 571 >::value; 572 } 573 574 static constexpr bool __is_explicitly_default_constructible() 575 { 576 return __and_<is_default_constructible<_Types>..., 577 __not_<__and_< 578 std::__is_implicitly_default_constructible<_Types>...> 579 >>::value; 580 } 581 }; 582 583 // Partial specialization used when a required precondition isn't met, 584 // e.g. when sizeof...(_Types) != sizeof...(_UTypes). 585 template<typename... _Types> 586 struct _TupleConstraints<false, _Types...> 587 { 588 template<typename... _UTypes> 589 static constexpr bool __is_implicitly_constructible() 590 { return false; } 591 592 template<typename... _UTypes> 593 static constexpr bool __is_explicitly_constructible() 594 { return false; } 595 }; 596 597 /// Primary class template, tuple 598 template<typename... _Elements> 599 class tuple : public _Tuple_impl<0, _Elements...> 600 { 601 typedef _Tuple_impl<0, _Elements...> _Inherited; 602 603 template<bool _Cond> 604 using _TCC = _TupleConstraints<_Cond, _Elements...>; 605 606 // Constraint for non-explicit default constructor 607 template<bool _Dummy> 608 using _ImplicitDefaultCtor = __enable_if_t< 609 _TCC<_Dummy>::__is_implicitly_default_constructible(), 610 bool>; 611 612 // Constraint for explicit default constructor 613 template<bool _Dummy> 614 using _ExplicitDefaultCtor = __enable_if_t< 615 _TCC<_Dummy>::__is_explicitly_default_constructible(), 616 bool>; 617 618 // Constraint for non-explicit constructors 619 template<bool _Cond, typename... _Args> 620 using _ImplicitCtor = __enable_if_t< 621 _TCC<_Cond>::template __is_implicitly_constructible<_Args...>(), 622 bool>; 623 624 // Constraint for non-explicit constructors 625 template<bool _Cond, typename... _Args> 626 using _ExplicitCtor = __enable_if_t< 627 _TCC<_Cond>::template __is_explicitly_constructible<_Args...>(), 628 bool>; 629 630 template<typename... _UElements> 631 static constexpr 632 __enable_if_t<sizeof...(_UElements) == sizeof...(_Elements), bool> 633 __assignable() 634 { return __and_<is_assignable<_Elements&, _UElements>...>::value; } 635 636 // Condition for noexcept-specifier of an assignment operator. 637 template<typename... _UElements> 638 static constexpr bool __nothrow_assignable() 639 { 640 return 641 __and_<is_nothrow_assignable<_Elements&, _UElements>...>::value; 642 } 643 644 // Condition for noexcept-specifier of a constructor. 645 template<typename... _UElements> 646 static constexpr bool __nothrow_constructible() 647 { 648 return 649 __and_<is_nothrow_constructible<_Elements, _UElements>...>::value; 650 } 651 652 // Constraint for tuple(_UTypes&&...) where sizeof...(_UTypes) == 1. 653 template<typename _Up> 654 static constexpr bool __valid_args() 655 { 656 return sizeof...(_Elements) == 1 657 && !is_same<tuple, __remove_cvref_t<_Up>>::value; 658 } 659 660 // Constraint for tuple(_UTypes&&...) where sizeof...(_UTypes) > 1. 661 template<typename, typename, typename... _Tail> 662 static constexpr bool __valid_args() 663 { return (sizeof...(_Tail) + 2) == sizeof...(_Elements); } 664 665 /* Constraint for constructors with a tuple<UTypes...> parameter ensures 666 * that the constructor is only viable when it would not interfere with 667 * tuple(UTypes&&...) or tuple(const tuple&) or tuple(tuple&&). 668 * Such constructors are only viable if: 669 * either sizeof...(Types) != 1, 670 * or (when Types... expands to T and UTypes... expands to U) 671 * is_convertible_v<TUPLE, T>, is_constructible_v<T, TUPLE>, 672 * and is_same_v<T, U> are all false. 673 */ 674 template<typename _Tuple, typename = tuple, 675 typename = __remove_cvref_t<_Tuple>> 676 struct _UseOtherCtor 677 : false_type 678 { }; 679 // If TUPLE is convertible to the single element in *this, 680 // then TUPLE should match tuple(UTypes&&...) instead. 681 template<typename _Tuple, typename _Tp, typename _Up> 682 struct _UseOtherCtor<_Tuple, tuple<_Tp>, tuple<_Up>> 683 : __or_<is_convertible<_Tuple, _Tp>, is_constructible<_Tp, _Tuple>> 684 { }; 685 // If TUPLE and *this each have a single element of the same type, 686 // then TUPLE should match a copy/move constructor instead. 687 template<typename _Tuple, typename _Tp> 688 struct _UseOtherCtor<_Tuple, tuple<_Tp>, tuple<_Tp>> 689 : true_type 690 { }; 691 692 // Return true iff sizeof...(Types) == 1 && tuple_size_v<TUPLE> == 1 693 // and the single element in Types can be initialized from TUPLE, 694 // or is the same type as tuple_element_t<0, TUPLE>. 695 template<typename _Tuple> 696 static constexpr bool __use_other_ctor() 697 { return _UseOtherCtor<_Tuple>::value; } 698 699 public: 700 template<typename _Dummy = void, 701 _ImplicitDefaultCtor<is_void<_Dummy>::value> = true> 702 constexpr 703 tuple() 704 noexcept(__and_<is_nothrow_default_constructible<_Elements>...>::value) 705 : _Inherited() { } 706 707 template<typename _Dummy = void, 708 _ExplicitDefaultCtor<is_void<_Dummy>::value> = false> 709 explicit constexpr 710 tuple() 711 noexcept(__and_<is_nothrow_default_constructible<_Elements>...>::value) 712 : _Inherited() { } 713 714 template<bool _NotEmpty = (sizeof...(_Elements) >= 1), 715 _ImplicitCtor<_NotEmpty, const _Elements&...> = true> 716 constexpr 717 tuple(const _Elements&... __elements) 718 noexcept(__nothrow_constructible<const _Elements&...>()) 719 : _Inherited(__elements...) { } 720 721 template<bool _NotEmpty = (sizeof...(_Elements) >= 1), 722 _ExplicitCtor<_NotEmpty, const _Elements&...> = false> 723 explicit constexpr 724 tuple(const _Elements&... __elements) 725 noexcept(__nothrow_constructible<const _Elements&...>()) 726 : _Inherited(__elements...) { } 727 728 template<typename... _UElements, 729 bool _Valid = __valid_args<_UElements...>(), 730 _ImplicitCtor<_Valid, _UElements...> = true> 731 constexpr 732 tuple(_UElements&&... __elements) 733 noexcept(__nothrow_constructible<_UElements...>()) 734 : _Inherited(std::forward<_UElements>(__elements)...) { } 735 736 template<typename... _UElements, 737 bool _Valid = __valid_args<_UElements...>(), 738 _ExplicitCtor<_Valid, _UElements...> = false> 739 explicit constexpr 740 tuple(_UElements&&... __elements) 741 noexcept(__nothrow_constructible<_UElements...>()) 742 : _Inherited(std::forward<_UElements>(__elements)...) { } 743 744 constexpr tuple(const tuple&) = default; 745 746 constexpr tuple(tuple&&) = default; 747 748 template<typename... _UElements, 749 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) 750 && !__use_other_ctor<const tuple<_UElements...>&>(), 751 _ImplicitCtor<_Valid, const _UElements&...> = true> 752 constexpr 753 tuple(const tuple<_UElements...>& __in) 754 noexcept(__nothrow_constructible<const _UElements&...>()) 755 : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) 756 { } 757 758 template<typename... _UElements, 759 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) 760 && !__use_other_ctor<const tuple<_UElements...>&>(), 761 _ExplicitCtor<_Valid, const _UElements&...> = false> 762 explicit constexpr 763 tuple(const tuple<_UElements...>& __in) 764 noexcept(__nothrow_constructible<const _UElements&...>()) 765 : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) 766 { } 767 768 template<typename... _UElements, 769 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) 770 && !__use_other_ctor<tuple<_UElements...>&&>(), 771 _ImplicitCtor<_Valid, _UElements...> = true> 772 constexpr 773 tuple(tuple<_UElements...>&& __in) 774 noexcept(__nothrow_constructible<_UElements...>()) 775 : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } 776 777 template<typename... _UElements, 778 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) 779 && !__use_other_ctor<tuple<_UElements...>&&>(), 780 _ExplicitCtor<_Valid, _UElements...> = false> 781 explicit constexpr 782 tuple(tuple<_UElements...>&& __in) 783 noexcept(__nothrow_constructible<_UElements...>()) 784 : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } 785 786 // Allocator-extended constructors. 787 788 template<typename _Alloc, 789 _ImplicitDefaultCtor<is_object<_Alloc>::value> = true> 790 _GLIBCXX20_CONSTEXPR 791 tuple(allocator_arg_t __tag, const _Alloc& __a) 792 : _Inherited(__tag, __a) { } 793 794 template<typename _Alloc, bool _NotEmpty = (sizeof...(_Elements) >= 1), 795 _ImplicitCtor<_NotEmpty, const _Elements&...> = true> 796 _GLIBCXX20_CONSTEXPR 797 tuple(allocator_arg_t __tag, const _Alloc& __a, 798 const _Elements&... __elements) 799 : _Inherited(__tag, __a, __elements...) { } 800 801 template<typename _Alloc, bool _NotEmpty = (sizeof...(_Elements) >= 1), 802 _ExplicitCtor<_NotEmpty, const _Elements&...> = false> 803 _GLIBCXX20_CONSTEXPR 804 explicit 805 tuple(allocator_arg_t __tag, const _Alloc& __a, 806 const _Elements&... __elements) 807 : _Inherited(__tag, __a, __elements...) { } 808 809 template<typename _Alloc, typename... _UElements, 810 bool _Valid = __valid_args<_UElements...>(), 811 _ImplicitCtor<_Valid, _UElements...> = true> 812 _GLIBCXX20_CONSTEXPR 813 tuple(allocator_arg_t __tag, const _Alloc& __a, 814 _UElements&&... __elements) 815 : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...) 816 { } 817 818 template<typename _Alloc, typename... _UElements, 819 bool _Valid = __valid_args<_UElements...>(), 820 _ExplicitCtor<_Valid, _UElements...> = false> 821 _GLIBCXX20_CONSTEXPR 822 explicit 823 tuple(allocator_arg_t __tag, const _Alloc& __a, 824 _UElements&&... __elements) 825 : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...) 826 { } 827 828 template<typename _Alloc> 829 _GLIBCXX20_CONSTEXPR 830 tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) 831 : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { } 832 833 template<typename _Alloc> 834 _GLIBCXX20_CONSTEXPR 835 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) 836 : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { } 837 838 template<typename _Alloc, typename... _UElements, 839 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) 840 && !__use_other_ctor<const tuple<_UElements...>&>(), 841 _ImplicitCtor<_Valid, const _UElements&...> = true> 842 _GLIBCXX20_CONSTEXPR 843 tuple(allocator_arg_t __tag, const _Alloc& __a, 844 const tuple<_UElements...>& __in) 845 : _Inherited(__tag, __a, 846 static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) 847 { } 848 849 template<typename _Alloc, typename... _UElements, 850 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) 851 && !__use_other_ctor<const tuple<_UElements...>&>(), 852 _ExplicitCtor<_Valid, const _UElements&...> = false> 853 _GLIBCXX20_CONSTEXPR 854 explicit 855 tuple(allocator_arg_t __tag, const _Alloc& __a, 856 const tuple<_UElements...>& __in) 857 : _Inherited(__tag, __a, 858 static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) 859 { } 860 861 template<typename _Alloc, typename... _UElements, 862 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) 863 && !__use_other_ctor<tuple<_UElements...>&&>(), 864 _ImplicitCtor<_Valid, _UElements...> = true> 865 _GLIBCXX20_CONSTEXPR 866 tuple(allocator_arg_t __tag, const _Alloc& __a, 867 tuple<_UElements...>&& __in) 868 : _Inherited(__tag, __a, 869 static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) 870 { } 871 872 template<typename _Alloc, typename... _UElements, 873 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) 874 && !__use_other_ctor<tuple<_UElements...>&&>(), 875 _ExplicitCtor<_Valid, _UElements...> = false> 876 _GLIBCXX20_CONSTEXPR 877 explicit 878 tuple(allocator_arg_t __tag, const _Alloc& __a, 879 tuple<_UElements...>&& __in) 880 : _Inherited(__tag, __a, 881 static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) 882 { } 883 884 // tuple assignment 885 886 _GLIBCXX20_CONSTEXPR 887 tuple& 888 operator=(typename conditional<__assignable<const _Elements&...>(), 889 const tuple&, 890 const __nonesuch&>::type __in) 891 noexcept(__nothrow_assignable<const _Elements&...>()) 892 { 893 this->_M_assign(__in); 894 return *this; 895 } 896 897 _GLIBCXX20_CONSTEXPR 898 tuple& 899 operator=(typename conditional<__assignable<_Elements...>(), 900 tuple&&, 901 __nonesuch&&>::type __in) 902 noexcept(__nothrow_assignable<_Elements...>()) 903 { 904 this->_M_assign(std::move(__in)); 905 return *this; 906 } 907 908 template<typename... _UElements> 909 _GLIBCXX20_CONSTEXPR 910 __enable_if_t<__assignable<const _UElements&...>(), tuple&> 911 operator=(const tuple<_UElements...>& __in) 912 noexcept(__nothrow_assignable<const _UElements&...>()) 913 { 914 this->_M_assign(__in); 915 return *this; 916 } 917 918 template<typename... _UElements> 919 _GLIBCXX20_CONSTEXPR 920 __enable_if_t<__assignable<_UElements...>(), tuple&> 921 operator=(tuple<_UElements...>&& __in) 922 noexcept(__nothrow_assignable<_UElements...>()) 923 { 924 this->_M_assign(std::move(__in)); 925 return *this; 926 } 927 928 // tuple swap 929 _GLIBCXX20_CONSTEXPR 930 void 931 swap(tuple& __in) 932 noexcept(__and_<__is_nothrow_swappable<_Elements>...>::value) 933 { _Inherited::_M_swap(__in); } 934 }; 935 936#if __cpp_deduction_guides >= 201606 937 template<typename... _UTypes> 938 tuple(_UTypes...) -> tuple<_UTypes...>; 939 template<typename _T1, typename _T2> 940 tuple(pair<_T1, _T2>) -> tuple<_T1, _T2>; 941 template<typename _Alloc, typename... _UTypes> 942 tuple(allocator_arg_t, _Alloc, _UTypes...) -> tuple<_UTypes...>; 943 template<typename _Alloc, typename _T1, typename _T2> 944 tuple(allocator_arg_t, _Alloc, pair<_T1, _T2>) -> tuple<_T1, _T2>; 945 template<typename _Alloc, typename... _UTypes> 946 tuple(allocator_arg_t, _Alloc, tuple<_UTypes...>) -> tuple<_UTypes...>; 947#endif 948 949 // Explicit specialization, zero-element tuple. 950 template<> 951 class tuple<> 952 { 953 public: 954 void swap(tuple&) noexcept { /* no-op */ } 955 // We need the default since we're going to define no-op 956 // allocator constructors. 957 tuple() = default; 958 // No-op allocator constructors. 959 template<typename _Alloc> 960 _GLIBCXX20_CONSTEXPR 961 tuple(allocator_arg_t, const _Alloc&) noexcept { } 962 template<typename _Alloc> 963 _GLIBCXX20_CONSTEXPR 964 tuple(allocator_arg_t, const _Alloc&, const tuple&) noexcept { } 965 }; 966 967 /// Partial specialization, 2-element tuple. 968 /// Includes construction and assignment from a pair. 969 template<typename _T1, typename _T2> 970 class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2> 971 { 972 typedef _Tuple_impl<0, _T1, _T2> _Inherited; 973 974 // Constraint for non-explicit default constructor 975 template<bool _Dummy, typename _U1, typename _U2> 976 using _ImplicitDefaultCtor = __enable_if_t< 977 _TupleConstraints<_Dummy, _U1, _U2>:: 978 __is_implicitly_default_constructible(), 979 bool>; 980 981 // Constraint for explicit default constructor 982 template<bool _Dummy, typename _U1, typename _U2> 983 using _ExplicitDefaultCtor = __enable_if_t< 984 _TupleConstraints<_Dummy, _U1, _U2>:: 985 __is_explicitly_default_constructible(), 986 bool>; 987 988 template<bool _Dummy> 989 using _TCC = _TupleConstraints<_Dummy, _T1, _T2>; 990 991 // Constraint for non-explicit constructors 992 template<bool _Cond, typename _U1, typename _U2> 993 using _ImplicitCtor = __enable_if_t< 994 _TCC<_Cond>::template __is_implicitly_constructible<_U1, _U2>(), 995 bool>; 996 997 // Constraint for non-explicit constructors 998 template<bool _Cond, typename _U1, typename _U2> 999 using _ExplicitCtor = __enable_if_t< 1000 _TCC<_Cond>::template __is_explicitly_constructible<_U1, _U2>(), 1001 bool>; 1002 1003 template<typename _U1, typename _U2> 1004 static constexpr bool __assignable() 1005 { 1006 return __and_<is_assignable<_T1&, _U1>, 1007 is_assignable<_T2&, _U2>>::value; 1008 } 1009 1010 template<typename _U1, typename _U2> 1011 static constexpr bool __nothrow_assignable() 1012 { 1013 return __and_<is_nothrow_assignable<_T1&, _U1>, 1014 is_nothrow_assignable<_T2&, _U2>>::value; 1015 } 1016 1017 template<typename _U1, typename _U2> 1018 static constexpr bool __nothrow_constructible() 1019 { 1020 return __and_<is_nothrow_constructible<_T1, _U1>, 1021 is_nothrow_constructible<_T2, _U2>>::value; 1022 } 1023 1024 static constexpr bool __nothrow_default_constructible() 1025 { 1026 return __and_<is_nothrow_default_constructible<_T1>, 1027 is_nothrow_default_constructible<_T2>>::value; 1028 } 1029 1030 template<typename _U1> 1031 static constexpr bool __is_alloc_arg() 1032 { return is_same<__remove_cvref_t<_U1>, allocator_arg_t>::value; } 1033 1034 public: 1035 template<bool _Dummy = true, 1036 _ImplicitDefaultCtor<_Dummy, _T1, _T2> = true> 1037 constexpr 1038 tuple() 1039 noexcept(__nothrow_default_constructible()) 1040 : _Inherited() { } 1041 1042 template<bool _Dummy = true, 1043 _ExplicitDefaultCtor<_Dummy, _T1, _T2> = false> 1044 explicit constexpr 1045 tuple() 1046 noexcept(__nothrow_default_constructible()) 1047 : _Inherited() { } 1048 1049 template<bool _Dummy = true, 1050 _ImplicitCtor<_Dummy, const _T1&, const _T2&> = true> 1051 constexpr 1052 tuple(const _T1& __a1, const _T2& __a2) 1053 noexcept(__nothrow_constructible<const _T1&, const _T2&>()) 1054 : _Inherited(__a1, __a2) { } 1055 1056 template<bool _Dummy = true, 1057 _ExplicitCtor<_Dummy, const _T1&, const _T2&> = false> 1058 explicit constexpr 1059 tuple(const _T1& __a1, const _T2& __a2) 1060 noexcept(__nothrow_constructible<const _T1&, const _T2&>()) 1061 : _Inherited(__a1, __a2) { } 1062 1063 template<typename _U1, typename _U2, 1064 _ImplicitCtor<!__is_alloc_arg<_U1>(), _U1, _U2> = true> 1065 constexpr 1066 tuple(_U1&& __a1, _U2&& __a2) 1067 noexcept(__nothrow_constructible<_U1, _U2>()) 1068 : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } 1069 1070 template<typename _U1, typename _U2, 1071 _ExplicitCtor<!__is_alloc_arg<_U1>(), _U1, _U2> = false> 1072 explicit constexpr 1073 tuple(_U1&& __a1, _U2&& __a2) 1074 noexcept(__nothrow_constructible<_U1, _U2>()) 1075 : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } 1076 1077 constexpr tuple(const tuple&) = default; 1078 1079 constexpr tuple(tuple&&) = default; 1080 1081 template<typename _U1, typename _U2, 1082 _ImplicitCtor<true, const _U1&, const _U2&> = true> 1083 constexpr 1084 tuple(const tuple<_U1, _U2>& __in) 1085 noexcept(__nothrow_constructible<const _U1&, const _U2&>()) 1086 : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { } 1087 1088 template<typename _U1, typename _U2, 1089 _ExplicitCtor<true, const _U1&, const _U2&> = false> 1090 explicit constexpr 1091 tuple(const tuple<_U1, _U2>& __in) 1092 noexcept(__nothrow_constructible<const _U1&, const _U2&>()) 1093 : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { } 1094 1095 template<typename _U1, typename _U2, 1096 _ImplicitCtor<true, _U1, _U2> = true> 1097 constexpr 1098 tuple(tuple<_U1, _U2>&& __in) 1099 noexcept(__nothrow_constructible<_U1, _U2>()) 1100 : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } 1101 1102 template<typename _U1, typename _U2, 1103 _ExplicitCtor<true, _U1, _U2> = false> 1104 explicit constexpr 1105 tuple(tuple<_U1, _U2>&& __in) 1106 noexcept(__nothrow_constructible<_U1, _U2>()) 1107 : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } 1108 1109 template<typename _U1, typename _U2, 1110 _ImplicitCtor<true, const _U1&, const _U2&> = true> 1111 constexpr 1112 tuple(const pair<_U1, _U2>& __in) 1113 noexcept(__nothrow_constructible<const _U1&, const _U2&>()) 1114 : _Inherited(__in.first, __in.second) { } 1115 1116 template<typename _U1, typename _U2, 1117 _ExplicitCtor<true, const _U1&, const _U2&> = false> 1118 explicit constexpr 1119 tuple(const pair<_U1, _U2>& __in) 1120 noexcept(__nothrow_constructible<const _U1&, const _U2&>()) 1121 : _Inherited(__in.first, __in.second) { } 1122 1123 template<typename _U1, typename _U2, 1124 _ImplicitCtor<true, _U1, _U2> = true> 1125 constexpr 1126 tuple(pair<_U1, _U2>&& __in) 1127 noexcept(__nothrow_constructible<_U1, _U2>()) 1128 : _Inherited(std::forward<_U1>(__in.first), 1129 std::forward<_U2>(__in.second)) { } 1130 1131 template<typename _U1, typename _U2, 1132 _ExplicitCtor<true, _U1, _U2> = false> 1133 explicit constexpr 1134 tuple(pair<_U1, _U2>&& __in) 1135 noexcept(__nothrow_constructible<_U1, _U2>()) 1136 : _Inherited(std::forward<_U1>(__in.first), 1137 std::forward<_U2>(__in.second)) { } 1138 1139 // Allocator-extended constructors. 1140 1141 template<typename _Alloc, 1142 _ImplicitDefaultCtor<is_object<_Alloc>::value, _T1, _T2> = true> 1143 _GLIBCXX20_CONSTEXPR 1144 tuple(allocator_arg_t __tag, const _Alloc& __a) 1145 : _Inherited(__tag, __a) { } 1146 1147 template<typename _Alloc, bool _Dummy = true, 1148 _ImplicitCtor<_Dummy, const _T1&, const _T2&> = true> 1149 _GLIBCXX20_CONSTEXPR 1150 tuple(allocator_arg_t __tag, const _Alloc& __a, 1151 const _T1& __a1, const _T2& __a2) 1152 : _Inherited(__tag, __a, __a1, __a2) { } 1153 1154 template<typename _Alloc, bool _Dummy = true, 1155 _ExplicitCtor<_Dummy, const _T1&, const _T2&> = false> 1156 explicit 1157 _GLIBCXX20_CONSTEXPR 1158 tuple(allocator_arg_t __tag, const _Alloc& __a, 1159 const _T1& __a1, const _T2& __a2) 1160 : _Inherited(__tag, __a, __a1, __a2) { } 1161 1162 template<typename _Alloc, typename _U1, typename _U2, 1163 _ImplicitCtor<true, _U1, _U2> = true> 1164 _GLIBCXX20_CONSTEXPR 1165 tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2) 1166 : _Inherited(__tag, __a, std::forward<_U1>(__a1), 1167 std::forward<_U2>(__a2)) { } 1168 1169 template<typename _Alloc, typename _U1, typename _U2, 1170 _ExplicitCtor<true, _U1, _U2> = false> 1171 explicit 1172 _GLIBCXX20_CONSTEXPR 1173 tuple(allocator_arg_t __tag, const _Alloc& __a, 1174 _U1&& __a1, _U2&& __a2) 1175 : _Inherited(__tag, __a, std::forward<_U1>(__a1), 1176 std::forward<_U2>(__a2)) { } 1177 1178 template<typename _Alloc> 1179 _GLIBCXX20_CONSTEXPR 1180 tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) 1181 : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { } 1182 1183 template<typename _Alloc> 1184 _GLIBCXX20_CONSTEXPR 1185 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) 1186 : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { } 1187 1188 template<typename _Alloc, typename _U1, typename _U2, 1189 _ImplicitCtor<true, const _U1&, const _U2&> = true> 1190 _GLIBCXX20_CONSTEXPR 1191 tuple(allocator_arg_t __tag, const _Alloc& __a, 1192 const tuple<_U1, _U2>& __in) 1193 : _Inherited(__tag, __a, 1194 static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) 1195 { } 1196 1197 template<typename _Alloc, typename _U1, typename _U2, 1198 _ExplicitCtor<true, const _U1&, const _U2&> = false> 1199 explicit 1200 _GLIBCXX20_CONSTEXPR 1201 tuple(allocator_arg_t __tag, const _Alloc& __a, 1202 const tuple<_U1, _U2>& __in) 1203 : _Inherited(__tag, __a, 1204 static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) 1205 { } 1206 1207 template<typename _Alloc, typename _U1, typename _U2, 1208 _ImplicitCtor<true, _U1, _U2> = true> 1209 _GLIBCXX20_CONSTEXPR 1210 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in) 1211 : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) 1212 { } 1213 1214 template<typename _Alloc, typename _U1, typename _U2, 1215 _ExplicitCtor<true, _U1, _U2> = false> 1216 explicit 1217 _GLIBCXX20_CONSTEXPR 1218 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in) 1219 : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) 1220 { } 1221 1222 template<typename _Alloc, typename _U1, typename _U2, 1223 _ImplicitCtor<true, const _U1&, const _U2&> = true> 1224 _GLIBCXX20_CONSTEXPR 1225 tuple(allocator_arg_t __tag, const _Alloc& __a, 1226 const pair<_U1, _U2>& __in) 1227 : _Inherited(__tag, __a, __in.first, __in.second) { } 1228 1229 template<typename _Alloc, typename _U1, typename _U2, 1230 _ExplicitCtor<true, const _U1&, const _U2&> = false> 1231 explicit 1232 _GLIBCXX20_CONSTEXPR 1233 tuple(allocator_arg_t __tag, const _Alloc& __a, 1234 const pair<_U1, _U2>& __in) 1235 : _Inherited(__tag, __a, __in.first, __in.second) { } 1236 1237 template<typename _Alloc, typename _U1, typename _U2, 1238 _ImplicitCtor<true, _U1, _U2> = true> 1239 _GLIBCXX20_CONSTEXPR 1240 tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in) 1241 : _Inherited(__tag, __a, std::forward<_U1>(__in.first), 1242 std::forward<_U2>(__in.second)) { } 1243 1244 template<typename _Alloc, typename _U1, typename _U2, 1245 _ExplicitCtor<true, _U1, _U2> = false> 1246 explicit 1247 _GLIBCXX20_CONSTEXPR 1248 tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in) 1249 : _Inherited(__tag, __a, std::forward<_U1>(__in.first), 1250 std::forward<_U2>(__in.second)) { } 1251 1252 // Tuple assignment. 1253 1254 _GLIBCXX20_CONSTEXPR 1255 tuple& 1256 operator=(typename conditional<__assignable<const _T1&, const _T2&>(), 1257 const tuple&, 1258 const __nonesuch&>::type __in) 1259 noexcept(__nothrow_assignable<const _T1&, const _T2&>()) 1260 { 1261 this->_M_assign(__in); 1262 return *this; 1263 } 1264 1265 _GLIBCXX20_CONSTEXPR 1266 tuple& 1267 operator=(typename conditional<__assignable<_T1, _T2>(), 1268 tuple&&, 1269 __nonesuch&&>::type __in) 1270 noexcept(__nothrow_assignable<_T1, _T2>()) 1271 { 1272 this->_M_assign(std::move(__in)); 1273 return *this; 1274 } 1275 1276 template<typename _U1, typename _U2> 1277 _GLIBCXX20_CONSTEXPR 1278 __enable_if_t<__assignable<const _U1&, const _U2&>(), tuple&> 1279 operator=(const tuple<_U1, _U2>& __in) 1280 noexcept(__nothrow_assignable<const _U1&, const _U2&>()) 1281 { 1282 this->_M_assign(__in); 1283 return *this; 1284 } 1285 1286 template<typename _U1, typename _U2> 1287 _GLIBCXX20_CONSTEXPR 1288 __enable_if_t<__assignable<_U1, _U2>(), tuple&> 1289 operator=(tuple<_U1, _U2>&& __in) 1290 noexcept(__nothrow_assignable<_U1, _U2>()) 1291 { 1292 this->_M_assign(std::move(__in)); 1293 return *this; 1294 } 1295 1296 template<typename _U1, typename _U2> 1297 _GLIBCXX20_CONSTEXPR 1298 __enable_if_t<__assignable<const _U1&, const _U2&>(), tuple&> 1299 operator=(const pair<_U1, _U2>& __in) 1300 noexcept(__nothrow_assignable<const _U1&, const _U2&>()) 1301 { 1302 this->_M_head(*this) = __in.first; 1303 this->_M_tail(*this)._M_head(*this) = __in.second; 1304 return *this; 1305 } 1306 1307 template<typename _U1, typename _U2> 1308 _GLIBCXX20_CONSTEXPR 1309 __enable_if_t<__assignable<_U1, _U2>(), tuple&> 1310 operator=(pair<_U1, _U2>&& __in) 1311 noexcept(__nothrow_assignable<_U1, _U2>()) 1312 { 1313 this->_M_head(*this) = std::forward<_U1>(__in.first); 1314 this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second); 1315 return *this; 1316 } 1317 1318 _GLIBCXX20_CONSTEXPR 1319 void 1320 swap(tuple& __in) 1321 noexcept(__and_<__is_nothrow_swappable<_T1>, 1322 __is_nothrow_swappable<_T2>>::value) 1323 { _Inherited::_M_swap(__in); } 1324 }; 1325 1326 1327 /// class tuple_size 1328 template<typename... _Elements> 1329 struct tuple_size<tuple<_Elements...>> 1330 : public integral_constant<size_t, sizeof...(_Elements)> { }; 1331 1332#if __cplusplus > 201402L 1333 template <typename _Tp> 1334 inline constexpr size_t tuple_size_v = tuple_size<_Tp>::value; 1335#endif 1336 1337 /** 1338 * Recursive case for tuple_element: strip off the first element in 1339 * the tuple and retrieve the (i-1)th element of the remaining tuple. 1340 */ 1341 template<size_t __i, typename _Head, typename... _Tail> 1342 struct tuple_element<__i, tuple<_Head, _Tail...> > 1343 : tuple_element<__i - 1, tuple<_Tail...> > { }; 1344 1345 /** 1346 * Basis case for tuple_element: The first element is the one we're seeking. 1347 */ 1348 template<typename _Head, typename... _Tail> 1349 struct tuple_element<0, tuple<_Head, _Tail...> > 1350 { 1351 typedef _Head type; 1352 }; 1353 1354 /** 1355 * Error case for tuple_element: invalid index. 1356 */ 1357 template<size_t __i> 1358 struct tuple_element<__i, tuple<>> 1359 { 1360 static_assert(__i < tuple_size<tuple<>>::value, 1361 "tuple index must be in range"); 1362 }; 1363 1364 template<size_t __i, typename _Head, typename... _Tail> 1365 constexpr _Head& 1366 __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 1367 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 1368 1369 template<size_t __i, typename _Head, typename... _Tail> 1370 constexpr const _Head& 1371 __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 1372 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 1373 1374 // Deleted overload to improve diagnostics for invalid indices 1375 template<size_t __i, typename... _Types> 1376 __enable_if_t<(__i >= sizeof...(_Types))> 1377 __get_helper(const tuple<_Types...>&) = delete; 1378 1379 /// Return a reference to the ith element of a tuple. 1380 template<size_t __i, typename... _Elements> 1381 constexpr __tuple_element_t<__i, tuple<_Elements...>>& 1382 get(tuple<_Elements...>& __t) noexcept 1383 { return std::__get_helper<__i>(__t); } 1384 1385 /// Return a const reference to the ith element of a const tuple. 1386 template<size_t __i, typename... _Elements> 1387 constexpr const __tuple_element_t<__i, tuple<_Elements...>>& 1388 get(const tuple<_Elements...>& __t) noexcept 1389 { return std::__get_helper<__i>(__t); } 1390 1391 /// Return an rvalue reference to the ith element of a tuple rvalue. 1392 template<size_t __i, typename... _Elements> 1393 constexpr __tuple_element_t<__i, tuple<_Elements...>>&& 1394 get(tuple<_Elements...>&& __t) noexcept 1395 { 1396 typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type; 1397 return std::forward<__element_type>(std::__get_helper<__i>(__t)); 1398 } 1399 1400 /// Return a const rvalue reference to the ith element of a const tuple rvalue. 1401 template<size_t __i, typename... _Elements> 1402 constexpr const __tuple_element_t<__i, tuple<_Elements...>>&& 1403 get(const tuple<_Elements...>&& __t) noexcept 1404 { 1405 typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type; 1406 return std::forward<const __element_type>(std::__get_helper<__i>(__t)); 1407 } 1408 1409#if __cplusplus >= 201402L 1410 1411#define __cpp_lib_tuples_by_type 201304 1412 1413 // Return the index of _Tp in _Types, if it occurs exactly once. 1414 // Otherwise, return sizeof...(_Types). 1415 // TODO reuse this for __detail::__variant::__exactly_once. 1416 template<typename _Tp, typename... _Types> 1417 constexpr size_t 1418 __find_uniq_type_in_pack() 1419 { 1420 constexpr size_t __sz = sizeof...(_Types); 1421 constexpr bool __found[__sz] = { __is_same(_Tp, _Types) ... }; 1422 size_t __n = __sz; 1423 for (size_t __i = 0; __i < __sz; ++__i) 1424 { 1425 if (__found[__i]) 1426 { 1427 if (__n < __sz) // more than one _Tp found 1428 return __sz; 1429 __n = __i; 1430 } 1431 } 1432 return __n; 1433 } 1434 1435 /// Return a reference to the unique element of type _Tp of a tuple. 1436 template <typename _Tp, typename... _Types> 1437 constexpr _Tp& 1438 get(tuple<_Types...>& __t) noexcept 1439 { 1440 constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>(); 1441 static_assert(__idx < sizeof...(_Types), 1442 "the type T in std::get<T> must occur exactly once in the tuple"); 1443 return std::__get_helper<__idx>(__t); 1444 } 1445 1446 /// Return a reference to the unique element of type _Tp of a tuple rvalue. 1447 template <typename _Tp, typename... _Types> 1448 constexpr _Tp&& 1449 get(tuple<_Types...>&& __t) noexcept 1450 { 1451 constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>(); 1452 static_assert(__idx < sizeof...(_Types), 1453 "the type T in std::get<T> must occur exactly once in the tuple"); 1454 return std::forward<_Tp>(std::__get_helper<__idx>(__t)); 1455 } 1456 1457 /// Return a const reference to the unique element of type _Tp of a tuple. 1458 template <typename _Tp, typename... _Types> 1459 constexpr const _Tp& 1460 get(const tuple<_Types...>& __t) noexcept 1461 { 1462 constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>(); 1463 static_assert(__idx < sizeof...(_Types), 1464 "the type T in std::get<T> must occur exactly once in the tuple"); 1465 return std::__get_helper<__idx>(__t); 1466 } 1467 1468 /// Return a const reference to the unique element of type _Tp of 1469 /// a const tuple rvalue. 1470 template <typename _Tp, typename... _Types> 1471 constexpr const _Tp&& 1472 get(const tuple<_Types...>&& __t) noexcept 1473 { 1474 constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>(); 1475 static_assert(__idx < sizeof...(_Types), 1476 "the type T in std::get<T> must occur exactly once in the tuple"); 1477 return std::forward<const _Tp>(std::__get_helper<__idx>(__t)); 1478 } 1479#endif 1480 1481 // This class performs the comparison operations on tuples 1482 template<typename _Tp, typename _Up, size_t __i, size_t __size> 1483 struct __tuple_compare 1484 { 1485 static constexpr bool 1486 __eq(const _Tp& __t, const _Up& __u) 1487 { 1488 return bool(std::get<__i>(__t) == std::get<__i>(__u)) 1489 && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u); 1490 } 1491 1492 static constexpr bool 1493 __less(const _Tp& __t, const _Up& __u) 1494 { 1495 return bool(std::get<__i>(__t) < std::get<__i>(__u)) 1496 || (!bool(std::get<__i>(__u) < std::get<__i>(__t)) 1497 && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u)); 1498 } 1499 }; 1500 1501 template<typename _Tp, typename _Up, size_t __size> 1502 struct __tuple_compare<_Tp, _Up, __size, __size> 1503 { 1504 static constexpr bool 1505 __eq(const _Tp&, const _Up&) { return true; } 1506 1507 static constexpr bool 1508 __less(const _Tp&, const _Up&) { return false; } 1509 }; 1510 1511 template<typename... _TElements, typename... _UElements> 1512 constexpr bool 1513 operator==(const tuple<_TElements...>& __t, 1514 const tuple<_UElements...>& __u) 1515 { 1516 static_assert(sizeof...(_TElements) == sizeof...(_UElements), 1517 "tuple objects can only be compared if they have equal sizes."); 1518 using __compare = __tuple_compare<tuple<_TElements...>, 1519 tuple<_UElements...>, 1520 0, sizeof...(_TElements)>; 1521 return __compare::__eq(__t, __u); 1522 } 1523 1524#if __cpp_lib_three_way_comparison 1525 template<typename _Cat, typename _Tp, typename _Up> 1526 constexpr _Cat 1527 __tuple_cmp(const _Tp&, const _Up&, index_sequence<>) 1528 { return _Cat::equivalent; } 1529 1530 template<typename _Cat, typename _Tp, typename _Up, 1531 size_t _Idx0, size_t... _Idxs> 1532 constexpr _Cat 1533 __tuple_cmp(const _Tp& __t, const _Up& __u, 1534 index_sequence<_Idx0, _Idxs...>) 1535 { 1536 auto __c 1537 = __detail::__synth3way(std::get<_Idx0>(__t), std::get<_Idx0>(__u)); 1538 if (__c != 0) 1539 return __c; 1540 return std::__tuple_cmp<_Cat>(__t, __u, index_sequence<_Idxs...>()); 1541 } 1542 1543 template<typename... _Tps, typename... _Ups> 1544 constexpr 1545 common_comparison_category_t<__detail::__synth3way_t<_Tps, _Ups>...> 1546 operator<=>(const tuple<_Tps...>& __t, const tuple<_Ups...>& __u) 1547 { 1548 using _Cat 1549 = common_comparison_category_t<__detail::__synth3way_t<_Tps, _Ups>...>; 1550 return std::__tuple_cmp<_Cat>(__t, __u, index_sequence_for<_Tps...>()); 1551 } 1552#else 1553 template<typename... _TElements, typename... _UElements> 1554 constexpr bool 1555 operator<(const tuple<_TElements...>& __t, 1556 const tuple<_UElements...>& __u) 1557 { 1558 static_assert(sizeof...(_TElements) == sizeof...(_UElements), 1559 "tuple objects can only be compared if they have equal sizes."); 1560 using __compare = __tuple_compare<tuple<_TElements...>, 1561 tuple<_UElements...>, 1562 0, sizeof...(_TElements)>; 1563 return __compare::__less(__t, __u); 1564 } 1565 1566 template<typename... _TElements, typename... _UElements> 1567 constexpr bool 1568 operator!=(const tuple<_TElements...>& __t, 1569 const tuple<_UElements...>& __u) 1570 { return !(__t == __u); } 1571 1572 template<typename... _TElements, typename... _UElements> 1573 constexpr bool 1574 operator>(const tuple<_TElements...>& __t, 1575 const tuple<_UElements...>& __u) 1576 { return __u < __t; } 1577 1578 template<typename... _TElements, typename... _UElements> 1579 constexpr bool 1580 operator<=(const tuple<_TElements...>& __t, 1581 const tuple<_UElements...>& __u) 1582 { return !(__u < __t); } 1583 1584 template<typename... _TElements, typename... _UElements> 1585 constexpr bool 1586 operator>=(const tuple<_TElements...>& __t, 1587 const tuple<_UElements...>& __u) 1588 { return !(__t < __u); } 1589#endif // three_way_comparison 1590 1591 // NB: DR 705. 1592 template<typename... _Elements> 1593 constexpr tuple<typename __decay_and_strip<_Elements>::__type...> 1594 make_tuple(_Elements&&... __args) 1595 { 1596 typedef tuple<typename __decay_and_strip<_Elements>::__type...> 1597 __result_type; 1598 return __result_type(std::forward<_Elements>(__args)...); 1599 } 1600 1601 // _GLIBCXX_RESOLVE_LIB_DEFECTS 1602 // 2275. Why is forward_as_tuple not constexpr? 1603 /// std::forward_as_tuple 1604 template<typename... _Elements> 1605 constexpr tuple<_Elements&&...> 1606 forward_as_tuple(_Elements&&... __args) noexcept 1607 { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); } 1608 1609 template<size_t, typename, typename, size_t> 1610 struct __make_tuple_impl; 1611 1612 template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm> 1613 struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm> 1614 : __make_tuple_impl<_Idx + 1, 1615 tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>, 1616 _Tuple, _Nm> 1617 { }; 1618 1619 template<size_t _Nm, typename _Tuple, typename... _Tp> 1620 struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm> 1621 { 1622 typedef tuple<_Tp...> __type; 1623 }; 1624 1625 template<typename _Tuple> 1626 struct __do_make_tuple 1627 : __make_tuple_impl<0, tuple<>, _Tuple, tuple_size<_Tuple>::value> 1628 { }; 1629 1630 // Returns the std::tuple equivalent of a tuple-like type. 1631 template<typename _Tuple> 1632 struct __make_tuple 1633 : public __do_make_tuple<__remove_cvref_t<_Tuple>> 1634 { }; 1635 1636 // Combines several std::tuple's into a single one. 1637 template<typename...> 1638 struct __combine_tuples; 1639 1640 template<> 1641 struct __combine_tuples<> 1642 { 1643 typedef tuple<> __type; 1644 }; 1645 1646 template<typename... _Ts> 1647 struct __combine_tuples<tuple<_Ts...>> 1648 { 1649 typedef tuple<_Ts...> __type; 1650 }; 1651 1652 template<typename... _T1s, typename... _T2s, typename... _Rem> 1653 struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...> 1654 { 1655 typedef typename __combine_tuples<tuple<_T1s..., _T2s...>, 1656 _Rem...>::__type __type; 1657 }; 1658 1659 // Computes the result type of tuple_cat given a set of tuple-like types. 1660 template<typename... _Tpls> 1661 struct __tuple_cat_result 1662 { 1663 typedef typename __combine_tuples 1664 <typename __make_tuple<_Tpls>::__type...>::__type __type; 1665 }; 1666 1667 // Helper to determine the index set for the first tuple-like 1668 // type of a given set. 1669 template<typename...> 1670 struct __make_1st_indices; 1671 1672 template<> 1673 struct __make_1st_indices<> 1674 { 1675 typedef _Index_tuple<> __type; 1676 }; 1677 1678 template<typename _Tp, typename... _Tpls> 1679 struct __make_1st_indices<_Tp, _Tpls...> 1680 { 1681 typedef typename _Build_index_tuple<tuple_size< 1682 typename remove_reference<_Tp>::type>::value>::__type __type; 1683 }; 1684 1685 // Performs the actual concatenation by step-wise expanding tuple-like 1686 // objects into the elements, which are finally forwarded into the 1687 // result tuple. 1688 template<typename _Ret, typename _Indices, typename... _Tpls> 1689 struct __tuple_concater; 1690 1691 template<typename _Ret, size_t... _Is, typename _Tp, typename... _Tpls> 1692 struct __tuple_concater<_Ret, _Index_tuple<_Is...>, _Tp, _Tpls...> 1693 { 1694 template<typename... _Us> 1695 static constexpr _Ret 1696 _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us) 1697 { 1698 typedef typename __make_1st_indices<_Tpls...>::__type __idx; 1699 typedef __tuple_concater<_Ret, __idx, _Tpls...> __next; 1700 return __next::_S_do(std::forward<_Tpls>(__tps)..., 1701 std::forward<_Us>(__us)..., 1702 std::get<_Is>(std::forward<_Tp>(__tp))...); 1703 } 1704 }; 1705 1706 template<typename _Ret> 1707 struct __tuple_concater<_Ret, _Index_tuple<>> 1708 { 1709 template<typename... _Us> 1710 static constexpr _Ret 1711 _S_do(_Us&&... __us) 1712 { 1713 return _Ret(std::forward<_Us>(__us)...); 1714 } 1715 }; 1716 1717 /// tuple_cat 1718 template<typename... _Tpls, typename = typename 1719 enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type> 1720 constexpr auto 1721 tuple_cat(_Tpls&&... __tpls) 1722 -> typename __tuple_cat_result<_Tpls...>::__type 1723 { 1724 typedef typename __tuple_cat_result<_Tpls...>::__type __ret; 1725 typedef typename __make_1st_indices<_Tpls...>::__type __idx; 1726 typedef __tuple_concater<__ret, __idx, _Tpls...> __concater; 1727 return __concater::_S_do(std::forward<_Tpls>(__tpls)...); 1728 } 1729 1730 // _GLIBCXX_RESOLVE_LIB_DEFECTS 1731 // 2301. Why is tie not constexpr? 1732 /// tie 1733 template<typename... _Elements> 1734 constexpr tuple<_Elements&...> 1735 tie(_Elements&... __args) noexcept 1736 { return tuple<_Elements&...>(__args...); } 1737 1738 /// swap 1739 template<typename... _Elements> 1740 _GLIBCXX20_CONSTEXPR 1741 inline 1742#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 1743 // Constrained free swap overload, see p0185r1 1744 typename enable_if<__and_<__is_swappable<_Elements>...>::value 1745 >::type 1746#else 1747 void 1748#endif 1749 swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y) 1750 noexcept(noexcept(__x.swap(__y))) 1751 { __x.swap(__y); } 1752 1753#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 1754 template<typename... _Elements> 1755 _GLIBCXX20_CONSTEXPR 1756 typename enable_if<!__and_<__is_swappable<_Elements>...>::value>::type 1757 swap(tuple<_Elements...>&, tuple<_Elements...>&) = delete; 1758#endif 1759 1760 // A class (and instance) which can be used in 'tie' when an element 1761 // of a tuple is not required. 1762 // _GLIBCXX14_CONSTEXPR 1763 // 2933. PR for LWG 2773 could be clearer 1764 struct _Swallow_assign 1765 { 1766 template<class _Tp> 1767 _GLIBCXX14_CONSTEXPR const _Swallow_assign& 1768 operator=(const _Tp&) const 1769 { return *this; } 1770 }; 1771 1772 // _GLIBCXX_RESOLVE_LIB_DEFECTS 1773 // 2773. Making std::ignore constexpr 1774 _GLIBCXX17_INLINE constexpr _Swallow_assign ignore{}; 1775 1776 /// Partial specialization for tuples 1777 template<typename... _Types, typename _Alloc> 1778 struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { }; 1779 1780 // See stl_pair.h... 1781 /** "piecewise construction" using a tuple of arguments for each member. 1782 * 1783 * @param __first Arguments for the first member of the pair. 1784 * @param __second Arguments for the second member of the pair. 1785 * 1786 * The elements of each tuple will be used as the constructor arguments 1787 * for the data members of the pair. 1788 */ 1789 template<class _T1, class _T2> 1790 template<typename... _Args1, typename... _Args2> 1791 _GLIBCXX20_CONSTEXPR 1792 inline 1793 pair<_T1, _T2>:: 1794 pair(piecewise_construct_t, 1795 tuple<_Args1...> __first, tuple<_Args2...> __second) 1796 : pair(__first, __second, 1797 typename _Build_index_tuple<sizeof...(_Args1)>::__type(), 1798 typename _Build_index_tuple<sizeof...(_Args2)>::__type()) 1799 { } 1800 1801 template<class _T1, class _T2> 1802 template<typename... _Args1, size_t... _Indexes1, 1803 typename... _Args2, size_t... _Indexes2> 1804 _GLIBCXX20_CONSTEXPR inline 1805 pair<_T1, _T2>:: 1806 pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2, 1807 _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>) 1808 : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...), 1809 second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...) 1810 { } 1811 1812#if __cplusplus >= 201703L 1813 1814 // Unpack a std::tuple into a type trait and use its value. 1815 // For cv std::tuple<_Up> the result is _Trait<_Tp, cv _Up...>::value. 1816 // For cv std::tuple<_Up>& the result is _Trait<_Tp, cv _Up&...>::value. 1817 // Otherwise the result is false (because we don't know if std::get throws). 1818 template<template<typename...> class _Trait, typename _Tp, typename _Tuple> 1819 inline constexpr bool __unpack_std_tuple = false; 1820 1821 template<template<typename...> class _Trait, typename _Tp, typename... _Up> 1822 inline constexpr bool __unpack_std_tuple<_Trait, _Tp, tuple<_Up...>> 1823 = _Trait<_Tp, _Up...>::value; 1824 1825 template<template<typename...> class _Trait, typename _Tp, typename... _Up> 1826 inline constexpr bool __unpack_std_tuple<_Trait, _Tp, tuple<_Up...>&> 1827 = _Trait<_Tp, _Up&...>::value; 1828 1829 template<template<typename...> class _Trait, typename _Tp, typename... _Up> 1830 inline constexpr bool __unpack_std_tuple<_Trait, _Tp, const tuple<_Up...>> 1831 = _Trait<_Tp, const _Up...>::value; 1832 1833 template<template<typename...> class _Trait, typename _Tp, typename... _Up> 1834 inline constexpr bool __unpack_std_tuple<_Trait, _Tp, const tuple<_Up...>&> 1835 = _Trait<_Tp, const _Up&...>::value; 1836 1837# define __cpp_lib_apply 201603 1838 1839 template <typename _Fn, typename _Tuple, size_t... _Idx> 1840 constexpr decltype(auto) 1841 __apply_impl(_Fn&& __f, _Tuple&& __t, index_sequence<_Idx...>) 1842 { 1843 return std::__invoke(std::forward<_Fn>(__f), 1844 std::get<_Idx>(std::forward<_Tuple>(__t))...); 1845 } 1846 1847 template <typename _Fn, typename _Tuple> 1848 constexpr decltype(auto) 1849 apply(_Fn&& __f, _Tuple&& __t) 1850 noexcept(__unpack_std_tuple<is_nothrow_invocable, _Fn, _Tuple>) 1851 { 1852 using _Indices 1853 = make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>; 1854 return std::__apply_impl(std::forward<_Fn>(__f), 1855 std::forward<_Tuple>(__t), 1856 _Indices{}); 1857 } 1858 1859#define __cpp_lib_make_from_tuple 201606 1860 1861 template <typename _Tp, typename _Tuple, size_t... _Idx> 1862 constexpr _Tp 1863 __make_from_tuple_impl(_Tuple&& __t, index_sequence<_Idx...>) 1864 { return _Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...); } 1865 1866 template <typename _Tp, typename _Tuple> 1867 constexpr _Tp 1868 make_from_tuple(_Tuple&& __t) 1869 noexcept(__unpack_std_tuple<is_nothrow_constructible, _Tp, _Tuple>) 1870 { 1871 return __make_from_tuple_impl<_Tp>( 1872 std::forward<_Tuple>(__t), 1873 make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>{}); 1874 } 1875#endif // C++17 1876 1877 /// @} 1878 1879_GLIBCXX_END_NAMESPACE_VERSION 1880} // namespace std 1881 1882#endif // C++11 1883 1884#endif // _GLIBCXX_TUPLE 1885