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