1 // <tuple> -*- C++ -*- 2 3 // Copyright (C) 2007, 2008, 2009, 2010, 2011 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 #ifndef __GXX_EXPERIMENTAL_CXX0X__ 35 # include <bits/c++0x_warning.h> 36 #else 37 38 #include <utility> 39 40 namespace std _GLIBCXX_VISIBILITY(default) 41 { 42 _GLIBCXX_BEGIN_NAMESPACE_VERSION 43 44 // Adds a const reference to a non-reference type. 45 template<typename _Tp> 46 struct __add_c_ref 47 { typedef const _Tp& type; }; 48 49 template<typename _Tp> 50 struct __add_c_ref<_Tp&> 51 { typedef _Tp& type; }; 52 53 // Adds a reference to a non-reference type. 54 template<typename _Tp> 55 struct __add_ref 56 { typedef _Tp& type; }; 57 58 template<typename _Tp> 59 struct __add_ref<_Tp&> 60 { typedef _Tp& type; }; 61 62 template<std::size_t _Idx, typename _Head, bool _IsEmpty> 63 struct _Head_base; 64 65 template<std::size_t _Idx, typename _Head> 66 struct _Head_base<_Idx, _Head, true> 67 : public _Head 68 { 69 constexpr _Head_base() 70 : _Head() { } 71 72 constexpr _Head_base(const _Head& __h) 73 : _Head(__h) { } 74 75 template<typename _UHead> 76 _Head_base(_UHead&& __h) 77 : _Head(std::forward<_UHead>(__h)) { } 78 79 _Head& _M_head() { return *this; } 80 const _Head& _M_head() const { return *this; } 81 82 void 83 _M_swap_impl(_Head& __h) 84 { 85 using std::swap; 86 swap(__h, _M_head()); 87 } 88 }; 89 90 template<std::size_t _Idx, typename _Head> 91 struct _Head_base<_Idx, _Head, false> 92 { 93 constexpr _Head_base() 94 : _M_head_impl() { } 95 96 constexpr _Head_base(const _Head& __h) 97 : _M_head_impl(__h) { } 98 99 template<typename _UHead> 100 _Head_base(_UHead&& __h) 101 : _M_head_impl(std::forward<_UHead>(__h)) { } 102 103 _Head& _M_head() { return _M_head_impl; } 104 const _Head& _M_head() const { return _M_head_impl; } 105 106 void 107 _M_swap_impl(_Head& __h) 108 { 109 using std::swap; 110 swap(__h, _M_head()); 111 } 112 113 _Head _M_head_impl; 114 }; 115 116 /** 117 * Contains the actual implementation of the @c tuple template, stored 118 * as a recursive inheritance hierarchy from the first element (most 119 * derived class) to the last (least derived class). The @c Idx 120 * parameter gives the 0-based index of the element stored at this 121 * point in the hierarchy; we use it to implement a constant-time 122 * get() operation. 123 */ 124 template<std::size_t _Idx, typename... _Elements> 125 struct _Tuple_impl; 126 127 /** 128 * Zero-element tuple implementation. This is the basis case for the 129 * inheritance recursion. 130 */ 131 template<std::size_t _Idx> 132 struct _Tuple_impl<_Idx> 133 { 134 protected: 135 void _M_swap_impl(_Tuple_impl&) { /* no-op */ } 136 }; 137 138 /** 139 * Recursive tuple implementation. Here we store the @c Head element 140 * and derive from a @c Tuple_impl containing the remaining elements 141 * (which contains the @c Tail). 142 */ 143 template<std::size_t _Idx, typename _Head, typename... _Tail> 144 struct _Tuple_impl<_Idx, _Head, _Tail...> 145 : public _Tuple_impl<_Idx + 1, _Tail...>, 146 private _Head_base<_Idx, _Head, std::is_empty<_Head>::value> 147 { 148 typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited; 149 typedef _Head_base<_Idx, _Head, std::is_empty<_Head>::value> _Base; 150 151 _Head& _M_head() { return _Base::_M_head(); } 152 const _Head& _M_head() const { return _Base::_M_head(); } 153 154 _Inherited& _M_tail() { return *this; } 155 const _Inherited& _M_tail() const { return *this; } 156 157 constexpr _Tuple_impl() 158 : _Inherited(), _Base() { } 159 160 explicit 161 constexpr _Tuple_impl(const _Head& __head, const _Tail&... __tail) 162 : _Inherited(__tail...), _Base(__head) { } 163 164 template<typename _UHead, typename... _UTail> 165 explicit 166 _Tuple_impl(_UHead&& __head, _UTail&&... __tail) 167 : _Inherited(std::forward<_UTail>(__tail)...), 168 _Base(std::forward<_UHead>(__head)) { } 169 170 constexpr _Tuple_impl(const _Tuple_impl&) = default; 171 172 _Tuple_impl(_Tuple_impl&& __in) 173 : _Inherited(std::move(__in._M_tail())), 174 _Base(std::forward<_Head>(__in._M_head())) { } 175 176 template<typename... _UElements> 177 _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in) 178 : _Inherited(__in._M_tail()), _Base(__in._M_head()) { } 179 180 template<typename _UHead, typename... _UTails> 181 _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) 182 : _Inherited(std::move(__in._M_tail())), 183 _Base(std::forward<_UHead>(__in._M_head())) { } 184 185 _Tuple_impl& 186 operator=(const _Tuple_impl& __in) 187 { 188 _M_head() = __in._M_head(); 189 _M_tail() = __in._M_tail(); 190 return *this; 191 } 192 193 _Tuple_impl& 194 operator=(_Tuple_impl&& __in) 195 { 196 _M_head() = std::forward<_Head>(__in._M_head()); 197 _M_tail() = std::move(__in._M_tail()); 198 return *this; 199 } 200 201 template<typename... _UElements> 202 _Tuple_impl& 203 operator=(const _Tuple_impl<_Idx, _UElements...>& __in) 204 { 205 _M_head() = __in._M_head(); 206 _M_tail() = __in._M_tail(); 207 return *this; 208 } 209 210 template<typename _UHead, typename... _UTails> 211 _Tuple_impl& 212 operator=(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) 213 { 214 _M_head() = std::forward<_UHead>(__in._M_head()); 215 _M_tail() = std::move(__in._M_tail()); 216 return *this; 217 } 218 219 protected: 220 void 221 _M_swap_impl(_Tuple_impl& __in) 222 { 223 _Base::_M_swap_impl(__in._M_head()); 224 _Inherited::_M_swap_impl(__in._M_tail()); 225 } 226 }; 227 228 /// tuple 229 template<typename... _Elements> 230 class tuple : public _Tuple_impl<0, _Elements...> 231 { 232 typedef _Tuple_impl<0, _Elements...> _Inherited; 233 234 public: 235 constexpr tuple() 236 : _Inherited() { } 237 238 explicit 239 constexpr tuple(const _Elements&... __elements) 240 : _Inherited(__elements...) { } 241 242 template<typename... _UElements, typename = typename 243 std::enable_if<sizeof...(_UElements) 244 == sizeof...(_Elements)>::type> 245 explicit 246 tuple(_UElements&&... __elements) 247 : _Inherited(std::forward<_UElements>(__elements)...) { } 248 249 constexpr tuple(const tuple&) = default; 250 251 tuple(tuple&& __in) 252 : _Inherited(static_cast<_Inherited&&>(__in)) { } 253 254 template<typename... _UElements, typename = typename 255 std::enable_if<sizeof...(_UElements) 256 == sizeof...(_Elements)>::type> 257 tuple(const tuple<_UElements...>& __in) 258 : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) 259 { } 260 261 template<typename... _UElements, typename = typename 262 std::enable_if<sizeof...(_UElements) 263 == sizeof...(_Elements)>::type> 264 tuple(tuple<_UElements...>&& __in) 265 : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } 266 267 tuple& 268 operator=(const tuple& __in) 269 { 270 static_cast<_Inherited&>(*this) = __in; 271 return *this; 272 } 273 274 tuple& 275 operator=(tuple&& __in) 276 { 277 static_cast<_Inherited&>(*this) = std::move(__in); 278 return *this; 279 } 280 281 template<typename... _UElements, typename = typename 282 std::enable_if<sizeof...(_UElements) 283 == sizeof...(_Elements)>::type> 284 tuple& 285 operator=(const tuple<_UElements...>& __in) 286 { 287 static_cast<_Inherited&>(*this) = __in; 288 return *this; 289 } 290 291 template<typename... _UElements, typename = typename 292 std::enable_if<sizeof...(_UElements) 293 == sizeof...(_Elements)>::type> 294 tuple& 295 operator=(tuple<_UElements...>&& __in) 296 { 297 static_cast<_Inherited&>(*this) = std::move(__in); 298 return *this; 299 } 300 301 void 302 swap(tuple& __in) 303 { _Inherited::_M_swap_impl(__in); } 304 }; 305 306 template<> 307 class tuple<> 308 { 309 public: 310 void swap(tuple&) { /* no-op */ } 311 }; 312 313 /// tuple (2-element), with construction and assignment from a pair. 314 template<typename _T1, typename _T2> 315 class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2> 316 { 317 typedef _Tuple_impl<0, _T1, _T2> _Inherited; 318 319 public: 320 constexpr tuple() 321 : _Inherited() { } 322 323 explicit 324 constexpr tuple(const _T1& __a1, const _T2& __a2) 325 : _Inherited(__a1, __a2) { } 326 327 template<typename _U1, typename _U2> 328 explicit 329 tuple(_U1&& __a1, _U2&& __a2) 330 : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } 331 332 constexpr tuple(const tuple&) = default; 333 334 tuple(tuple&& __in) 335 : _Inherited(static_cast<_Inherited&&>(__in)) { } 336 337 template<typename _U1, typename _U2> 338 tuple(const tuple<_U1, _U2>& __in) 339 : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { } 340 341 template<typename _U1, typename _U2> 342 tuple(tuple<_U1, _U2>&& __in) 343 : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } 344 345 template<typename _U1, typename _U2> 346 tuple(const pair<_U1, _U2>& __in) 347 : _Inherited(__in.first, __in.second) { } 348 349 template<typename _U1, typename _U2> 350 tuple(pair<_U1, _U2>&& __in) 351 : _Inherited(std::forward<_U1>(__in.first), 352 std::forward<_U2>(__in.second)) { } 353 354 tuple& 355 operator=(const tuple& __in) 356 { 357 static_cast<_Inherited&>(*this) = __in; 358 return *this; 359 } 360 361 tuple& 362 operator=(tuple&& __in) 363 { 364 static_cast<_Inherited&>(*this) = std::move(__in); 365 return *this; 366 } 367 368 template<typename _U1, typename _U2> 369 tuple& 370 operator=(const tuple<_U1, _U2>& __in) 371 { 372 static_cast<_Inherited&>(*this) = __in; 373 return *this; 374 } 375 376 template<typename _U1, typename _U2> 377 tuple& 378 operator=(tuple<_U1, _U2>&& __in) 379 { 380 static_cast<_Inherited&>(*this) = std::move(__in); 381 return *this; 382 } 383 384 template<typename _U1, typename _U2> 385 tuple& 386 operator=(const pair<_U1, _U2>& __in) 387 { 388 this->_M_head() = __in.first; 389 this->_M_tail()._M_head() = __in.second; 390 return *this; 391 } 392 393 template<typename _U1, typename _U2> 394 tuple& 395 operator=(pair<_U1, _U2>&& __in) 396 { 397 this->_M_head() = std::forward<_U1>(__in.first); 398 this->_M_tail()._M_head() = std::forward<_U2>(__in.second); 399 return *this; 400 } 401 402 void 403 swap(tuple& __in) 404 { 405 using std::swap; 406 swap(this->_M_head(), __in._M_head()); 407 swap(this->_M_tail()._M_head(), __in._M_tail()._M_head()); 408 } 409 }; 410 411 /// tuple (1-element). 412 template<typename _T1> 413 class tuple<_T1> : public _Tuple_impl<0, _T1> 414 { 415 typedef _Tuple_impl<0, _T1> _Inherited; 416 417 public: 418 constexpr tuple() 419 : _Inherited() { } 420 421 explicit 422 constexpr tuple(const _T1& __a1) 423 : _Inherited(__a1) { } 424 425 template<typename _U1, typename = typename 426 std::enable_if<std::is_convertible<_U1, _T1>::value>::type> 427 explicit 428 tuple(_U1&& __a1) 429 : _Inherited(std::forward<_U1>(__a1)) { } 430 431 constexpr tuple(const tuple&) = default; 432 433 tuple(tuple&& __in) 434 : _Inherited(static_cast<_Inherited&&>(__in)) { } 435 436 template<typename _U1> 437 tuple(const tuple<_U1>& __in) 438 : _Inherited(static_cast<const _Tuple_impl<0, _U1>&>(__in)) { } 439 440 template<typename _U1> 441 tuple(tuple<_U1>&& __in) 442 : _Inherited(static_cast<_Tuple_impl<0, _U1>&&>(__in)) { } 443 444 tuple& 445 operator=(const tuple& __in) 446 { 447 static_cast<_Inherited&>(*this) = __in; 448 return *this; 449 } 450 451 tuple& 452 operator=(tuple&& __in) 453 { 454 static_cast<_Inherited&>(*this) = std::move(__in); 455 return *this; 456 } 457 458 template<typename _U1> 459 tuple& 460 operator=(const tuple<_U1>& __in) 461 { 462 static_cast<_Inherited&>(*this) = __in; 463 return *this; 464 } 465 466 template<typename _U1> 467 tuple& 468 operator=(tuple<_U1>&& __in) 469 { 470 static_cast<_Inherited&>(*this) = std::move(__in); 471 return *this; 472 } 473 474 void 475 swap(tuple& __in) 476 { _Inherited::_M_swap_impl(__in); } 477 }; 478 479 480 /// Gives the type of the ith element of a given tuple type. 481 template<std::size_t __i, typename _Tp> 482 struct tuple_element; 483 484 /** 485 * Recursive case for tuple_element: strip off the first element in 486 * the tuple and retrieve the (i-1)th element of the remaining tuple. 487 */ 488 template<std::size_t __i, typename _Head, typename... _Tail> 489 struct tuple_element<__i, tuple<_Head, _Tail...> > 490 : tuple_element<__i - 1, tuple<_Tail...> > { }; 491 492 /** 493 * Basis case for tuple_element: The first element is the one we're seeking. 494 */ 495 template<typename _Head, typename... _Tail> 496 struct tuple_element<0, tuple<_Head, _Tail...> > 497 { 498 typedef _Head type; 499 }; 500 501 /// Finds the size of a given tuple type. 502 template<typename _Tp> 503 struct tuple_size; 504 505 /// class tuple_size 506 template<typename... _Elements> 507 struct tuple_size<tuple<_Elements...> > 508 { 509 static const std::size_t value = sizeof...(_Elements); 510 }; 511 512 template<typename... _Elements> 513 const std::size_t tuple_size<tuple<_Elements...> >::value; 514 515 template<std::size_t __i, typename _Head, typename... _Tail> 516 inline typename __add_ref<_Head>::type 517 __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) 518 { return __t._M_head(); } 519 520 template<std::size_t __i, typename _Head, typename... _Tail> 521 inline typename __add_c_ref<_Head>::type 522 __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) 523 { return __t._M_head(); } 524 525 // Return a reference (const reference) to the ith element of a tuple. 526 // Any const or non-const ref elements are returned with their original type. 527 template<std::size_t __i, typename... _Elements> 528 inline typename __add_ref< 529 typename tuple_element<__i, tuple<_Elements...> >::type 530 >::type 531 get(tuple<_Elements...>& __t) 532 { return __get_helper<__i>(__t); } 533 534 template<std::size_t __i, typename... _Elements> 535 inline typename __add_c_ref< 536 typename tuple_element<__i, tuple<_Elements...> >::type 537 >::type 538 get(const tuple<_Elements...>& __t) 539 { return __get_helper<__i>(__t); } 540 541 // This class helps construct the various comparison operations on tuples 542 template<std::size_t __check_equal_size, std::size_t __i, std::size_t __j, 543 typename _Tp, typename _Up> 544 struct __tuple_compare; 545 546 template<std::size_t __i, std::size_t __j, typename _Tp, typename _Up> 547 struct __tuple_compare<0, __i, __j, _Tp, _Up> 548 { 549 static bool __eq(const _Tp& __t, const _Up& __u) 550 { 551 return (get<__i>(__t) == get<__i>(__u) && 552 __tuple_compare<0, __i + 1, __j, _Tp, _Up>::__eq(__t, __u)); 553 } 554 555 static bool __less(const _Tp& __t, const _Up& __u) 556 { 557 return ((get<__i>(__t) < get<__i>(__u)) 558 || !(get<__i>(__u) < get<__i>(__t)) && 559 __tuple_compare<0, __i + 1, __j, _Tp, _Up>::__less(__t, __u)); 560 } 561 }; 562 563 template<std::size_t __i, typename _Tp, typename _Up> 564 struct __tuple_compare<0, __i, __i, _Tp, _Up> 565 { 566 static bool __eq(const _Tp&, const _Up&) 567 { return true; } 568 569 static bool __less(const _Tp&, const _Up&) 570 { return false; } 571 }; 572 573 template<typename... _TElements, typename... _UElements> 574 bool 575 operator==(const tuple<_TElements...>& __t, 576 const tuple<_UElements...>& __u) 577 { 578 typedef tuple<_TElements...> _Tp; 579 typedef tuple<_UElements...> _Up; 580 return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value, 581 0, tuple_size<_Tp>::value, _Tp, _Up>::__eq(__t, __u)); 582 } 583 584 template<typename... _TElements, typename... _UElements> 585 bool 586 operator<(const tuple<_TElements...>& __t, 587 const tuple<_UElements...>& __u) 588 { 589 typedef tuple<_TElements...> _Tp; 590 typedef tuple<_UElements...> _Up; 591 return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value, 592 0, tuple_size<_Tp>::value, _Tp, _Up>::__less(__t, __u)); 593 } 594 595 template<typename... _TElements, typename... _UElements> 596 inline bool 597 operator!=(const tuple<_TElements...>& __t, 598 const tuple<_UElements...>& __u) 599 { return !(__t == __u); } 600 601 template<typename... _TElements, typename... _UElements> 602 inline bool 603 operator>(const tuple<_TElements...>& __t, 604 const tuple<_UElements...>& __u) 605 { return __u < __t; } 606 607 template<typename... _TElements, typename... _UElements> 608 inline bool 609 operator<=(const tuple<_TElements...>& __t, 610 const tuple<_UElements...>& __u) 611 { return !(__u < __t); } 612 613 template<typename... _TElements, typename... _UElements> 614 inline bool 615 operator>=(const tuple<_TElements...>& __t, 616 const tuple<_UElements...>& __u) 617 { return !(__t < __u); } 618 619 // NB: DR 705. 620 template<typename... _Elements> 621 inline tuple<typename __decay_and_strip<_Elements>::__type...> 622 make_tuple(_Elements&&... __args) 623 { 624 typedef tuple<typename __decay_and_strip<_Elements>::__type...> 625 __result_type; 626 return __result_type(std::forward<_Elements>(__args)...); 627 } 628 629 template<typename... _Elements> 630 inline tuple<_Elements&&...> 631 forward_as_tuple(_Elements&&... __args) 632 { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); } 633 634 template<std::size_t...> struct __index_holder { }; 635 636 template<std::size_t __i, typename _IdxHolder, typename... _Elements> 637 struct __index_holder_impl; 638 639 template<std::size_t __i, std::size_t... _Indexes, typename _IdxHolder, 640 typename... _Elements> 641 struct __index_holder_impl<__i, __index_holder<_Indexes...>, 642 _IdxHolder, _Elements...> 643 { 644 typedef typename __index_holder_impl<__i + 1, 645 __index_holder<_Indexes..., __i>, 646 _Elements...>::type type; 647 }; 648 649 template<std::size_t __i, std::size_t... _Indexes> 650 struct __index_holder_impl<__i, __index_holder<_Indexes...> > 651 { typedef __index_holder<_Indexes...> type; }; 652 653 template<typename... _Elements> 654 struct __make_index_holder 655 : __index_holder_impl<0, __index_holder<>, _Elements...> { }; 656 657 template<typename... _TElements, std::size_t... _TIdx, 658 typename... _UElements, std::size_t... _UIdx> 659 inline tuple<_TElements..., _UElements...> 660 __tuple_cat_helper(const tuple<_TElements...>& __t, 661 const __index_holder<_TIdx...>&, 662 const tuple<_UElements...>& __u, 663 const __index_holder<_UIdx...>&) 664 { return tuple<_TElements..., _UElements...>(get<_TIdx>(__t)..., 665 get<_UIdx>(__u)...); } 666 667 template<typename... _TElements, std::size_t... _TIdx, 668 typename... _UElements, std::size_t... _UIdx> 669 inline tuple<_TElements..., _UElements...> 670 __tuple_cat_helper(tuple<_TElements...>&& __t, 671 const __index_holder<_TIdx...>&, 672 const tuple<_UElements...>& __u, 673 const __index_holder<_UIdx...>&) 674 { return tuple<_TElements..., _UElements...> 675 (std::forward<_TElements>(get<_TIdx>(__t))..., get<_UIdx>(__u)...); } 676 677 template<typename... _TElements, std::size_t... _TIdx, 678 typename... _UElements, std::size_t... _UIdx> 679 inline tuple<_TElements..., _UElements...> 680 __tuple_cat_helper(const tuple<_TElements...>& __t, 681 const __index_holder<_TIdx...>&, 682 tuple<_UElements...>&& __u, 683 const __index_holder<_UIdx...>&) 684 { return tuple<_TElements..., _UElements...> 685 (get<_TIdx>(__t)..., std::forward<_UElements>(get<_UIdx>(__u))...); } 686 687 template<typename... _TElements, std::size_t... _TIdx, 688 typename... _UElements, std::size_t... _UIdx> 689 inline tuple<_TElements..., _UElements...> 690 __tuple_cat_helper(tuple<_TElements...>&& __t, 691 const __index_holder<_TIdx...>&, 692 tuple<_UElements...>&& __u, 693 const __index_holder<_UIdx...>&) 694 { return tuple<_TElements..., _UElements...> 695 (std::forward<_TElements>(get<_TIdx>(__t))..., 696 std::forward<_UElements>(get<_UIdx>(__u))...); } 697 698 template<typename... _TElements, typename... _UElements> 699 inline tuple<_TElements..., _UElements...> 700 tuple_cat(const tuple<_TElements...>& __t, const tuple<_UElements...>& __u) 701 { 702 return __tuple_cat_helper(__t, typename 703 __make_index_holder<_TElements...>::type(), 704 __u, typename 705 __make_index_holder<_UElements...>::type()); 706 } 707 708 template<typename... _TElements, typename... _UElements> 709 inline tuple<_TElements..., _UElements...> 710 tuple_cat(tuple<_TElements...>&& __t, const tuple<_UElements...>& __u) 711 { 712 return __tuple_cat_helper(std::move(__t), typename 713 __make_index_holder<_TElements...>::type(), 714 __u, typename 715 __make_index_holder<_UElements...>::type()); 716 } 717 718 template<typename... _TElements, typename... _UElements> 719 inline tuple<_TElements..., _UElements...> 720 tuple_cat(const tuple<_TElements...>& __t, tuple<_UElements...>&& __u) 721 { 722 return __tuple_cat_helper(__t, typename 723 __make_index_holder<_TElements...>::type(), 724 std::move(__u), typename 725 __make_index_holder<_UElements...>::type()); 726 } 727 728 template<typename... _TElements, typename... _UElements> 729 inline tuple<_TElements..., _UElements...> 730 tuple_cat(tuple<_TElements...>&& __t, tuple<_UElements...>&& __u) 731 { 732 return __tuple_cat_helper(std::move(__t), typename 733 __make_index_holder<_TElements...>::type(), 734 std::move(__u), typename 735 __make_index_holder<_UElements...>::type()); 736 } 737 738 template<typename... _Elements> 739 inline tuple<_Elements&...> 740 tie(_Elements&... __args) 741 { return tuple<_Elements&...>(__args...); } 742 743 template<typename... _Elements> 744 inline void 745 swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y) 746 { __x.swap(__y); } 747 748 // A class (and instance) which can be used in 'tie' when an element 749 // of a tuple is not required 750 struct _Swallow_assign 751 { 752 template<class _Tp> 753 const _Swallow_assign& 754 operator=(const _Tp&) const 755 { return *this; } 756 }; 757 758 const _Swallow_assign ignore{}; 759 760 /** 761 * Stores a tuple of indices. Used by bind() to extract the elements 762 * in a tuple. 763 */ 764 template<int... _Indexes> 765 struct _Index_tuple 766 { 767 typedef _Index_tuple<_Indexes..., sizeof...(_Indexes)> __next; 768 }; 769 770 /// Builds an _Index_tuple<0, 1, 2, ..., _Num-1>. 771 template<std::size_t _Num> 772 struct _Build_index_tuple 773 { 774 typedef typename _Build_index_tuple<_Num-1>::__type::__next __type; 775 }; 776 777 template<> 778 struct _Build_index_tuple<0> 779 { 780 typedef _Index_tuple<> __type; 781 }; 782 783 // See stl_pair.h... 784 template<class _T1, class _T2> 785 template<typename _Tp, typename... _Args> 786 inline _Tp 787 pair<_T1, _T2>:: 788 __cons(tuple<_Args...>&& __tuple) 789 { 790 typedef typename _Build_index_tuple<sizeof...(_Args)>::__type 791 _Indexes; 792 return __do_cons<_Tp>(std::move(__tuple), _Indexes()); 793 } 794 795 template<class _T1, class _T2> 796 template<typename _Tp, typename... _Args, int... _Indexes> 797 inline _Tp 798 pair<_T1, _T2>:: 799 __do_cons(tuple<_Args...>&& __tuple, 800 const _Index_tuple<_Indexes...>&) 801 { return _Tp(std::forward<_Args>(get<_Indexes>(__tuple))...); } 802 803 _GLIBCXX_END_NAMESPACE_VERSION 804 } // namespace 805 806 #endif // __GXX_EXPERIMENTAL_CXX0X__ 807 808 #endif // _GLIBCXX_TUPLE 809