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 #include <bits/uses_allocator.h> 40 41 namespace std _GLIBCXX_VISIBILITY(default) 42 { 43 _GLIBCXX_BEGIN_NAMESPACE_VERSION 44 45 // Adds a const reference to a non-reference type. 46 template<typename _Tp> 47 struct __add_c_ref 48 { typedef const _Tp& type; }; 49 50 template<typename _Tp> 51 struct __add_c_ref<_Tp&> 52 { typedef _Tp& type; }; 53 54 // Adds a reference to a non-reference type. 55 template<typename _Tp> 56 struct __add_ref 57 { typedef _Tp& type; }; 58 59 template<typename _Tp> 60 struct __add_ref<_Tp&> 61 { typedef _Tp& type; }; 62 63 // Adds an rvalue reference to a non-reference type. 64 template<typename _Tp> 65 struct __add_r_ref 66 { typedef _Tp&& type; }; 67 68 template<typename _Tp> 69 struct __add_r_ref<_Tp&> 70 { typedef _Tp& type; }; 71 72 template<std::size_t _Idx, typename _Head, bool _IsEmptyNotFinal> 73 struct _Head_base; 74 75 template<std::size_t _Idx, typename _Head> 76 struct _Head_base<_Idx, _Head, true> 77 : public _Head 78 { 79 constexpr _Head_base() 80 : _Head() { } 81 82 constexpr _Head_base(const _Head& __h) 83 : _Head(__h) { } 84 85 template<typename _UHead, typename = typename 86 enable_if<!is_convertible<_UHead, 87 __uses_alloc_base>::value>::type> 88 constexpr _Head_base(_UHead&& __h) 89 : _Head(std::forward<_UHead>(__h)) { } 90 91 _Head_base(__uses_alloc0) 92 : _Head() { } 93 94 template<typename _Alloc> 95 _Head_base(__uses_alloc1<_Alloc> __a) 96 : _Head(allocator_arg, *__a._M_a) { } 97 98 template<typename _Alloc> 99 _Head_base(__uses_alloc2<_Alloc> __a) 100 : _Head(*__a._M_a) { } 101 102 template<typename _UHead> 103 _Head_base(__uses_alloc0, _UHead&& __uhead) 104 : _Head(std::forward<_UHead>(__uhead)) { } 105 106 template<typename _Alloc, typename _UHead> 107 _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead) 108 : _Head(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { } 109 110 template<typename _Alloc, typename _UHead> 111 _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead) 112 : _Head(std::forward<_UHead>(__uhead), *__a._M_a) { } 113 114 static constexpr _Head& 115 _M_head(_Head_base& __b) noexcept { return __b; } 116 117 static constexpr const _Head& 118 _M_head(const _Head_base& __b) noexcept { return __b; } 119 }; 120 121 template<std::size_t _Idx, typename _Head> 122 struct _Head_base<_Idx, _Head, false> 123 { 124 constexpr _Head_base() 125 : _M_head_impl() { } 126 127 constexpr _Head_base(const _Head& __h) 128 : _M_head_impl(__h) { } 129 130 template<typename _UHead, typename = typename 131 enable_if<!is_convertible<_UHead, 132 __uses_alloc_base>::value>::type> 133 constexpr _Head_base(_UHead&& __h) 134 : _M_head_impl(std::forward<_UHead>(__h)) { } 135 136 _Head_base(__uses_alloc0) 137 : _M_head_impl() { } 138 139 template<typename _Alloc> 140 _Head_base(__uses_alloc1<_Alloc> __a) 141 : _M_head_impl(allocator_arg, *__a._M_a) { } 142 143 template<typename _Alloc> 144 _Head_base(__uses_alloc2<_Alloc> __a) 145 : _M_head_impl(*__a._M_a) { } 146 147 template<typename _UHead> 148 _Head_base(__uses_alloc0, _UHead&& __uhead) 149 : _M_head_impl(std::forward<_UHead>(__uhead)) { } 150 151 template<typename _Alloc, typename _UHead> 152 _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead) 153 : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) 154 { } 155 156 template<typename _Alloc, typename _UHead> 157 _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead) 158 : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { } 159 160 static constexpr _Head& 161 _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; } 162 163 static constexpr const _Head& 164 _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; } 165 166 _Head _M_head_impl; 167 }; 168 169 /** 170 * Contains the actual implementation of the @c tuple template, stored 171 * as a recursive inheritance hierarchy from the first element (most 172 * derived class) to the last (least derived class). The @c Idx 173 * parameter gives the 0-based index of the element stored at this 174 * point in the hierarchy; we use it to implement a constant-time 175 * get() operation. 176 */ 177 template<std::size_t _Idx, typename... _Elements> 178 struct _Tuple_impl; 179 180 /** 181 * Zero-element tuple implementation. This is the basis case for the 182 * inheritance recursion. 183 */ 184 template<std::size_t _Idx> 185 struct _Tuple_impl<_Idx> 186 { 187 template<std::size_t, typename...> friend class _Tuple_impl; 188 189 _Tuple_impl() = default; 190 191 template<typename _Alloc> 192 _Tuple_impl(allocator_arg_t, const _Alloc&) { } 193 194 template<typename _Alloc> 195 _Tuple_impl(allocator_arg_t, const _Alloc&, const _Tuple_impl&) { } 196 197 template<typename _Alloc> 198 _Tuple_impl(allocator_arg_t, const _Alloc&, _Tuple_impl&&) { } 199 200 protected: 201 void _M_swap(_Tuple_impl&) noexcept { /* no-op */ } 202 }; 203 204 // Use the Empty Base-class Optimization for empty, non-final types. 205 template<typename _Tp> 206 using __empty_not_final 207 = typename conditional<__is_final(_Tp), false_type, is_empty<_Tp>>::type; 208 209 /** 210 * Recursive tuple implementation. Here we store the @c Head element 211 * and derive from a @c Tuple_impl containing the remaining elements 212 * (which contains the @c Tail). 213 */ 214 template<std::size_t _Idx, typename _Head, typename... _Tail> 215 struct _Tuple_impl<_Idx, _Head, _Tail...> 216 : public _Tuple_impl<_Idx + 1, _Tail...>, 217 private _Head_base<_Idx, _Head, __empty_not_final<_Head>::value> 218 { 219 template<std::size_t, typename...> friend class _Tuple_impl; 220 221 typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited; 222 typedef _Head_base<_Idx, _Head, __empty_not_final<_Head>::value> _Base; 223 224 static constexpr _Head& 225 _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } 226 227 static constexpr const _Head& 228 _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } 229 230 static constexpr _Inherited& 231 _M_tail(_Tuple_impl& __t) noexcept { return __t; } 232 233 static constexpr const _Inherited& 234 _M_tail(const _Tuple_impl& __t) noexcept { return __t; } 235 236 constexpr _Tuple_impl() 237 : _Inherited(), _Base() { } 238 239 explicit 240 constexpr _Tuple_impl(const _Head& __head, const _Tail&... __tail) 241 : _Inherited(__tail...), _Base(__head) { } 242 243 template<typename _UHead, typename... _UTail, typename = typename 244 enable_if<sizeof...(_Tail) == sizeof...(_UTail)>::type> 245 explicit 246 constexpr _Tuple_impl(_UHead&& __head, _UTail&&... __tail) 247 : _Inherited(std::forward<_UTail>(__tail)...), 248 _Base(std::forward<_UHead>(__head)) { } 249 250 constexpr _Tuple_impl(const _Tuple_impl&) = default; 251 252 constexpr 253 _Tuple_impl(_Tuple_impl&& __in) 254 noexcept(__and_<is_nothrow_move_constructible<_Head>, 255 is_nothrow_move_constructible<_Inherited>>::value) 256 : _Inherited(std::move(_M_tail(__in))), 257 _Base(std::forward<_Head>(_M_head(__in))) { } 258 259 template<typename... _UElements> 260 constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in) 261 : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)), 262 _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { } 263 264 template<typename _UHead, typename... _UTails> 265 constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) 266 : _Inherited(std::move 267 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))), 268 _Base(std::forward<_UHead> 269 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { } 270 271 template<typename _Alloc> 272 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a) 273 : _Inherited(__tag, __a), 274 _Base(__use_alloc<_Head>(__a)) { } 275 276 template<typename _Alloc> 277 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 278 const _Head& __head, const _Tail&... __tail) 279 : _Inherited(__tag, __a, __tail...), 280 _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { } 281 282 template<typename _Alloc, typename _UHead, typename... _UTail, 283 typename = typename enable_if<sizeof...(_Tail) 284 == sizeof...(_UTail)>::type> 285 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 286 _UHead&& __head, _UTail&&... __tail) 287 : _Inherited(__tag, __a, std::forward<_UTail>(__tail)...), 288 _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), 289 std::forward<_UHead>(__head)) { } 290 291 template<typename _Alloc> 292 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 293 const _Tuple_impl& __in) 294 : _Inherited(__tag, __a, _M_tail(__in)), 295 _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { } 296 297 template<typename _Alloc> 298 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 299 _Tuple_impl&& __in) 300 : _Inherited(__tag, __a, std::move(_M_tail(__in))), 301 _Base(__use_alloc<_Head, _Alloc, _Head>(__a), 302 std::forward<_Head>(_M_head(__in))) { } 303 304 template<typename _Alloc, typename... _UElements> 305 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 306 const _Tuple_impl<_Idx, _UElements...>& __in) 307 : _Inherited(__tag, __a, 308 _Tuple_impl<_Idx, _UElements...>::_M_tail(__in)), 309 _Base(__use_alloc<_Head, _Alloc, _Head>(__a), 310 _Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { } 311 312 template<typename _Alloc, typename _UHead, typename... _UTails> 313 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 314 _Tuple_impl<_Idx, _UHead, _UTails...>&& __in) 315 : _Inherited(__tag, __a, std::move 316 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))), 317 _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), 318 std::forward<_UHead> 319 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { } 320 321 _Tuple_impl& 322 operator=(const _Tuple_impl& __in) 323 { 324 _M_head(*this) = _M_head(__in); 325 _M_tail(*this) = _M_tail(__in); 326 return *this; 327 } 328 329 _Tuple_impl& 330 operator=(_Tuple_impl&& __in) 331 noexcept(__and_<is_nothrow_move_assignable<_Head>, 332 is_nothrow_move_assignable<_Inherited>>::value) 333 { 334 _M_head(*this) = std::forward<_Head>(_M_head(__in)); 335 _M_tail(*this) = std::move(_M_tail(__in)); 336 return *this; 337 } 338 339 template<typename... _UElements> 340 _Tuple_impl& 341 operator=(const _Tuple_impl<_Idx, _UElements...>& __in) 342 { 343 _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in); 344 _M_tail(*this) = _Tuple_impl<_Idx, _UElements...>::_M_tail(__in); 345 return *this; 346 } 347 348 template<typename _UHead, typename... _UTails> 349 _Tuple_impl& 350 operator=(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) 351 { 352 _M_head(*this) = std::forward<_UHead> 353 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)); 354 _M_tail(*this) = std::move 355 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)); 356 return *this; 357 } 358 359 protected: 360 void 361 _M_swap(_Tuple_impl& __in) 362 noexcept(noexcept(swap(std::declval<_Head&>(), 363 std::declval<_Head&>())) 364 && noexcept(_M_tail(__in)._M_swap(_M_tail(__in)))) 365 { 366 using std::swap; 367 swap(_M_head(*this), _M_head(__in)); 368 _Inherited::_M_swap(_M_tail(__in)); 369 } 370 }; 371 372 /// Primary class template, tuple 373 template<typename... _Elements> 374 class tuple : public _Tuple_impl<0, _Elements...> 375 { 376 typedef _Tuple_impl<0, _Elements...> _Inherited; 377 378 public: 379 constexpr tuple() 380 : _Inherited() { } 381 382 explicit 383 constexpr tuple(const _Elements&... __elements) 384 : _Inherited(__elements...) { } 385 386 template<typename... _UElements, typename = typename 387 enable_if<__and_<is_convertible<_UElements, 388 _Elements>...>::value>::type> 389 explicit 390 constexpr tuple(_UElements&&... __elements) 391 : _Inherited(std::forward<_UElements>(__elements)...) { } 392 393 constexpr tuple(const tuple&) = default; 394 395 constexpr tuple(tuple&&) = default; 396 397 template<typename... _UElements, typename = typename 398 enable_if<__and_<is_convertible<const _UElements&, 399 _Elements>...>::value>::type> 400 constexpr tuple(const tuple<_UElements...>& __in) 401 : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) 402 { } 403 404 template<typename... _UElements, typename = typename 405 enable_if<__and_<is_convertible<_UElements, 406 _Elements>...>::value>::type> 407 constexpr tuple(tuple<_UElements...>&& __in) 408 : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } 409 410 // Allocator-extended constructors. 411 412 template<typename _Alloc> 413 tuple(allocator_arg_t __tag, const _Alloc& __a) 414 : _Inherited(__tag, __a) { } 415 416 template<typename _Alloc> 417 tuple(allocator_arg_t __tag, const _Alloc& __a, 418 const _Elements&... __elements) 419 : _Inherited(__tag, __a, __elements...) { } 420 421 template<typename _Alloc, typename... _UElements, typename = typename 422 enable_if<sizeof...(_UElements) 423 == sizeof...(_Elements)>::type> 424 tuple(allocator_arg_t __tag, const _Alloc& __a, 425 _UElements&&... __elements) 426 : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...) 427 { } 428 429 template<typename _Alloc> 430 tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) 431 : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { } 432 433 template<typename _Alloc> 434 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) 435 : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { } 436 437 template<typename _Alloc, typename... _UElements, typename = typename 438 enable_if<sizeof...(_UElements) 439 == sizeof...(_Elements)>::type> 440 tuple(allocator_arg_t __tag, const _Alloc& __a, 441 const tuple<_UElements...>& __in) 442 : _Inherited(__tag, __a, 443 static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) 444 { } 445 446 template<typename _Alloc, typename... _UElements, typename = typename 447 enable_if<sizeof...(_UElements) 448 == sizeof...(_Elements)>::type> 449 tuple(allocator_arg_t __tag, const _Alloc& __a, 450 tuple<_UElements...>&& __in) 451 : _Inherited(__tag, __a, 452 static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) 453 { } 454 455 tuple& 456 operator=(const tuple& __in) 457 { 458 static_cast<_Inherited&>(*this) = __in; 459 return *this; 460 } 461 462 tuple& 463 operator=(tuple&& __in) 464 noexcept(is_nothrow_move_assignable<_Inherited>::value) 465 { 466 static_cast<_Inherited&>(*this) = std::move(__in); 467 return *this; 468 } 469 470 template<typename... _UElements, typename = typename 471 enable_if<sizeof...(_UElements) 472 == sizeof...(_Elements)>::type> 473 tuple& 474 operator=(const tuple<_UElements...>& __in) 475 { 476 static_cast<_Inherited&>(*this) = __in; 477 return *this; 478 } 479 480 template<typename... _UElements, typename = typename 481 enable_if<sizeof...(_UElements) 482 == sizeof...(_Elements)>::type> 483 tuple& 484 operator=(tuple<_UElements...>&& __in) 485 { 486 static_cast<_Inherited&>(*this) = std::move(__in); 487 return *this; 488 } 489 490 void 491 swap(tuple& __in) 492 noexcept(noexcept(__in._M_swap(__in))) 493 { _Inherited::_M_swap(__in); } 494 }; 495 496 // Explicit specialization, zero-element tuple. 497 template<> 498 class tuple<> 499 { 500 public: 501 void swap(tuple&) noexcept { /* no-op */ } 502 }; 503 504 /// Partial specialization, 2-element tuple. 505 /// Includes construction and assignment from a pair. 506 template<typename _T1, typename _T2> 507 class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2> 508 { 509 typedef _Tuple_impl<0, _T1, _T2> _Inherited; 510 511 public: 512 constexpr tuple() 513 : _Inherited() { } 514 515 explicit 516 constexpr tuple(const _T1& __a1, const _T2& __a2) 517 : _Inherited(__a1, __a2) { } 518 519 template<typename _U1, typename _U2, typename = typename 520 enable_if<__and_<is_convertible<_U1, _T1>, 521 is_convertible<_U2, _T2>>::value>::type> 522 explicit 523 constexpr tuple(_U1&& __a1, _U2&& __a2) 524 : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } 525 526 constexpr tuple(const tuple&) = default; 527 528 constexpr tuple(tuple&&) = default; 529 530 template<typename _U1, typename _U2, typename = typename 531 enable_if<__and_<is_convertible<const _U1&, _T1>, 532 is_convertible<const _U2&, _T2>>::value>::type> 533 constexpr tuple(const tuple<_U1, _U2>& __in) 534 : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { } 535 536 template<typename _U1, typename _U2, typename = typename 537 enable_if<__and_<is_convertible<_U1, _T1>, 538 is_convertible<_U2, _T2>>::value>::type> 539 constexpr tuple(tuple<_U1, _U2>&& __in) 540 : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } 541 542 template<typename _U1, typename _U2, typename = typename 543 enable_if<__and_<is_convertible<const _U1&, _T1>, 544 is_convertible<const _U2&, _T2>>::value>::type> 545 constexpr tuple(const pair<_U1, _U2>& __in) 546 : _Inherited(__in.first, __in.second) { } 547 548 template<typename _U1, typename _U2, typename = typename 549 enable_if<__and_<is_convertible<_U1, _T1>, 550 is_convertible<_U2, _T2>>::value>::type> 551 constexpr tuple(pair<_U1, _U2>&& __in) 552 : _Inherited(std::forward<_U1>(__in.first), 553 std::forward<_U2>(__in.second)) { } 554 555 // Allocator-extended constructors. 556 557 template<typename _Alloc> 558 tuple(allocator_arg_t __tag, const _Alloc& __a) 559 : _Inherited(__tag, __a) { } 560 561 template<typename _Alloc> 562 tuple(allocator_arg_t __tag, const _Alloc& __a, 563 const _T1& __a1, const _T2& __a2) 564 : _Inherited(__tag, __a, __a1, __a2) { } 565 566 template<typename _Alloc, typename _U1, typename _U2> 567 tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2) 568 : _Inherited(__tag, __a, std::forward<_U1>(__a1), 569 std::forward<_U2>(__a2)) { } 570 571 template<typename _Alloc> 572 tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) 573 : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { } 574 575 template<typename _Alloc> 576 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) 577 : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { } 578 579 template<typename _Alloc, typename _U1, typename _U2> 580 tuple(allocator_arg_t __tag, const _Alloc& __a, 581 const tuple<_U1, _U2>& __in) 582 : _Inherited(__tag, __a, 583 static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) 584 { } 585 586 template<typename _Alloc, typename _U1, typename _U2> 587 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in) 588 : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) 589 { } 590 591 template<typename _Alloc, typename _U1, typename _U2> 592 tuple(allocator_arg_t __tag, const _Alloc& __a, 593 const pair<_U1, _U2>& __in) 594 : _Inherited(__tag, __a, __in.first, __in.second) { } 595 596 template<typename _Alloc, typename _U1, typename _U2> 597 tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in) 598 : _Inherited(__tag, __a, std::forward<_U1>(__in.first), 599 std::forward<_U2>(__in.second)) { } 600 601 tuple& 602 operator=(const tuple& __in) 603 { 604 static_cast<_Inherited&>(*this) = __in; 605 return *this; 606 } 607 608 tuple& 609 operator=(tuple&& __in) 610 noexcept(is_nothrow_move_assignable<_Inherited>::value) 611 { 612 static_cast<_Inherited&>(*this) = std::move(__in); 613 return *this; 614 } 615 616 template<typename _U1, typename _U2> 617 tuple& 618 operator=(const tuple<_U1, _U2>& __in) 619 { 620 static_cast<_Inherited&>(*this) = __in; 621 return *this; 622 } 623 624 template<typename _U1, typename _U2> 625 tuple& 626 operator=(tuple<_U1, _U2>&& __in) 627 { 628 static_cast<_Inherited&>(*this) = std::move(__in); 629 return *this; 630 } 631 632 template<typename _U1, typename _U2> 633 tuple& 634 operator=(const pair<_U1, _U2>& __in) 635 { 636 this->_M_head(*this) = __in.first; 637 this->_M_tail(*this)._M_head(*this) = __in.second; 638 return *this; 639 } 640 641 template<typename _U1, typename _U2> 642 tuple& 643 operator=(pair<_U1, _U2>&& __in) 644 { 645 this->_M_head(*this) = std::forward<_U1>(__in.first); 646 this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second); 647 return *this; 648 } 649 650 void 651 swap(tuple& __in) 652 noexcept(noexcept(__in._M_swap(__in))) 653 { _Inherited::_M_swap(__in); } 654 }; 655 656 657 /// Gives the type of the ith element of a given tuple type. 658 template<std::size_t __i, typename _Tp> 659 struct tuple_element; 660 661 /** 662 * Recursive case for tuple_element: strip off the first element in 663 * the tuple and retrieve the (i-1)th element of the remaining tuple. 664 */ 665 template<std::size_t __i, typename _Head, typename... _Tail> 666 struct tuple_element<__i, tuple<_Head, _Tail...> > 667 : tuple_element<__i - 1, tuple<_Tail...> > { }; 668 669 /** 670 * Basis case for tuple_element: The first element is the one we're seeking. 671 */ 672 template<typename _Head, typename... _Tail> 673 struct tuple_element<0, tuple<_Head, _Tail...> > 674 { 675 typedef _Head type; 676 }; 677 678 template<std::size_t __i, typename _Tp> 679 struct tuple_element<__i, const _Tp> 680 { 681 typedef typename 682 add_const<typename tuple_element<__i, _Tp>::type>::type type; 683 }; 684 685 template<std::size_t __i, typename _Tp> 686 struct tuple_element<__i, volatile _Tp> 687 { 688 typedef typename 689 add_volatile<typename tuple_element<__i, _Tp>::type>::type type; 690 }; 691 692 template<std::size_t __i, typename _Tp> 693 struct tuple_element<__i, const volatile _Tp> 694 { 695 typedef typename 696 add_cv<typename tuple_element<__i, _Tp>::type>::type type; 697 }; 698 699 /// Finds the size of a given tuple type. 700 template<typename _Tp> 701 struct tuple_size; 702 703 template<typename _Tp> 704 struct tuple_size<const _Tp> 705 : public integral_constant< 706 typename remove_cv<decltype(tuple_size<_Tp>::value)>::type, 707 tuple_size<_Tp>::value> { }; 708 709 template<typename _Tp> 710 struct tuple_size<volatile _Tp> 711 : public integral_constant< 712 typename remove_cv<decltype(tuple_size<_Tp>::value)>::type, 713 tuple_size<_Tp>::value> { }; 714 715 template<typename _Tp> 716 struct tuple_size<const volatile _Tp> 717 : public integral_constant< 718 typename remove_cv<decltype(tuple_size<_Tp>::value)>::type, 719 tuple_size<_Tp>::value> { }; 720 721 /// class tuple_size 722 template<typename... _Elements> 723 struct tuple_size<tuple<_Elements...>> 724 : public integral_constant<std::size_t, sizeof...(_Elements)> { }; 725 726 template<std::size_t __i, typename _Head, typename... _Tail> 727 constexpr typename __add_ref<_Head>::type 728 __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 729 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 730 731 template<std::size_t __i, typename _Head, typename... _Tail> 732 constexpr typename __add_c_ref<_Head>::type 733 __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 734 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 735 736 // Return a reference (const reference, rvalue reference) to the ith element 737 // of a tuple. Any const or non-const ref elements are returned with their 738 // original type. 739 template<std::size_t __i, typename... _Elements> 740 constexpr typename __add_ref< 741 typename tuple_element<__i, tuple<_Elements...>>::type 742 >::type 743 get(tuple<_Elements...>& __t) noexcept 744 { return __get_helper<__i>(__t); } 745 746 template<std::size_t __i, typename... _Elements> 747 constexpr typename __add_c_ref< 748 typename tuple_element<__i, tuple<_Elements...>>::type 749 >::type 750 get(const tuple<_Elements...>& __t) noexcept 751 { return __get_helper<__i>(__t); } 752 753 template<std::size_t __i, typename... _Elements> 754 constexpr typename __add_r_ref< 755 typename tuple_element<__i, tuple<_Elements...>>::type 756 >::type 757 get(tuple<_Elements...>&& __t) noexcept 758 { return std::forward<typename tuple_element<__i, 759 tuple<_Elements...>>::type&&>(get<__i>(__t)); } 760 761 // This class helps construct the various comparison operations on tuples 762 template<std::size_t __check_equal_size, std::size_t __i, std::size_t __j, 763 typename _Tp, typename _Up> 764 struct __tuple_compare; 765 766 template<std::size_t __i, std::size_t __j, typename _Tp, typename _Up> 767 struct __tuple_compare<0, __i, __j, _Tp, _Up> 768 { 769 static bool 770 __eq(const _Tp& __t, const _Up& __u) 771 { 772 return (get<__i>(__t) == get<__i>(__u) && 773 __tuple_compare<0, __i + 1, __j, _Tp, _Up>::__eq(__t, __u)); 774 } 775 776 static bool 777 __less(const _Tp& __t, const _Up& __u) 778 { 779 return ((get<__i>(__t) < get<__i>(__u)) 780 || !(get<__i>(__u) < get<__i>(__t)) && 781 __tuple_compare<0, __i + 1, __j, _Tp, _Up>::__less(__t, __u)); 782 } 783 }; 784 785 template<std::size_t __i, typename _Tp, typename _Up> 786 struct __tuple_compare<0, __i, __i, _Tp, _Up> 787 { 788 static bool 789 __eq(const _Tp&, const _Up&) { return true; } 790 791 static bool 792 __less(const _Tp&, const _Up&) { return false; } 793 }; 794 795 template<typename... _TElements, typename... _UElements> 796 bool 797 operator==(const tuple<_TElements...>& __t, 798 const tuple<_UElements...>& __u) 799 { 800 typedef tuple<_TElements...> _Tp; 801 typedef tuple<_UElements...> _Up; 802 return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value, 803 0, tuple_size<_Tp>::value, _Tp, _Up>::__eq(__t, __u)); 804 } 805 806 template<typename... _TElements, typename... _UElements> 807 bool 808 operator<(const tuple<_TElements...>& __t, 809 const tuple<_UElements...>& __u) 810 { 811 typedef tuple<_TElements...> _Tp; 812 typedef tuple<_UElements...> _Up; 813 return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value, 814 0, tuple_size<_Tp>::value, _Tp, _Up>::__less(__t, __u)); 815 } 816 817 template<typename... _TElements, typename... _UElements> 818 inline bool 819 operator!=(const tuple<_TElements...>& __t, 820 const tuple<_UElements...>& __u) 821 { return !(__t == __u); } 822 823 template<typename... _TElements, typename... _UElements> 824 inline bool 825 operator>(const tuple<_TElements...>& __t, 826 const tuple<_UElements...>& __u) 827 { return __u < __t; } 828 829 template<typename... _TElements, typename... _UElements> 830 inline bool 831 operator<=(const tuple<_TElements...>& __t, 832 const tuple<_UElements...>& __u) 833 { return !(__u < __t); } 834 835 template<typename... _TElements, typename... _UElements> 836 inline bool 837 operator>=(const tuple<_TElements...>& __t, 838 const tuple<_UElements...>& __u) 839 { return !(__t < __u); } 840 841 // NB: DR 705. 842 template<typename... _Elements> 843 constexpr tuple<typename __decay_and_strip<_Elements>::__type...> 844 make_tuple(_Elements&&... __args) 845 { 846 typedef tuple<typename __decay_and_strip<_Elements>::__type...> 847 __result_type; 848 return __result_type(std::forward<_Elements>(__args)...); 849 } 850 851 template<typename... _Elements> 852 constexpr tuple<_Elements&&...> 853 forward_as_tuple(_Elements&&... __args) noexcept 854 { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); } 855 856 857 template<typename, std::size_t> struct array; 858 859 template<std::size_t _Int, typename _Tp, std::size_t _Nm> 860 constexpr _Tp& get(array<_Tp, _Nm>&) noexcept; 861 862 template<std::size_t _Int, typename _Tp, std::size_t _Nm> 863 constexpr _Tp&& get(array<_Tp, _Nm>&&) noexcept; 864 865 template<std::size_t _Int, typename _Tp, std::size_t _Nm> 866 constexpr const _Tp& get(const array<_Tp, _Nm>&) noexcept; 867 868 template<typename> 869 struct __is_tuple_like_impl : false_type 870 { }; 871 872 template<typename... _Tps> 873 struct __is_tuple_like_impl<tuple<_Tps...>> : true_type 874 { }; 875 876 template<typename _T1, typename _T2> 877 struct __is_tuple_like_impl<pair<_T1, _T2>> : true_type 878 { }; 879 880 template<typename _Tp, std::size_t _Nm> 881 struct __is_tuple_like_impl<array<_Tp, _Nm>> : true_type 882 { }; 883 884 // Internal type trait that allows us to sfinae-protect tuple_cat. 885 template<typename _Tp> 886 struct __is_tuple_like 887 : public __is_tuple_like_impl<typename std::remove_cv 888 <typename std::remove_reference<_Tp>::type>::type>::type 889 { }; 890 891 // Stores a tuple of indices. Also used by bind() to extract the elements 892 // in a tuple. 893 template<std::size_t... _Indexes> 894 struct _Index_tuple 895 { 896 typedef _Index_tuple<_Indexes..., sizeof...(_Indexes)> __next; 897 }; 898 899 // Builds an _Index_tuple<0, 1, 2, ..., _Num-1>. 900 template<std::size_t _Num> 901 struct _Build_index_tuple 902 { 903 typedef typename _Build_index_tuple<_Num - 1>::__type::__next __type; 904 }; 905 906 template<> 907 struct _Build_index_tuple<0> 908 { 909 typedef _Index_tuple<> __type; 910 }; 911 912 template<std::size_t, typename, typename, std::size_t> 913 struct __make_tuple_impl; 914 915 template<std::size_t _Idx, typename _Tuple, typename... _Tp, 916 std::size_t _Nm> 917 struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm> 918 { 919 typedef typename __make_tuple_impl<_Idx + 1, tuple<_Tp..., 920 typename std::tuple_element<_Idx, _Tuple>::type>, _Tuple, _Nm>::__type 921 __type; 922 }; 923 924 template<std::size_t _Nm, typename _Tuple, typename... _Tp> 925 struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm> 926 { 927 typedef tuple<_Tp...> __type; 928 }; 929 930 template<typename _Tuple> 931 struct __do_make_tuple 932 : public __make_tuple_impl<0, tuple<>, _Tuple, 933 std::tuple_size<_Tuple>::value> 934 { }; 935 936 // Returns the std::tuple equivalent of a tuple-like type. 937 template<typename _Tuple> 938 struct __make_tuple 939 : public __do_make_tuple<typename std::remove_cv 940 <typename std::remove_reference<_Tuple>::type>::type> 941 { }; 942 943 // Combines several std::tuple's into a single one. 944 template<typename...> 945 struct __combine_tuples; 946 947 template<> 948 struct __combine_tuples<> 949 { 950 typedef tuple<> __type; 951 }; 952 953 template<typename... _Ts> 954 struct __combine_tuples<tuple<_Ts...>> 955 { 956 typedef tuple<_Ts...> __type; 957 }; 958 959 template<typename... _T1s, typename... _T2s, typename... _Rem> 960 struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...> 961 { 962 typedef typename __combine_tuples<tuple<_T1s..., _T2s...>, 963 _Rem...>::__type __type; 964 }; 965 966 // Computes the result type of tuple_cat given a set of tuple-like types. 967 template<typename... _Tpls> 968 struct __tuple_cat_result 969 { 970 typedef typename __combine_tuples 971 <typename __make_tuple<_Tpls>::__type...>::__type __type; 972 }; 973 974 // Helper to determine the index set for the first tuple-like 975 // type of a given set. 976 template<typename...> 977 struct __make_1st_indices; 978 979 template<> 980 struct __make_1st_indices<> 981 { 982 typedef std::_Index_tuple<> __type; 983 }; 984 985 template<typename _Tp, typename... _Tpls> 986 struct __make_1st_indices<_Tp, _Tpls...> 987 { 988 typedef typename std::_Build_index_tuple<std::tuple_size< 989 typename std::remove_reference<_Tp>::type>::value>::__type __type; 990 }; 991 992 // Performs the actual concatenation by step-wise expanding tuple-like 993 // objects into the elements, which are finally forwarded into the 994 // result tuple. 995 template<typename _Ret, typename _Indices, typename... _Tpls> 996 struct __tuple_concater; 997 998 template<typename _Ret, std::size_t... _Is, typename _Tp, typename... _Tpls> 999 struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...> 1000 { 1001 template<typename... _Us> 1002 static constexpr _Ret 1003 _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us) 1004 { 1005 typedef typename __make_1st_indices<_Tpls...>::__type __idx; 1006 typedef __tuple_concater<_Ret, __idx, _Tpls...> __next; 1007 return __next::_S_do(std::forward<_Tpls>(__tps)..., 1008 std::forward<_Us>(__us)..., 1009 std::get<_Is>(std::forward<_Tp>(__tp))...); 1010 } 1011 }; 1012 1013 template<typename _Ret> 1014 struct __tuple_concater<_Ret, std::_Index_tuple<>> 1015 { 1016 template<typename... _Us> 1017 static constexpr _Ret 1018 _S_do(_Us&&... __us) 1019 { 1020 return _Ret(std::forward<_Us>(__us)...); 1021 } 1022 }; 1023 1024 template<typename... _Tpls, typename = typename 1025 enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type> 1026 constexpr auto 1027 tuple_cat(_Tpls&&... __tpls) 1028 -> typename __tuple_cat_result<_Tpls...>::__type 1029 { 1030 typedef typename __tuple_cat_result<_Tpls...>::__type __ret; 1031 typedef typename __make_1st_indices<_Tpls...>::__type __idx; 1032 typedef __tuple_concater<__ret, __idx, _Tpls...> __concater; 1033 return __concater::_S_do(std::forward<_Tpls>(__tpls)...); 1034 } 1035 1036 template<typename... _Elements> 1037 inline tuple<_Elements&...> 1038 tie(_Elements&... __args) noexcept 1039 { return tuple<_Elements&...>(__args...); } 1040 1041 template<typename... _Elements> 1042 inline void 1043 swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y) 1044 noexcept(noexcept(__x.swap(__y))) 1045 { __x.swap(__y); } 1046 1047 // A class (and instance) which can be used in 'tie' when an element 1048 // of a tuple is not required 1049 struct _Swallow_assign 1050 { 1051 template<class _Tp> 1052 const _Swallow_assign& 1053 operator=(const _Tp&) const 1054 { return *this; } 1055 }; 1056 1057 const _Swallow_assign ignore{}; 1058 1059 /// Partial specialization for tuples 1060 template<typename... _Types, typename _Alloc> 1061 struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { }; 1062 1063 // See stl_pair.h... 1064 template<class _T1, class _T2> 1065 template<typename... _Args1, typename... _Args2> 1066 inline 1067 pair<_T1, _T2>:: 1068 pair(piecewise_construct_t, 1069 tuple<_Args1...> __first, tuple<_Args2...> __second) 1070 : pair(__first, __second, 1071 typename _Build_index_tuple<sizeof...(_Args1)>::__type(), 1072 typename _Build_index_tuple<sizeof...(_Args2)>::__type()) 1073 { } 1074 1075 template<class _T1, class _T2> 1076 template<typename... _Args1, std::size_t... _Indexes1, 1077 typename... _Args2, std::size_t... _Indexes2> 1078 inline 1079 pair<_T1, _T2>:: 1080 pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2, 1081 _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>) 1082 : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...), 1083 second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...) 1084 { } 1085 1086 _GLIBCXX_END_NAMESPACE_VERSION 1087 } // namespace 1088 1089 #endif // __GXX_EXPERIMENTAL_CXX0X__ 1090 1091 #endif // _GLIBCXX_TUPLE 1092