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, 805 _ExplicitDefaultCtor<is_object<_Alloc>::value> = false> 806 _GLIBCXX20_CONSTEXPR 807 explicit 808 tuple(allocator_arg_t __tag, const _Alloc& __a) 809 : _Inherited(__tag, __a) { } 810 811 template<typename _Alloc, bool _NotEmpty = (sizeof...(_Elements) >= 1), 812 _ImplicitCtor<_NotEmpty, const _Elements&...> = true> 813 _GLIBCXX20_CONSTEXPR 814 tuple(allocator_arg_t __tag, const _Alloc& __a, 815 const _Elements&... __elements) 816 : _Inherited(__tag, __a, __elements...) { } 817 818 template<typename _Alloc, bool _NotEmpty = (sizeof...(_Elements) >= 1), 819 _ExplicitCtor<_NotEmpty, const _Elements&...> = false> 820 _GLIBCXX20_CONSTEXPR 821 explicit 822 tuple(allocator_arg_t __tag, const _Alloc& __a, 823 const _Elements&... __elements) 824 : _Inherited(__tag, __a, __elements...) { } 825 826 template<typename _Alloc, typename... _UElements, 827 bool _Valid = __valid_args<_UElements...>(), 828 _ImplicitCtor<_Valid, _UElements...> = true> 829 _GLIBCXX20_CONSTEXPR 830 tuple(allocator_arg_t __tag, const _Alloc& __a, 831 _UElements&&... __elements) 832 : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...) 833 { } 834 835 template<typename _Alloc, typename... _UElements, 836 bool _Valid = __valid_args<_UElements...>(), 837 _ExplicitCtor<_Valid, _UElements...> = false> 838 _GLIBCXX20_CONSTEXPR 839 explicit 840 tuple(allocator_arg_t __tag, const _Alloc& __a, 841 _UElements&&... __elements) 842 : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...) 843 { } 844 845 template<typename _Alloc> 846 _GLIBCXX20_CONSTEXPR 847 tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) 848 : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { } 849 850 template<typename _Alloc> 851 _GLIBCXX20_CONSTEXPR 852 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) 853 : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { } 854 855 template<typename _Alloc, typename... _UElements, 856 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) 857 && !__use_other_ctor<const tuple<_UElements...>&>(), 858 _ImplicitCtor<_Valid, const _UElements&...> = true> 859 _GLIBCXX20_CONSTEXPR 860 tuple(allocator_arg_t __tag, const _Alloc& __a, 861 const tuple<_UElements...>& __in) 862 : _Inherited(__tag, __a, 863 static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) 864 { } 865 866 template<typename _Alloc, typename... _UElements, 867 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) 868 && !__use_other_ctor<const tuple<_UElements...>&>(), 869 _ExplicitCtor<_Valid, const _UElements&...> = false> 870 _GLIBCXX20_CONSTEXPR 871 explicit 872 tuple(allocator_arg_t __tag, const _Alloc& __a, 873 const tuple<_UElements...>& __in) 874 : _Inherited(__tag, __a, 875 static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) 876 { } 877 878 template<typename _Alloc, typename... _UElements, 879 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) 880 && !__use_other_ctor<tuple<_UElements...>&&>(), 881 _ImplicitCtor<_Valid, _UElements...> = true> 882 _GLIBCXX20_CONSTEXPR 883 tuple(allocator_arg_t __tag, const _Alloc& __a, 884 tuple<_UElements...>&& __in) 885 : _Inherited(__tag, __a, 886 static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) 887 { } 888 889 template<typename _Alloc, typename... _UElements, 890 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements)) 891 && !__use_other_ctor<tuple<_UElements...>&&>(), 892 _ExplicitCtor<_Valid, _UElements...> = false> 893 _GLIBCXX20_CONSTEXPR 894 explicit 895 tuple(allocator_arg_t __tag, const _Alloc& __a, 896 tuple<_UElements...>&& __in) 897 : _Inherited(__tag, __a, 898 static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) 899 { } 900 901 // tuple assignment 902 903 _GLIBCXX20_CONSTEXPR 904 tuple& 905 operator=(__conditional_t<__assignable<const _Elements&...>(), 906 const tuple&, 907 const __nonesuch&> __in) 908 noexcept(__nothrow_assignable<const _Elements&...>()) 909 { 910 this->_M_assign(__in); 911 return *this; 912 } 913 914 _GLIBCXX20_CONSTEXPR 915 tuple& 916 operator=(__conditional_t<__assignable<_Elements...>(), 917 tuple&&, 918 __nonesuch&&> __in) 919 noexcept(__nothrow_assignable<_Elements...>()) 920 { 921 this->_M_assign(std::move(__in)); 922 return *this; 923 } 924 925 template<typename... _UElements> 926 _GLIBCXX20_CONSTEXPR 927 __enable_if_t<__assignable<const _UElements&...>(), tuple&> 928 operator=(const tuple<_UElements...>& __in) 929 noexcept(__nothrow_assignable<const _UElements&...>()) 930 { 931 this->_M_assign(__in); 932 return *this; 933 } 934 935 template<typename... _UElements> 936 _GLIBCXX20_CONSTEXPR 937 __enable_if_t<__assignable<_UElements...>(), tuple&> 938 operator=(tuple<_UElements...>&& __in) 939 noexcept(__nothrow_assignable<_UElements...>()) 940 { 941 this->_M_assign(std::move(__in)); 942 return *this; 943 } 944 945 // tuple swap 946 _GLIBCXX20_CONSTEXPR 947 void 948 swap(tuple& __in) 949 noexcept(__and_<__is_nothrow_swappable<_Elements>...>::value) 950 { _Inherited::_M_swap(__in); } 951 }; 952 953#if __cpp_deduction_guides >= 201606 954 template<typename... _UTypes> 955 tuple(_UTypes...) -> tuple<_UTypes...>; 956 template<typename _T1, typename _T2> 957 tuple(pair<_T1, _T2>) -> tuple<_T1, _T2>; 958 template<typename _Alloc, typename... _UTypes> 959 tuple(allocator_arg_t, _Alloc, _UTypes...) -> tuple<_UTypes...>; 960 template<typename _Alloc, typename _T1, typename _T2> 961 tuple(allocator_arg_t, _Alloc, pair<_T1, _T2>) -> tuple<_T1, _T2>; 962 template<typename _Alloc, typename... _UTypes> 963 tuple(allocator_arg_t, _Alloc, tuple<_UTypes...>) -> tuple<_UTypes...>; 964#endif 965 966 // Explicit specialization, zero-element tuple. 967 template<> 968 class tuple<> 969 { 970 public: 971 _GLIBCXX20_CONSTEXPR 972 void swap(tuple&) noexcept { /* no-op */ } 973 // We need the default since we're going to define no-op 974 // allocator constructors. 975 tuple() = default; 976 // No-op allocator constructors. 977 template<typename _Alloc> 978 _GLIBCXX20_CONSTEXPR 979 tuple(allocator_arg_t, const _Alloc&) noexcept { } 980 template<typename _Alloc> 981 _GLIBCXX20_CONSTEXPR 982 tuple(allocator_arg_t, const _Alloc&, const tuple&) noexcept { } 983 }; 984 985 /// Partial specialization, 2-element tuple. 986 /// Includes construction and assignment from a pair. 987 template<typename _T1, typename _T2> 988 class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2> 989 { 990 typedef _Tuple_impl<0, _T1, _T2> _Inherited; 991 992 // Constraint for non-explicit default constructor 993 template<bool _Dummy, typename _U1, typename _U2> 994 using _ImplicitDefaultCtor = __enable_if_t< 995 _TupleConstraints<_Dummy, _U1, _U2>:: 996 __is_implicitly_default_constructible(), 997 bool>; 998 999 // Constraint for explicit default constructor 1000 template<bool _Dummy, typename _U1, typename _U2> 1001 using _ExplicitDefaultCtor = __enable_if_t< 1002 _TupleConstraints<_Dummy, _U1, _U2>:: 1003 __is_explicitly_default_constructible(), 1004 bool>; 1005 1006 template<bool _Dummy> 1007 using _TCC = _TupleConstraints<_Dummy, _T1, _T2>; 1008 1009 // Constraint for non-explicit constructors 1010 template<bool _Cond, typename _U1, typename _U2> 1011 using _ImplicitCtor = __enable_if_t< 1012 _TCC<_Cond>::template __is_implicitly_constructible<_U1, _U2>(), 1013 bool>; 1014 1015 // Constraint for non-explicit constructors 1016 template<bool _Cond, typename _U1, typename _U2> 1017 using _ExplicitCtor = __enable_if_t< 1018 _TCC<_Cond>::template __is_explicitly_constructible<_U1, _U2>(), 1019 bool>; 1020 1021 template<typename _U1, typename _U2> 1022 static constexpr bool __assignable() 1023 { 1024 return __and_<is_assignable<_T1&, _U1>, 1025 is_assignable<_T2&, _U2>>::value; 1026 } 1027 1028 template<typename _U1, typename _U2> 1029 static constexpr bool __nothrow_assignable() 1030 { 1031 return __and_<is_nothrow_assignable<_T1&, _U1>, 1032 is_nothrow_assignable<_T2&, _U2>>::value; 1033 } 1034 1035 template<typename _U1, typename _U2> 1036 static constexpr bool __nothrow_constructible() 1037 { 1038 return __and_<is_nothrow_constructible<_T1, _U1>, 1039 is_nothrow_constructible<_T2, _U2>>::value; 1040 } 1041 1042 static constexpr bool __nothrow_default_constructible() 1043 { 1044 return __and_<is_nothrow_default_constructible<_T1>, 1045 is_nothrow_default_constructible<_T2>>::value; 1046 } 1047 1048 template<typename _U1> 1049 static constexpr bool __is_alloc_arg() 1050 { return is_same<__remove_cvref_t<_U1>, allocator_arg_t>::value; } 1051 1052 public: 1053 template<bool _Dummy = true, 1054 _ImplicitDefaultCtor<_Dummy, _T1, _T2> = true> 1055 constexpr 1056 tuple() 1057 noexcept(__nothrow_default_constructible()) 1058 : _Inherited() { } 1059 1060 template<bool _Dummy = true, 1061 _ExplicitDefaultCtor<_Dummy, _T1, _T2> = false> 1062 explicit constexpr 1063 tuple() 1064 noexcept(__nothrow_default_constructible()) 1065 : _Inherited() { } 1066 1067 template<bool _Dummy = true, 1068 _ImplicitCtor<_Dummy, const _T1&, const _T2&> = true> 1069 constexpr 1070 tuple(const _T1& __a1, const _T2& __a2) 1071 noexcept(__nothrow_constructible<const _T1&, const _T2&>()) 1072 : _Inherited(__a1, __a2) { } 1073 1074 template<bool _Dummy = true, 1075 _ExplicitCtor<_Dummy, const _T1&, const _T2&> = false> 1076 explicit constexpr 1077 tuple(const _T1& __a1, const _T2& __a2) 1078 noexcept(__nothrow_constructible<const _T1&, const _T2&>()) 1079 : _Inherited(__a1, __a2) { } 1080 1081 template<typename _U1, typename _U2, 1082 _ImplicitCtor<!__is_alloc_arg<_U1>(), _U1, _U2> = true> 1083 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 template<typename _U1, typename _U2, 1089 _ExplicitCtor<!__is_alloc_arg<_U1>(), _U1, _U2> = false> 1090 explicit constexpr 1091 tuple(_U1&& __a1, _U2&& __a2) 1092 noexcept(__nothrow_constructible<_U1, _U2>()) 1093 : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } 1094 1095 constexpr tuple(const tuple&) = default; 1096 1097 constexpr tuple(tuple&&) = default; 1098 1099 template<typename _U1, typename _U2, 1100 _ImplicitCtor<true, const _U1&, const _U2&> = true> 1101 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 _ExplicitCtor<true, const _U1&, const _U2&> = false> 1108 explicit constexpr 1109 tuple(const tuple<_U1, _U2>& __in) 1110 noexcept(__nothrow_constructible<const _U1&, const _U2&>()) 1111 : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { } 1112 1113 template<typename _U1, typename _U2, 1114 _ImplicitCtor<true, _U1, _U2> = true> 1115 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 _ExplicitCtor<true, _U1, _U2> = false> 1122 explicit constexpr 1123 tuple(tuple<_U1, _U2>&& __in) 1124 noexcept(__nothrow_constructible<_U1, _U2>()) 1125 : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } 1126 1127 template<typename _U1, typename _U2, 1128 _ImplicitCtor<true, const _U1&, const _U2&> = true> 1129 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 _ExplicitCtor<true, const _U1&, const _U2&> = false> 1136 explicit constexpr 1137 tuple(const pair<_U1, _U2>& __in) 1138 noexcept(__nothrow_constructible<const _U1&, const _U2&>()) 1139 : _Inherited(__in.first, __in.second) { } 1140 1141 template<typename _U1, typename _U2, 1142 _ImplicitCtor<true, _U1, _U2> = true> 1143 constexpr 1144 tuple(pair<_U1, _U2>&& __in) 1145 noexcept(__nothrow_constructible<_U1, _U2>()) 1146 : _Inherited(std::forward<_U1>(__in.first), 1147 std::forward<_U2>(__in.second)) { } 1148 1149 template<typename _U1, typename _U2, 1150 _ExplicitCtor<true, _U1, _U2> = false> 1151 explicit constexpr 1152 tuple(pair<_U1, _U2>&& __in) 1153 noexcept(__nothrow_constructible<_U1, _U2>()) 1154 : _Inherited(std::forward<_U1>(__in.first), 1155 std::forward<_U2>(__in.second)) { } 1156 1157 // Allocator-extended constructors. 1158 1159 template<typename _Alloc, 1160 _ImplicitDefaultCtor<is_object<_Alloc>::value, _T1, _T2> = true> 1161 _GLIBCXX20_CONSTEXPR 1162 tuple(allocator_arg_t __tag, const _Alloc& __a) 1163 : _Inherited(__tag, __a) { } 1164 1165 template<typename _Alloc, 1166 _ExplicitDefaultCtor<is_object<_Alloc>::value, _T1, _T2> = false> 1167 _GLIBCXX20_CONSTEXPR 1168 explicit 1169 tuple(allocator_arg_t __tag, const _Alloc& __a) 1170 : _Inherited(__tag, __a) { } 1171 1172 template<typename _Alloc, bool _Dummy = true, 1173 _ImplicitCtor<_Dummy, const _T1&, const _T2&> = true> 1174 _GLIBCXX20_CONSTEXPR 1175 tuple(allocator_arg_t __tag, const _Alloc& __a, 1176 const _T1& __a1, const _T2& __a2) 1177 : _Inherited(__tag, __a, __a1, __a2) { } 1178 1179 template<typename _Alloc, bool _Dummy = true, 1180 _ExplicitCtor<_Dummy, const _T1&, const _T2&> = false> 1181 explicit 1182 _GLIBCXX20_CONSTEXPR 1183 tuple(allocator_arg_t __tag, const _Alloc& __a, 1184 const _T1& __a1, const _T2& __a2) 1185 : _Inherited(__tag, __a, __a1, __a2) { } 1186 1187 template<typename _Alloc, typename _U1, typename _U2, 1188 _ImplicitCtor<true, _U1, _U2> = true> 1189 _GLIBCXX20_CONSTEXPR 1190 tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2) 1191 : _Inherited(__tag, __a, std::forward<_U1>(__a1), 1192 std::forward<_U2>(__a2)) { } 1193 1194 template<typename _Alloc, typename _U1, typename _U2, 1195 _ExplicitCtor<true, _U1, _U2> = false> 1196 explicit 1197 _GLIBCXX20_CONSTEXPR 1198 tuple(allocator_arg_t __tag, const _Alloc& __a, 1199 _U1&& __a1, _U2&& __a2) 1200 : _Inherited(__tag, __a, std::forward<_U1>(__a1), 1201 std::forward<_U2>(__a2)) { } 1202 1203 template<typename _Alloc> 1204 _GLIBCXX20_CONSTEXPR 1205 tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) 1206 : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { } 1207 1208 template<typename _Alloc> 1209 _GLIBCXX20_CONSTEXPR 1210 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) 1211 : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { } 1212 1213 template<typename _Alloc, typename _U1, typename _U2, 1214 _ImplicitCtor<true, const _U1&, const _U2&> = true> 1215 _GLIBCXX20_CONSTEXPR 1216 tuple(allocator_arg_t __tag, const _Alloc& __a, 1217 const tuple<_U1, _U2>& __in) 1218 : _Inherited(__tag, __a, 1219 static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) 1220 { } 1221 1222 template<typename _Alloc, typename _U1, typename _U2, 1223 _ExplicitCtor<true, const _U1&, const _U2&> = false> 1224 explicit 1225 _GLIBCXX20_CONSTEXPR 1226 tuple(allocator_arg_t __tag, const _Alloc& __a, 1227 const tuple<_U1, _U2>& __in) 1228 : _Inherited(__tag, __a, 1229 static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) 1230 { } 1231 1232 template<typename _Alloc, typename _U1, typename _U2, 1233 _ImplicitCtor<true, _U1, _U2> = true> 1234 _GLIBCXX20_CONSTEXPR 1235 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in) 1236 : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) 1237 { } 1238 1239 template<typename _Alloc, typename _U1, typename _U2, 1240 _ExplicitCtor<true, _U1, _U2> = false> 1241 explicit 1242 _GLIBCXX20_CONSTEXPR 1243 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in) 1244 : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) 1245 { } 1246 1247 template<typename _Alloc, typename _U1, typename _U2, 1248 _ImplicitCtor<true, const _U1&, const _U2&> = true> 1249 _GLIBCXX20_CONSTEXPR 1250 tuple(allocator_arg_t __tag, const _Alloc& __a, 1251 const pair<_U1, _U2>& __in) 1252 : _Inherited(__tag, __a, __in.first, __in.second) { } 1253 1254 template<typename _Alloc, typename _U1, typename _U2, 1255 _ExplicitCtor<true, const _U1&, const _U2&> = false> 1256 explicit 1257 _GLIBCXX20_CONSTEXPR 1258 tuple(allocator_arg_t __tag, const _Alloc& __a, 1259 const pair<_U1, _U2>& __in) 1260 : _Inherited(__tag, __a, __in.first, __in.second) { } 1261 1262 template<typename _Alloc, typename _U1, typename _U2, 1263 _ImplicitCtor<true, _U1, _U2> = true> 1264 _GLIBCXX20_CONSTEXPR 1265 tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in) 1266 : _Inherited(__tag, __a, std::forward<_U1>(__in.first), 1267 std::forward<_U2>(__in.second)) { } 1268 1269 template<typename _Alloc, typename _U1, typename _U2, 1270 _ExplicitCtor<true, _U1, _U2> = false> 1271 explicit 1272 _GLIBCXX20_CONSTEXPR 1273 tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in) 1274 : _Inherited(__tag, __a, std::forward<_U1>(__in.first), 1275 std::forward<_U2>(__in.second)) { } 1276 1277 // Tuple assignment. 1278 1279 _GLIBCXX20_CONSTEXPR 1280 tuple& 1281 operator=(__conditional_t<__assignable<const _T1&, const _T2&>(), 1282 const tuple&, 1283 const __nonesuch&> __in) 1284 noexcept(__nothrow_assignable<const _T1&, const _T2&>()) 1285 { 1286 this->_M_assign(__in); 1287 return *this; 1288 } 1289 1290 _GLIBCXX20_CONSTEXPR 1291 tuple& 1292 operator=(__conditional_t<__assignable<_T1, _T2>(), 1293 tuple&&, 1294 __nonesuch&&> __in) 1295 noexcept(__nothrow_assignable<_T1, _T2>()) 1296 { 1297 this->_M_assign(std::move(__in)); 1298 return *this; 1299 } 1300 1301 template<typename _U1, typename _U2> 1302 _GLIBCXX20_CONSTEXPR 1303 __enable_if_t<__assignable<const _U1&, const _U2&>(), tuple&> 1304 operator=(const tuple<_U1, _U2>& __in) 1305 noexcept(__nothrow_assignable<const _U1&, const _U2&>()) 1306 { 1307 this->_M_assign(__in); 1308 return *this; 1309 } 1310 1311 template<typename _U1, typename _U2> 1312 _GLIBCXX20_CONSTEXPR 1313 __enable_if_t<__assignable<_U1, _U2>(), tuple&> 1314 operator=(tuple<_U1, _U2>&& __in) 1315 noexcept(__nothrow_assignable<_U1, _U2>()) 1316 { 1317 this->_M_assign(std::move(__in)); 1318 return *this; 1319 } 1320 1321 template<typename _U1, typename _U2> 1322 _GLIBCXX20_CONSTEXPR 1323 __enable_if_t<__assignable<const _U1&, const _U2&>(), tuple&> 1324 operator=(const pair<_U1, _U2>& __in) 1325 noexcept(__nothrow_assignable<const _U1&, const _U2&>()) 1326 { 1327 this->_M_head(*this) = __in.first; 1328 this->_M_tail(*this)._M_head(*this) = __in.second; 1329 return *this; 1330 } 1331 1332 template<typename _U1, typename _U2> 1333 _GLIBCXX20_CONSTEXPR 1334 __enable_if_t<__assignable<_U1, _U2>(), tuple&> 1335 operator=(pair<_U1, _U2>&& __in) 1336 noexcept(__nothrow_assignable<_U1, _U2>()) 1337 { 1338 this->_M_head(*this) = std::forward<_U1>(__in.first); 1339 this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second); 1340 return *this; 1341 } 1342 1343 _GLIBCXX20_CONSTEXPR 1344 void 1345 swap(tuple& __in) 1346 noexcept(__and_<__is_nothrow_swappable<_T1>, 1347 __is_nothrow_swappable<_T2>>::value) 1348 { _Inherited::_M_swap(__in); } 1349 }; 1350 1351 1352 /// class tuple_size 1353 template<typename... _Elements> 1354 struct tuple_size<tuple<_Elements...>> 1355 : public integral_constant<size_t, sizeof...(_Elements)> { }; 1356 1357#if __cplusplus >= 201703L 1358 template<typename... _Types> 1359 inline constexpr size_t tuple_size_v<tuple<_Types...>> 1360 = sizeof...(_Types); 1361 1362 template<typename... _Types> 1363 inline constexpr size_t tuple_size_v<const tuple<_Types...>> 1364 = sizeof...(_Types); 1365#endif 1366 1367 /// Trait to get the Ith element type from a tuple. 1368 template<size_t __i, typename... _Types> 1369 struct tuple_element<__i, tuple<_Types...>> 1370 { 1371 static_assert(__i < sizeof...(_Types), "tuple index must be in range"); 1372 1373 using type = typename _Nth_type<__i, _Types...>::type; 1374 }; 1375 1376 template<size_t __i, typename _Head, typename... _Tail> 1377 constexpr _Head& 1378 __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 1379 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 1380 1381 template<size_t __i, typename _Head, typename... _Tail> 1382 constexpr const _Head& 1383 __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 1384 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 1385 1386 // Deleted overload to improve diagnostics for invalid indices 1387 template<size_t __i, typename... _Types> 1388 __enable_if_t<(__i >= sizeof...(_Types))> 1389 __get_helper(const tuple<_Types...>&) = delete; 1390 1391 /// Return a reference to the ith element of a tuple. 1392 template<size_t __i, typename... _Elements> 1393 constexpr __tuple_element_t<__i, tuple<_Elements...>>& 1394 get(tuple<_Elements...>& __t) noexcept 1395 { return std::__get_helper<__i>(__t); } 1396 1397 /// Return a const reference to the ith element of a const tuple. 1398 template<size_t __i, typename... _Elements> 1399 constexpr const __tuple_element_t<__i, tuple<_Elements...>>& 1400 get(const tuple<_Elements...>& __t) noexcept 1401 { return std::__get_helper<__i>(__t); } 1402 1403 /// Return an rvalue reference to the ith element of a tuple rvalue. 1404 template<size_t __i, typename... _Elements> 1405 constexpr __tuple_element_t<__i, tuple<_Elements...>>&& 1406 get(tuple<_Elements...>&& __t) noexcept 1407 { 1408 typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type; 1409 return std::forward<__element_type>(std::__get_helper<__i>(__t)); 1410 } 1411 1412 /// Return a const rvalue reference to the ith element of a const tuple rvalue. 1413 template<size_t __i, typename... _Elements> 1414 constexpr const __tuple_element_t<__i, tuple<_Elements...>>&& 1415 get(const tuple<_Elements...>&& __t) noexcept 1416 { 1417 typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type; 1418 return std::forward<const __element_type>(std::__get_helper<__i>(__t)); 1419 } 1420 1421 /// @cond undocumented 1422 // Deleted overload chosen for invalid indices. 1423 template<size_t __i, typename... _Elements> 1424 constexpr __enable_if_t<(__i >= sizeof...(_Elements))> 1425 get(const tuple<_Elements...>&) = delete; 1426 /// @endcond 1427 1428#if __cplusplus >= 201402L 1429 1430#define __cpp_lib_tuples_by_type 201304L 1431 1432 /// Return a reference to the unique element of type _Tp of a tuple. 1433 template <typename _Tp, typename... _Types> 1434 constexpr _Tp& 1435 get(tuple<_Types...>& __t) noexcept 1436 { 1437 constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>(); 1438 static_assert(__idx < sizeof...(_Types), 1439 "the type T in std::get<T> must occur exactly once in the tuple"); 1440 return std::__get_helper<__idx>(__t); 1441 } 1442 1443 /// Return a reference to the unique element of type _Tp of a tuple rvalue. 1444 template <typename _Tp, typename... _Types> 1445 constexpr _Tp&& 1446 get(tuple<_Types...>&& __t) noexcept 1447 { 1448 constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>(); 1449 static_assert(__idx < sizeof...(_Types), 1450 "the type T in std::get<T> must occur exactly once in the tuple"); 1451 return std::forward<_Tp>(std::__get_helper<__idx>(__t)); 1452 } 1453 1454 /// Return a const reference to the unique element of type _Tp of a tuple. 1455 template <typename _Tp, typename... _Types> 1456 constexpr const _Tp& 1457 get(const tuple<_Types...>& __t) noexcept 1458 { 1459 constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>(); 1460 static_assert(__idx < sizeof...(_Types), 1461 "the type T in std::get<T> must occur exactly once in the tuple"); 1462 return std::__get_helper<__idx>(__t); 1463 } 1464 1465 /// Return a const reference to the unique element of type _Tp of 1466 /// a const tuple rvalue. 1467 template <typename _Tp, typename... _Types> 1468 constexpr const _Tp&& 1469 get(const tuple<_Types...>&& __t) noexcept 1470 { 1471 constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>(); 1472 static_assert(__idx < sizeof...(_Types), 1473 "the type T in std::get<T> must occur exactly once in the tuple"); 1474 return std::forward<const _Tp>(std::__get_helper<__idx>(__t)); 1475 } 1476#endif 1477 1478 // This class performs the comparison operations on tuples 1479 template<typename _Tp, typename _Up, size_t __i, size_t __size> 1480 struct __tuple_compare 1481 { 1482 static constexpr bool 1483 __eq(const _Tp& __t, const _Up& __u) 1484 { 1485 return bool(std::get<__i>(__t) == std::get<__i>(__u)) 1486 && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u); 1487 } 1488 1489 static constexpr bool 1490 __less(const _Tp& __t, const _Up& __u) 1491 { 1492 return bool(std::get<__i>(__t) < std::get<__i>(__u)) 1493 || (!bool(std::get<__i>(__u) < std::get<__i>(__t)) 1494 && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u)); 1495 } 1496 }; 1497 1498 template<typename _Tp, typename _Up, size_t __size> 1499 struct __tuple_compare<_Tp, _Up, __size, __size> 1500 { 1501 static constexpr bool 1502 __eq(const _Tp&, const _Up&) { return true; } 1503 1504 static constexpr bool 1505 __less(const _Tp&, const _Up&) { return false; } 1506 }; 1507 1508 template<typename... _TElements, typename... _UElements> 1509 constexpr bool 1510 operator==(const tuple<_TElements...>& __t, 1511 const tuple<_UElements...>& __u) 1512 { 1513 static_assert(sizeof...(_TElements) == sizeof...(_UElements), 1514 "tuple objects can only be compared if they have equal sizes."); 1515 using __compare = __tuple_compare<tuple<_TElements...>, 1516 tuple<_UElements...>, 1517 0, sizeof...(_TElements)>; 1518 return __compare::__eq(__t, __u); 1519 } 1520 1521#if __cpp_lib_three_way_comparison 1522 template<typename _Cat, typename _Tp, typename _Up> 1523 constexpr _Cat 1524 __tuple_cmp(const _Tp&, const _Up&, index_sequence<>) 1525 { return _Cat::equivalent; } 1526 1527 template<typename _Cat, typename _Tp, typename _Up, 1528 size_t _Idx0, size_t... _Idxs> 1529 constexpr _Cat 1530 __tuple_cmp(const _Tp& __t, const _Up& __u, 1531 index_sequence<_Idx0, _Idxs...>) 1532 { 1533 auto __c 1534 = __detail::__synth3way(std::get<_Idx0>(__t), std::get<_Idx0>(__u)); 1535 if (__c != 0) 1536 return __c; 1537 return std::__tuple_cmp<_Cat>(__t, __u, index_sequence<_Idxs...>()); 1538 } 1539 1540 template<typename... _Tps, typename... _Ups> 1541 constexpr 1542 common_comparison_category_t<__detail::__synth3way_t<_Tps, _Ups>...> 1543 operator<=>(const tuple<_Tps...>& __t, const tuple<_Ups...>& __u) 1544 { 1545 using _Cat 1546 = common_comparison_category_t<__detail::__synth3way_t<_Tps, _Ups>...>; 1547 return std::__tuple_cmp<_Cat>(__t, __u, index_sequence_for<_Tps...>()); 1548 } 1549#else 1550 template<typename... _TElements, typename... _UElements> 1551 constexpr bool 1552 operator<(const tuple<_TElements...>& __t, 1553 const tuple<_UElements...>& __u) 1554 { 1555 static_assert(sizeof...(_TElements) == sizeof...(_UElements), 1556 "tuple objects can only be compared if they have equal sizes."); 1557 using __compare = __tuple_compare<tuple<_TElements...>, 1558 tuple<_UElements...>, 1559 0, sizeof...(_TElements)>; 1560 return __compare::__less(__t, __u); 1561 } 1562 1563 template<typename... _TElements, typename... _UElements> 1564 constexpr bool 1565 operator!=(const tuple<_TElements...>& __t, 1566 const tuple<_UElements...>& __u) 1567 { return !(__t == __u); } 1568 1569 template<typename... _TElements, typename... _UElements> 1570 constexpr bool 1571 operator>(const tuple<_TElements...>& __t, 1572 const tuple<_UElements...>& __u) 1573 { return __u < __t; } 1574 1575 template<typename... _TElements, typename... _UElements> 1576 constexpr bool 1577 operator<=(const tuple<_TElements...>& __t, 1578 const tuple<_UElements...>& __u) 1579 { return !(__u < __t); } 1580 1581 template<typename... _TElements, typename... _UElements> 1582 constexpr bool 1583 operator>=(const tuple<_TElements...>& __t, 1584 const tuple<_UElements...>& __u) 1585 { return !(__t < __u); } 1586#endif // three_way_comparison 1587 1588 // NB: DR 705. 1589 /// Create a tuple containing copies of the arguments 1590 template<typename... _Elements> 1591 constexpr tuple<typename __decay_and_strip<_Elements>::__type...> 1592 make_tuple(_Elements&&... __args) 1593 { 1594 typedef tuple<typename __decay_and_strip<_Elements>::__type...> 1595 __result_type; 1596 return __result_type(std::forward<_Elements>(__args)...); 1597 } 1598 1599 // _GLIBCXX_RESOLVE_LIB_DEFECTS 1600 // 2275. Why is forward_as_tuple not constexpr? 1601 /// Create a tuple of lvalue or rvalue references to the arguments 1602 template<typename... _Elements> 1603 constexpr tuple<_Elements&&...> 1604 forward_as_tuple(_Elements&&... __args) noexcept 1605 { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); } 1606 1607 // Declarations of std::array and its std::get overloads, so that 1608 // std::tuple_cat can use them if <tuple> is included before <array>. 1609 1610 template<typename _Tp, size_t _Nm> struct array; 1611 1612 template<size_t _Int, typename _Tp, size_t _Nm> 1613 constexpr _Tp& 1614 get(array<_Tp, _Nm>&) noexcept; 1615 1616 template<size_t _Int, typename _Tp, size_t _Nm> 1617 constexpr _Tp&& 1618 get(array<_Tp, _Nm>&&) noexcept; 1619 1620 template<size_t _Int, typename _Tp, size_t _Nm> 1621 constexpr const _Tp& 1622 get(const array<_Tp, _Nm>&) noexcept; 1623 1624 template<size_t _Int, typename _Tp, size_t _Nm> 1625 constexpr const _Tp&& 1626 get(const array<_Tp, _Nm>&&) noexcept; 1627 1628 /// @cond undocumented 1629 template<size_t, typename, typename, size_t> 1630 struct __make_tuple_impl; 1631 1632 template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm> 1633 struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm> 1634 : __make_tuple_impl<_Idx + 1, 1635 tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>, 1636 _Tuple, _Nm> 1637 { }; 1638 1639 template<size_t _Nm, typename _Tuple, typename... _Tp> 1640 struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm> 1641 { 1642 typedef tuple<_Tp...> __type; 1643 }; 1644 1645 template<typename _Tuple> 1646 struct __do_make_tuple 1647 : __make_tuple_impl<0, tuple<>, _Tuple, tuple_size<_Tuple>::value> 1648 { }; 1649 1650 // Returns the std::tuple equivalent of a tuple-like type. 1651 template<typename _Tuple> 1652 struct __make_tuple 1653 : public __do_make_tuple<__remove_cvref_t<_Tuple>> 1654 { }; 1655 1656 // Combines several std::tuple's into a single one. 1657 template<typename...> 1658 struct __combine_tuples; 1659 1660 template<> 1661 struct __combine_tuples<> 1662 { 1663 typedef tuple<> __type; 1664 }; 1665 1666 template<typename... _Ts> 1667 struct __combine_tuples<tuple<_Ts...>> 1668 { 1669 typedef tuple<_Ts...> __type; 1670 }; 1671 1672 template<typename... _T1s, typename... _T2s, typename... _Rem> 1673 struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...> 1674 { 1675 typedef typename __combine_tuples<tuple<_T1s..., _T2s...>, 1676 _Rem...>::__type __type; 1677 }; 1678 1679 // Computes the result type of tuple_cat given a set of tuple-like types. 1680 template<typename... _Tpls> 1681 struct __tuple_cat_result 1682 { 1683 typedef typename __combine_tuples 1684 <typename __make_tuple<_Tpls>::__type...>::__type __type; 1685 }; 1686 1687 // Helper to determine the index set for the first tuple-like 1688 // type of a given set. 1689 template<typename...> 1690 struct __make_1st_indices; 1691 1692 template<> 1693 struct __make_1st_indices<> 1694 { 1695 typedef _Index_tuple<> __type; 1696 }; 1697 1698 template<typename _Tp, typename... _Tpls> 1699 struct __make_1st_indices<_Tp, _Tpls...> 1700 { 1701 typedef typename _Build_index_tuple<tuple_size< 1702 typename remove_reference<_Tp>::type>::value>::__type __type; 1703 }; 1704 1705 // Performs the actual concatenation by step-wise expanding tuple-like 1706 // objects into the elements, which are finally forwarded into the 1707 // result tuple. 1708 template<typename _Ret, typename _Indices, typename... _Tpls> 1709 struct __tuple_concater; 1710 1711 template<typename _Ret, size_t... _Is, typename _Tp, typename... _Tpls> 1712 struct __tuple_concater<_Ret, _Index_tuple<_Is...>, _Tp, _Tpls...> 1713 { 1714 template<typename... _Us> 1715 static constexpr _Ret 1716 _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us) 1717 { 1718 typedef typename __make_1st_indices<_Tpls...>::__type __idx; 1719 typedef __tuple_concater<_Ret, __idx, _Tpls...> __next; 1720 return __next::_S_do(std::forward<_Tpls>(__tps)..., 1721 std::forward<_Us>(__us)..., 1722 std::get<_Is>(std::forward<_Tp>(__tp))...); 1723 } 1724 }; 1725 1726 template<typename _Ret> 1727 struct __tuple_concater<_Ret, _Index_tuple<>> 1728 { 1729 template<typename... _Us> 1730 static constexpr _Ret 1731 _S_do(_Us&&... __us) 1732 { 1733 return _Ret(std::forward<_Us>(__us)...); 1734 } 1735 }; 1736 1737 template<typename... _Tps> 1738 struct __is_tuple_like_impl<tuple<_Tps...>> : true_type 1739 { }; 1740 /// @endcond 1741 1742 /// Create a `tuple` containing all elements from multiple tuple-like objects 1743 template<typename... _Tpls, typename = typename 1744 enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type> 1745 constexpr auto 1746 tuple_cat(_Tpls&&... __tpls) 1747 -> typename __tuple_cat_result<_Tpls...>::__type 1748 { 1749 typedef typename __tuple_cat_result<_Tpls...>::__type __ret; 1750 typedef typename __make_1st_indices<_Tpls...>::__type __idx; 1751 typedef __tuple_concater<__ret, __idx, _Tpls...> __concater; 1752 return __concater::_S_do(std::forward<_Tpls>(__tpls)...); 1753 } 1754 1755 // _GLIBCXX_RESOLVE_LIB_DEFECTS 1756 // 2301. Why is tie not constexpr? 1757 /// Return a tuple of lvalue references bound to the arguments 1758 template<typename... _Elements> 1759 constexpr tuple<_Elements&...> 1760 tie(_Elements&... __args) noexcept 1761 { return tuple<_Elements&...>(__args...); } 1762 1763 /// Exchange the values of two tuples 1764 template<typename... _Elements> 1765 _GLIBCXX20_CONSTEXPR 1766 inline 1767#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 1768 // Constrained free swap overload, see p0185r1 1769 typename enable_if<__and_<__is_swappable<_Elements>...>::value 1770 >::type 1771#else 1772 void 1773#endif 1774 swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y) 1775 noexcept(noexcept(__x.swap(__y))) 1776 { __x.swap(__y); } 1777 1778#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11 1779 /// Exchange the values of two const tuples (if const elements can be swapped) 1780 template<typename... _Elements> 1781 _GLIBCXX20_CONSTEXPR 1782 typename enable_if<!__and_<__is_swappable<_Elements>...>::value>::type 1783 swap(tuple<_Elements...>&, tuple<_Elements...>&) = delete; 1784#endif 1785 1786 // A class (and instance) which can be used in 'tie' when an element 1787 // of a tuple is not required. 1788 // _GLIBCXX14_CONSTEXPR 1789 // 2933. PR for LWG 2773 could be clearer 1790 struct _Swallow_assign 1791 { 1792 template<class _Tp> 1793 _GLIBCXX14_CONSTEXPR const _Swallow_assign& 1794 operator=(const _Tp&) const 1795 { return *this; } 1796 }; 1797 1798 // _GLIBCXX_RESOLVE_LIB_DEFECTS 1799 // 2773. Making std::ignore constexpr 1800 /** Used with `std::tie` to ignore an element of a tuple 1801 * 1802 * When using `std::tie` to assign the elements of a tuple to variables, 1803 * unwanted elements can be ignored by using `std::ignore`. For example: 1804 * 1805 * ``` 1806 * int x, y; 1807 * std::tie(x, std::ignore, y) = std::make_tuple(1, 2, 3); 1808 * ``` 1809 * 1810 * This assignment will perform `x=1; std::ignore=2; y=3;` which results 1811 * in the second element being ignored. 1812 * 1813 * @since C++11 1814 */ 1815 _GLIBCXX17_INLINE constexpr _Swallow_assign ignore{}; 1816 1817 /// Partial specialization for tuples 1818 template<typename... _Types, typename _Alloc> 1819 struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { }; 1820 1821 // See stl_pair.h... 1822 /** "piecewise construction" using a tuple of arguments for each member. 1823 * 1824 * @param __first Arguments for the first member of the pair. 1825 * @param __second Arguments for the second member of the pair. 1826 * 1827 * The elements of each tuple will be used as the constructor arguments 1828 * for the data members of the pair. 1829 */ 1830 template<class _T1, class _T2> 1831 template<typename... _Args1, typename... _Args2> 1832 _GLIBCXX20_CONSTEXPR 1833 inline 1834 pair<_T1, _T2>:: 1835 pair(piecewise_construct_t, 1836 tuple<_Args1...> __first, tuple<_Args2...> __second) 1837 : pair(__first, __second, 1838 typename _Build_index_tuple<sizeof...(_Args1)>::__type(), 1839 typename _Build_index_tuple<sizeof...(_Args2)>::__type()) 1840 { } 1841 1842 template<class _T1, class _T2> 1843 template<typename... _Args1, size_t... _Indexes1, 1844 typename... _Args2, size_t... _Indexes2> 1845 _GLIBCXX20_CONSTEXPR inline 1846 pair<_T1, _T2>:: 1847 pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2, 1848 _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>) 1849 : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...), 1850 second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...) 1851 { } 1852 1853#if __cplusplus >= 201703L 1854 1855 // Unpack a std::tuple into a type trait and use its value. 1856 // For cv std::tuple<_Up> the result is _Trait<_Tp, cv _Up...>::value. 1857 // For cv std::tuple<_Up>& the result is _Trait<_Tp, cv _Up&...>::value. 1858 // Otherwise the result is false (because we don't know if std::get throws). 1859 template<template<typename...> class _Trait, typename _Tp, typename _Tuple> 1860 inline constexpr bool __unpack_std_tuple = false; 1861 1862 template<template<typename...> class _Trait, typename _Tp, typename... _Up> 1863 inline constexpr bool __unpack_std_tuple<_Trait, _Tp, tuple<_Up...>> 1864 = _Trait<_Tp, _Up...>::value; 1865 1866 template<template<typename...> class _Trait, typename _Tp, typename... _Up> 1867 inline constexpr bool __unpack_std_tuple<_Trait, _Tp, tuple<_Up...>&> 1868 = _Trait<_Tp, _Up&...>::value; 1869 1870 template<template<typename...> class _Trait, typename _Tp, typename... _Up> 1871 inline constexpr bool __unpack_std_tuple<_Trait, _Tp, const tuple<_Up...>> 1872 = _Trait<_Tp, const _Up...>::value; 1873 1874 template<template<typename...> class _Trait, typename _Tp, typename... _Up> 1875 inline constexpr bool __unpack_std_tuple<_Trait, _Tp, const tuple<_Up...>&> 1876 = _Trait<_Tp, const _Up&...>::value; 1877 1878# define __cpp_lib_apply 201603L 1879 1880 template <typename _Fn, typename _Tuple, size_t... _Idx> 1881 constexpr decltype(auto) 1882 __apply_impl(_Fn&& __f, _Tuple&& __t, index_sequence<_Idx...>) 1883 { 1884 return std::__invoke(std::forward<_Fn>(__f), 1885 std::get<_Idx>(std::forward<_Tuple>(__t))...); 1886 } 1887 1888 template <typename _Fn, typename _Tuple> 1889 constexpr decltype(auto) 1890 apply(_Fn&& __f, _Tuple&& __t) 1891 noexcept(__unpack_std_tuple<is_nothrow_invocable, _Fn, _Tuple>) 1892 { 1893 using _Indices 1894 = make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>; 1895 return std::__apply_impl(std::forward<_Fn>(__f), 1896 std::forward<_Tuple>(__t), 1897 _Indices{}); 1898 } 1899 1900#define __cpp_lib_make_from_tuple 201606L 1901 1902 template <typename _Tp, typename _Tuple, size_t... _Idx> 1903 constexpr _Tp 1904 __make_from_tuple_impl(_Tuple&& __t, index_sequence<_Idx...>) 1905 { return _Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...); } 1906 1907 template <typename _Tp, typename _Tuple> 1908 constexpr _Tp 1909 make_from_tuple(_Tuple&& __t) 1910 noexcept(__unpack_std_tuple<is_nothrow_constructible, _Tp, _Tuple>) 1911 { 1912 return __make_from_tuple_impl<_Tp>( 1913 std::forward<_Tuple>(__t), 1914 make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>{}); 1915 } 1916#endif // C++17 1917 1918 /// @} 1919 1920_GLIBCXX_END_NAMESPACE_VERSION 1921} // namespace std 1922 1923#endif // C++11 1924 1925#endif // _GLIBCXX_TUPLE 1926