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