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