1 // <tuple> -*- C++ -*- 2 3 // Copyright (C) 2007-2014 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 #if __cplusplus > 201103L 714 template<std::size_t __i, typename _Tp> 715 using tuple_element_t = typename tuple_element<__i, _Tp>::type; 716 #endif 717 718 /// Finds the size of a given tuple type. 719 template<typename _Tp> 720 struct tuple_size; 721 722 // _GLIBCXX_RESOLVE_LIB_DEFECTS 723 // 2313. tuple_size should always derive from integral_constant<size_t, N> 724 template<typename _Tp> 725 struct tuple_size<const _Tp> 726 : public integral_constant<size_t, tuple_size<_Tp>::value> { }; 727 728 template<typename _Tp> 729 struct tuple_size<volatile _Tp> 730 : public integral_constant<size_t, tuple_size<_Tp>::value> { }; 731 732 template<typename _Tp> 733 struct tuple_size<const volatile _Tp> 734 : public integral_constant<size_t, tuple_size<_Tp>::value> { }; 735 736 /// class tuple_size 737 template<typename... _Elements> 738 struct tuple_size<tuple<_Elements...>> 739 : public integral_constant<std::size_t, sizeof...(_Elements)> { }; 740 741 template<std::size_t __i, typename _Head, typename... _Tail> 742 constexpr typename __add_ref<_Head>::type 743 __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 744 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 745 746 template<std::size_t __i, typename _Head, typename... _Tail> 747 constexpr typename __add_c_ref<_Head>::type 748 __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 749 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 750 751 /// Return a reference to the ith element of a tuple. 752 template<std::size_t __i, typename... _Elements> 753 constexpr typename __add_ref< 754 typename tuple_element<__i, tuple<_Elements...>>::type 755 >::type 756 get(tuple<_Elements...>& __t) noexcept 757 { return std::__get_helper<__i>(__t); } 758 759 /// Return a const reference to the ith element of a const tuple. 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 std::__get_helper<__i>(__t); } 766 767 /// Return an rvalue reference to the ith element of a tuple rvalue. 768 template<std::size_t __i, typename... _Elements> 769 constexpr typename __add_r_ref< 770 typename tuple_element<__i, tuple<_Elements...>>::type 771 >::type 772 get(tuple<_Elements...>&& __t) noexcept 773 { return std::forward<typename tuple_element<__i, 774 tuple<_Elements...>>::type&&>(get<__i>(__t)); } 775 776 #if __cplusplus > 201103L 777 template<typename _Head, size_t __i, typename... _Tail> 778 constexpr typename __add_ref<_Head>::type 779 __get_helper2(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 780 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 781 782 template<typename _Head, size_t __i, typename... _Tail> 783 constexpr typename __add_c_ref<_Head>::type 784 __get_helper2(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 785 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 786 787 /// Return a reference to the unique element of type _Tp of a tuple. 788 template <typename _Tp, typename... _Types> 789 constexpr _Tp& 790 get(tuple<_Types...>& __t) noexcept 791 { return std::__get_helper2<_Tp>(__t); } 792 793 /// Return a reference to the unique element of type _Tp of a tuple rvalue. 794 template <typename _Tp, typename... _Types> 795 constexpr _Tp&& 796 get(tuple<_Types...>&& __t) noexcept 797 { return std::forward<_Tp&&>(std::__get_helper2<_Tp>(__t)); } 798 799 /// Return a const reference to the unique element of type _Tp of a tuple. 800 template <typename _Tp, typename... _Types> 801 constexpr const _Tp& 802 get(const tuple<_Types...>& __t) noexcept 803 { return std::__get_helper2<_Tp>(__t); } 804 #endif 805 806 807 // This class helps construct the various comparison operations on tuples 808 template<std::size_t __check_equal_size, std::size_t __i, std::size_t __j, 809 typename _Tp, typename _Up> 810 struct __tuple_compare; 811 812 template<std::size_t __i, std::size_t __j, typename _Tp, typename _Up> 813 struct __tuple_compare<0, __i, __j, _Tp, _Up> 814 { 815 static constexpr bool 816 __eq(const _Tp& __t, const _Up& __u) 817 { 818 return (get<__i>(__t) == get<__i>(__u) && 819 __tuple_compare<0, __i + 1, __j, _Tp, _Up>::__eq(__t, __u)); 820 } 821 822 static constexpr bool 823 __less(const _Tp& __t, const _Up& __u) 824 { 825 return ((get<__i>(__t) < get<__i>(__u)) 826 || !(get<__i>(__u) < get<__i>(__t)) && 827 __tuple_compare<0, __i + 1, __j, _Tp, _Up>::__less(__t, __u)); 828 } 829 }; 830 831 template<std::size_t __i, typename _Tp, typename _Up> 832 struct __tuple_compare<0, __i, __i, _Tp, _Up> 833 { 834 static constexpr bool 835 __eq(const _Tp&, const _Up&) { return true; } 836 837 static constexpr bool 838 __less(const _Tp&, const _Up&) { return false; } 839 }; 840 841 template<typename... _TElements, typename... _UElements> 842 constexpr bool 843 operator==(const tuple<_TElements...>& __t, 844 const tuple<_UElements...>& __u) 845 { 846 typedef tuple<_TElements...> _Tp; 847 typedef tuple<_UElements...> _Up; 848 return bool(__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value, 849 0, tuple_size<_Tp>::value, _Tp, _Up>::__eq(__t, __u)); 850 } 851 852 template<typename... _TElements, typename... _UElements> 853 constexpr bool 854 operator<(const tuple<_TElements...>& __t, 855 const tuple<_UElements...>& __u) 856 { 857 typedef tuple<_TElements...> _Tp; 858 typedef tuple<_UElements...> _Up; 859 return bool(__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value, 860 0, tuple_size<_Tp>::value, _Tp, _Up>::__less(__t, __u)); 861 } 862 863 template<typename... _TElements, typename... _UElements> 864 constexpr bool 865 operator!=(const tuple<_TElements...>& __t, 866 const tuple<_UElements...>& __u) 867 { return !(__t == __u); } 868 869 template<typename... _TElements, typename... _UElements> 870 constexpr bool 871 operator>(const tuple<_TElements...>& __t, 872 const tuple<_UElements...>& __u) 873 { return __u < __t; } 874 875 template<typename... _TElements, typename... _UElements> 876 constexpr bool 877 operator<=(const tuple<_TElements...>& __t, 878 const tuple<_UElements...>& __u) 879 { return !(__u < __t); } 880 881 template<typename... _TElements, typename... _UElements> 882 constexpr bool 883 operator>=(const tuple<_TElements...>& __t, 884 const tuple<_UElements...>& __u) 885 { return !(__t < __u); } 886 887 // NB: DR 705. 888 template<typename... _Elements> 889 constexpr tuple<typename __decay_and_strip<_Elements>::__type...> 890 make_tuple(_Elements&&... __args) 891 { 892 typedef tuple<typename __decay_and_strip<_Elements>::__type...> 893 __result_type; 894 return __result_type(std::forward<_Elements>(__args)...); 895 } 896 897 template<typename... _Elements> 898 tuple<_Elements&&...> 899 forward_as_tuple(_Elements&&... __args) noexcept 900 { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); } 901 902 template<typename> 903 struct __is_tuple_like_impl : false_type 904 { }; 905 906 template<typename... _Tps> 907 struct __is_tuple_like_impl<tuple<_Tps...>> : true_type 908 { }; 909 910 template<typename _T1, typename _T2> 911 struct __is_tuple_like_impl<pair<_T1, _T2>> : true_type 912 { }; 913 914 template<typename _Tp, std::size_t _Nm> 915 struct __is_tuple_like_impl<array<_Tp, _Nm>> : true_type 916 { }; 917 918 // Internal type trait that allows us to sfinae-protect tuple_cat. 919 template<typename _Tp> 920 struct __is_tuple_like 921 : public __is_tuple_like_impl<typename std::remove_cv 922 <typename std::remove_reference<_Tp>::type>::type>::type 923 { }; 924 925 template<std::size_t, typename, typename, std::size_t> 926 struct __make_tuple_impl; 927 928 template<std::size_t _Idx, typename _Tuple, typename... _Tp, 929 std::size_t _Nm> 930 struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm> 931 { 932 typedef typename __make_tuple_impl<_Idx + 1, tuple<_Tp..., 933 typename std::tuple_element<_Idx, _Tuple>::type>, _Tuple, _Nm>::__type 934 __type; 935 }; 936 937 template<std::size_t _Nm, typename _Tuple, typename... _Tp> 938 struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm> 939 { 940 typedef tuple<_Tp...> __type; 941 }; 942 943 template<typename _Tuple> 944 struct __do_make_tuple 945 : public __make_tuple_impl<0, tuple<>, _Tuple, 946 std::tuple_size<_Tuple>::value> 947 { }; 948 949 // Returns the std::tuple equivalent of a tuple-like type. 950 template<typename _Tuple> 951 struct __make_tuple 952 : public __do_make_tuple<typename std::remove_cv 953 <typename std::remove_reference<_Tuple>::type>::type> 954 { }; 955 956 // Combines several std::tuple's into a single one. 957 template<typename...> 958 struct __combine_tuples; 959 960 template<> 961 struct __combine_tuples<> 962 { 963 typedef tuple<> __type; 964 }; 965 966 template<typename... _Ts> 967 struct __combine_tuples<tuple<_Ts...>> 968 { 969 typedef tuple<_Ts...> __type; 970 }; 971 972 template<typename... _T1s, typename... _T2s, typename... _Rem> 973 struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...> 974 { 975 typedef typename __combine_tuples<tuple<_T1s..., _T2s...>, 976 _Rem...>::__type __type; 977 }; 978 979 // Computes the result type of tuple_cat given a set of tuple-like types. 980 template<typename... _Tpls> 981 struct __tuple_cat_result 982 { 983 typedef typename __combine_tuples 984 <typename __make_tuple<_Tpls>::__type...>::__type __type; 985 }; 986 987 // Helper to determine the index set for the first tuple-like 988 // type of a given set. 989 template<typename...> 990 struct __make_1st_indices; 991 992 template<> 993 struct __make_1st_indices<> 994 { 995 typedef std::_Index_tuple<> __type; 996 }; 997 998 template<typename _Tp, typename... _Tpls> 999 struct __make_1st_indices<_Tp, _Tpls...> 1000 { 1001 typedef typename std::_Build_index_tuple<std::tuple_size< 1002 typename std::remove_reference<_Tp>::type>::value>::__type __type; 1003 }; 1004 1005 // Performs the actual concatenation by step-wise expanding tuple-like 1006 // objects into the elements, which are finally forwarded into the 1007 // result tuple. 1008 template<typename _Ret, typename _Indices, typename... _Tpls> 1009 struct __tuple_concater; 1010 1011 template<typename _Ret, std::size_t... _Is, typename _Tp, typename... _Tpls> 1012 struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...> 1013 { 1014 template<typename... _Us> 1015 static constexpr _Ret 1016 _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us) 1017 { 1018 typedef typename __make_1st_indices<_Tpls...>::__type __idx; 1019 typedef __tuple_concater<_Ret, __idx, _Tpls...> __next; 1020 return __next::_S_do(std::forward<_Tpls>(__tps)..., 1021 std::forward<_Us>(__us)..., 1022 std::get<_Is>(std::forward<_Tp>(__tp))...); 1023 } 1024 }; 1025 1026 template<typename _Ret> 1027 struct __tuple_concater<_Ret, std::_Index_tuple<>> 1028 { 1029 template<typename... _Us> 1030 static constexpr _Ret 1031 _S_do(_Us&&... __us) 1032 { 1033 return _Ret(std::forward<_Us>(__us)...); 1034 } 1035 }; 1036 1037 /// tuple_cat 1038 template<typename... _Tpls, typename = typename 1039 enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type> 1040 constexpr auto 1041 tuple_cat(_Tpls&&... __tpls) 1042 -> typename __tuple_cat_result<_Tpls...>::__type 1043 { 1044 typedef typename __tuple_cat_result<_Tpls...>::__type __ret; 1045 typedef typename __make_1st_indices<_Tpls...>::__type __idx; 1046 typedef __tuple_concater<__ret, __idx, _Tpls...> __concater; 1047 return __concater::_S_do(std::forward<_Tpls>(__tpls)...); 1048 } 1049 1050 /// tie 1051 template<typename... _Elements> 1052 inline tuple<_Elements&...> 1053 tie(_Elements&... __args) noexcept 1054 { return tuple<_Elements&...>(__args...); } 1055 1056 /// swap 1057 template<typename... _Elements> 1058 inline void 1059 swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y) 1060 noexcept(noexcept(__x.swap(__y))) 1061 { __x.swap(__y); } 1062 1063 // A class (and instance) which can be used in 'tie' when an element 1064 // of a tuple is not required 1065 struct _Swallow_assign 1066 { 1067 template<class _Tp> 1068 const _Swallow_assign& 1069 operator=(const _Tp&) const 1070 { return *this; } 1071 }; 1072 1073 const _Swallow_assign ignore{}; 1074 1075 /// Partial specialization for tuples 1076 template<typename... _Types, typename _Alloc> 1077 struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { }; 1078 1079 // See stl_pair.h... 1080 template<class _T1, class _T2> 1081 template<typename... _Args1, typename... _Args2> 1082 inline 1083 pair<_T1, _T2>:: 1084 pair(piecewise_construct_t, 1085 tuple<_Args1...> __first, tuple<_Args2...> __second) 1086 : pair(__first, __second, 1087 typename _Build_index_tuple<sizeof...(_Args1)>::__type(), 1088 typename _Build_index_tuple<sizeof...(_Args2)>::__type()) 1089 { } 1090 1091 template<class _T1, class _T2> 1092 template<typename... _Args1, std::size_t... _Indexes1, 1093 typename... _Args2, std::size_t... _Indexes2> 1094 inline 1095 pair<_T1, _T2>:: 1096 pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2, 1097 _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>) 1098 : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...), 1099 second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...) 1100 { } 1101 1102 /// @} 1103 1104 _GLIBCXX_END_NAMESPACE_VERSION 1105 } // namespace std 1106 1107 #endif // C++11 1108 1109 #endif // _GLIBCXX_TUPLE 1110