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