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