1// -*- C++ -*- 2//===--------------------------- tuple ------------------------------------===// 3// 4// The LLVM Compiler Infrastructure 5// 6// This file is distributed under the University of Illinois Open Source 7// License. See LICENSE.TXT for details. 8// 9//===----------------------------------------------------------------------===// 10 11#ifndef _LIBCPP_TUPLE 12#define _LIBCPP_TUPLE 13 14/* 15 tuple synopsis 16 17namespace std 18{ 19 20template <class... T> 21class tuple { 22public: 23 constexpr tuple(); 24 explicit tuple(const T&...); 25 template <class... U> 26 explicit tuple(U&&...); 27 tuple(const tuple&) = default; 28 tuple(tuple&&) = default; 29 template <class... U> 30 tuple(const tuple<U...>&); 31 template <class... U> 32 tuple(tuple<U...>&&); 33 template <class U1, class U2> 34 tuple(const pair<U1, U2>&); // iff sizeof...(T) == 2 35 template <class U1, class U2> 36 tuple(pair<U1, U2>&&); // iff sizeof...(T) == 2 37 38 // allocator-extended constructors 39 template <class Alloc> 40 tuple(allocator_arg_t, const Alloc& a); 41 template <class Alloc> 42 tuple(allocator_arg_t, const Alloc& a, const T&...); 43 template <class Alloc, class... U> 44 tuple(allocator_arg_t, const Alloc& a, U&&...); 45 template <class Alloc> 46 tuple(allocator_arg_t, const Alloc& a, const tuple&); 47 template <class Alloc> 48 tuple(allocator_arg_t, const Alloc& a, tuple&&); 49 template <class Alloc, class... U> 50 tuple(allocator_arg_t, const Alloc& a, const tuple<U...>&); 51 template <class Alloc, class... U> 52 tuple(allocator_arg_t, const Alloc& a, tuple<U...>&&); 53 template <class Alloc, class U1, class U2> 54 tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&); 55 template <class Alloc, class U1, class U2> 56 tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&); 57 58 tuple& operator=(const tuple&); 59 tuple& 60 operator=(tuple&&) noexcept(AND(is_nothrow_move_assignable<T>::value ...)); 61 template <class... U> 62 tuple& operator=(const tuple<U...>&); 63 template <class... U> 64 tuple& operator=(tuple<U...>&&); 65 template <class U1, class U2> 66 tuple& operator=(const pair<U1, U2>&); // iff sizeof...(T) == 2 67 template <class U1, class U2> 68 tuple& operator=(pair<U1, U2>&&); //iffsizeof...(T) == 2 69 70 void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...)); 71}; 72 73const unspecified ignore; 74 75template <class... T> tuple<V...> make_tuple(T&&...); 76template <class... T> tuple<ATypes...> forward_as_tuple(T&&...) noexcept; 77template <class... T> tuple<T&...> tie(T&...) noexcept; 78template <class... Tuples> tuple<CTypes...> tuple_cat(Tuples&&... tpls); 79 80// 20.4.1.4, tuple helper classes: 81template <class T> class tuple_size; // undefined 82template <class... T> class tuple_size<tuple<T...>>; 83template <intsize_t I, class T> class tuple_element; // undefined 84template <intsize_t I, class... T> class tuple_element<I, tuple<T...>>; 85 86// 20.4.1.5, element access: 87template <intsize_t I, class... T> 88 typename tuple_element<I, tuple<T...>>::type& 89 get(tuple<T...>&) noexcept; 90template <intsize_t I, class... T> 91 typename tuple_element<I, tuple<T...>>::type const& 92 get(const tuple<T...>&) noexcept; 93template <intsize_t I, class... T> 94 typename tuple_element<I, tuple<T...>>::type&& 95 get(tuple<T...>&&) noexcept; 96 97// 20.4.1.6, relational operators: 98template<class... T, class... U> bool operator==(const tuple<T...>&, const tuple<U...>&); 99template<class... T, class... U> bool operator<(const tuple<T...>&, const tuple<U...>&); 100template<class... T, class... U> bool operator!=(const tuple<T...>&, const tuple<U...>&); 101template<class... T, class... U> bool operator>(const tuple<T...>&, const tuple<U...>&); 102template<class... T, class... U> bool operator<=(const tuple<T...>&, const tuple<U...>&); 103template<class... T, class... U> bool operator>=(const tuple<T...>&, const tuple<U...>&); 104 105template <class... Types, class Alloc> 106 struct uses_allocator<tuple<Types...>, Alloc>; 107 108template <class... Types> 109 void 110 swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(noexcept(x.swap(y))); 111 112} // std 113 114*/ 115 116#include <__config> 117#include <__tuple> 118#include <cstddef> 119#include <memory> 120#include <type_traits> 121 122#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 123#pragma GCC system_header 124#endif 125 126_LIBCPP_BEGIN_NAMESPACE_STD 127 128#ifndef _LIBCPP_HAS_NO_VARIADICS 129 130// tuple_size 131 132template <class ..._Tp> 133class _LIBCPP_VISIBLE tuple_size<tuple<_Tp...> > 134 : public integral_constant<size_t, sizeof...(_Tp)> 135{ 136}; 137 138// tuple_element 139 140template <size_t _Ip, class ..._Tp> 141class _LIBCPP_VISIBLE tuple_element<_Ip, tuple<_Tp...> > 142{ 143public: 144 typedef typename tuple_element<_Ip, __tuple_types<_Tp...> >::type type; 145}; 146 147// __tuple_leaf 148 149template <size_t _Ip, class _Hp, bool=is_empty<_Hp>::value 150#if __has_feature(is_final) 151 && !__is_final(_Hp) 152#endif 153 > 154class __tuple_leaf; 155 156template <size_t _Ip, class _Hp, bool _Ep> 157inline _LIBCPP_INLINE_VISIBILITY 158void swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y) 159 _NOEXCEPT_(__is_nothrow_swappable<_Hp>::value) 160{ 161 swap(__x.get(), __y.get()); 162} 163 164template <size_t _Ip, class _Hp, bool> 165class __tuple_leaf 166{ 167 _Hp value; 168 169 __tuple_leaf& operator=(const __tuple_leaf&); 170public: 171 _LIBCPP_INLINE_VISIBILITY __tuple_leaf() : value() 172 {static_assert(!is_reference<_Hp>::value, 173 "Attempted to default construct a reference element in a tuple");} 174 175 template <class _Alloc> 176 _LIBCPP_INLINE_VISIBILITY 177 __tuple_leaf(integral_constant<int, 0>, const _Alloc&) 178 : value() 179 {static_assert(!is_reference<_Hp>::value, 180 "Attempted to default construct a reference element in a tuple");} 181 182 template <class _Alloc> 183 _LIBCPP_INLINE_VISIBILITY 184 __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a) 185 : value(allocator_arg_t(), __a) 186 {static_assert(!is_reference<_Hp>::value, 187 "Attempted to default construct a reference element in a tuple");} 188 189 template <class _Alloc> 190 _LIBCPP_INLINE_VISIBILITY 191 __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a) 192 : value(__a) 193 {static_assert(!is_reference<_Hp>::value, 194 "Attempted to default construct a reference element in a tuple");} 195 196 template <class _Tp, 197 class = typename enable_if<is_constructible<_Hp, _Tp>::value>::type> 198 _LIBCPP_INLINE_VISIBILITY 199 explicit __tuple_leaf(_Tp&& __t) 200 : value(_VSTD::forward<_Tp>(__t)) 201 {static_assert(!is_reference<_Hp>::value || 202 (is_lvalue_reference<_Hp>::value && 203 (is_lvalue_reference<_Tp>::value || 204 is_same<typename remove_reference<_Tp>::type, 205 reference_wrapper< 206 typename remove_reference<_Hp>::type 207 > 208 >::value)) || 209 (is_rvalue_reference<_Hp>::value && 210 !is_lvalue_reference<_Tp>::value), 211 "Attempted to construct a reference element in a tuple with an rvalue");} 212 213 template <class _Tp, class _Alloc> 214 _LIBCPP_INLINE_VISIBILITY 215 explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t) 216 : value(_VSTD::forward<_Tp>(__t)) 217 {static_assert(!is_lvalue_reference<_Hp>::value || 218 (is_lvalue_reference<_Hp>::value && 219 (is_lvalue_reference<_Tp>::value || 220 is_same<typename remove_reference<_Tp>::type, 221 reference_wrapper< 222 typename remove_reference<_Hp>::type 223 > 224 >::value)), 225 "Attempted to construct a reference element in a tuple with an rvalue");} 226 227 template <class _Tp, class _Alloc> 228 _LIBCPP_INLINE_VISIBILITY 229 explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t) 230 : value(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) 231 {static_assert(!is_lvalue_reference<_Hp>::value || 232 (is_lvalue_reference<_Hp>::value && 233 (is_lvalue_reference<_Tp>::value || 234 is_same<typename remove_reference<_Tp>::type, 235 reference_wrapper< 236 typename remove_reference<_Hp>::type 237 > 238 >::value)), 239 "Attempted to construct a reference element in a tuple with an rvalue");} 240 241 template <class _Tp, class _Alloc> 242 _LIBCPP_INLINE_VISIBILITY 243 explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t) 244 : value(_VSTD::forward<_Tp>(__t), __a) 245 {static_assert(!is_lvalue_reference<_Hp>::value || 246 (is_lvalue_reference<_Hp>::value && 247 (is_lvalue_reference<_Tp>::value || 248 is_same<typename remove_reference<_Tp>::type, 249 reference_wrapper< 250 typename remove_reference<_Hp>::type 251 > 252 >::value)), 253 "Attempted to construct a reference element in a tuple with an rvalue");} 254 255 __tuple_leaf(const __tuple_leaf& __t) 256 : value(__t.get()) 257 {static_assert(!is_rvalue_reference<_Hp>::value, "Can not copy a tuple with rvalue reference member");} 258 259 template <class _Tp> 260 _LIBCPP_INLINE_VISIBILITY 261 explicit __tuple_leaf(const __tuple_leaf<_Ip, _Tp>& __t) 262 : value(__t.get()) {} 263 264 template <class _Tp> 265 _LIBCPP_INLINE_VISIBILITY 266 __tuple_leaf& 267 operator=(_Tp&& __t) 268 { 269 value = _VSTD::forward<_Tp>(__t); 270 return *this; 271 } 272 273 _LIBCPP_INLINE_VISIBILITY 274 int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value) 275 { 276 _VSTD::swap(*this, __t); 277 return 0; 278 } 279 280 _LIBCPP_INLINE_VISIBILITY _Hp& get() {return value;} 281 _LIBCPP_INLINE_VISIBILITY const _Hp& get() const {return value;} 282}; 283 284template <size_t _Ip, class _Hp> 285class __tuple_leaf<_Ip, _Hp, true> 286 : private _Hp 287{ 288 289 __tuple_leaf& operator=(const __tuple_leaf&); 290public: 291 _LIBCPP_INLINE_VISIBILITY __tuple_leaf() {} 292 293 template <class _Alloc> 294 _LIBCPP_INLINE_VISIBILITY 295 __tuple_leaf(integral_constant<int, 0>, const _Alloc&) {} 296 297 template <class _Alloc> 298 _LIBCPP_INLINE_VISIBILITY 299 __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a) 300 : _Hp(allocator_arg_t(), __a) {} 301 302 template <class _Alloc> 303 _LIBCPP_INLINE_VISIBILITY 304 __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a) 305 : _Hp(__a) {} 306 307 template <class _Tp, 308 class = typename enable_if<is_constructible<_Hp, _Tp>::value>::type> 309 _LIBCPP_INLINE_VISIBILITY 310 explicit __tuple_leaf(_Tp&& __t) 311 : _Hp(_VSTD::forward<_Tp>(__t)) {} 312 313 template <class _Tp, class _Alloc> 314 _LIBCPP_INLINE_VISIBILITY 315 explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t) 316 : _Hp(_VSTD::forward<_Tp>(__t)) {} 317 318 template <class _Tp, class _Alloc> 319 _LIBCPP_INLINE_VISIBILITY 320 explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t) 321 : _Hp(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) {} 322 323 template <class _Tp, class _Alloc> 324 _LIBCPP_INLINE_VISIBILITY 325 explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t) 326 : _Hp(_VSTD::forward<_Tp>(__t), __a) {} 327 328 template <class _Tp> 329 _LIBCPP_INLINE_VISIBILITY 330 explicit __tuple_leaf(const __tuple_leaf<_Ip, _Tp>& __t) 331 : _Hp(__t.get()) {} 332 333 template <class _Tp> 334 _LIBCPP_INLINE_VISIBILITY 335 __tuple_leaf& 336 operator=(_Tp&& __t) 337 { 338 _Hp::operator=(_VSTD::forward<_Tp>(__t)); 339 return *this; 340 } 341 342 _LIBCPP_INLINE_VISIBILITY 343 int 344 swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value) 345 { 346 _VSTD::swap(*this, __t); 347 return 0; 348 } 349 350 _LIBCPP_INLINE_VISIBILITY _Hp& get() {return static_cast<_Hp&>(*this);} 351 _LIBCPP_INLINE_VISIBILITY const _Hp& get() const {return static_cast<const _Hp&>(*this);} 352}; 353 354template <class ..._Tp> 355_LIBCPP_INLINE_VISIBILITY 356void __swallow(_Tp&&...) {} 357 358template <bool ...> struct __all; 359 360template <> 361struct __all<> 362{ 363 static const bool value = true; 364}; 365 366template <bool _B0, bool ... _Bp> 367struct __all<_B0, _Bp...> 368{ 369 static const bool value = _B0 && __all<_Bp...>::value; 370}; 371 372// __tuple_impl 373 374template<class _Indx, class ..._Tp> struct __tuple_impl; 375 376template<size_t ..._Indx, class ..._Tp> 377struct __tuple_impl<__tuple_indices<_Indx...>, _Tp...> 378 : public __tuple_leaf<_Indx, _Tp>... 379{ 380 template <size_t ..._Uf, class ..._Tf, 381 size_t ..._Ul, class ..._Tl, class ..._Up> 382 _LIBCPP_INLINE_VISIBILITY 383 explicit 384 __tuple_impl(__tuple_indices<_Uf...>, __tuple_types<_Tf...>, 385 __tuple_indices<_Ul...>, __tuple_types<_Tl...>, 386 _Up&&... __u) : 387 __tuple_leaf<_Uf, _Tf>(_VSTD::forward<_Up>(__u))..., 388 __tuple_leaf<_Ul, _Tl>()... 389 {} 390 391 template <class _Alloc, size_t ..._Uf, class ..._Tf, 392 size_t ..._Ul, class ..._Tl, class ..._Up> 393 _LIBCPP_INLINE_VISIBILITY 394 explicit 395 __tuple_impl(allocator_arg_t, const _Alloc& __a, 396 __tuple_indices<_Uf...>, __tuple_types<_Tf...>, 397 __tuple_indices<_Ul...>, __tuple_types<_Tl...>, 398 _Up&&... __u) : 399 __tuple_leaf<_Uf, _Tf>(__uses_alloc_ctor<_Tf, _Alloc, _Up>(), __a, 400 _VSTD::forward<_Up>(__u))..., 401 __tuple_leaf<_Ul, _Tl>(__uses_alloc_ctor<_Tl, _Alloc>(), __a)... 402 {} 403 404 template <class _Tuple, 405 class = typename enable_if 406 < 407 __tuple_convertible<_Tuple, tuple<_Tp...> >::value 408 >::type 409 > 410 _LIBCPP_INLINE_VISIBILITY 411 __tuple_impl(_Tuple&& __t) 412 : __tuple_leaf<_Indx, _Tp>(_VSTD::forward<typename tuple_element<_Indx, 413 typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))... 414 {} 415 416 template <class _Alloc, class _Tuple, 417 class = typename enable_if 418 < 419 __tuple_convertible<_Tuple, tuple<_Tp...> >::value 420 >::type 421 > 422 _LIBCPP_INLINE_VISIBILITY 423 __tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t) 424 : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, typename tuple_element<_Indx, 425 typename __make_tuple_types<_Tuple>::type>::type>(), __a, 426 _VSTD::forward<typename tuple_element<_Indx, 427 typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))... 428 {} 429 430 template <class _Tuple> 431 _LIBCPP_INLINE_VISIBILITY 432 typename enable_if 433 < 434 __tuple_assignable<_Tuple, tuple<_Tp...> >::value, 435 __tuple_impl& 436 >::type 437 operator=(_Tuple&& __t) 438 { 439 __swallow(__tuple_leaf<_Indx, _Tp>::operator=(_VSTD::forward<typename tuple_element<_Indx, 440 typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...); 441 return *this; 442 } 443 444 _LIBCPP_INLINE_VISIBILITY 445 void swap(__tuple_impl& __t) 446 _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value) 447 { 448 __swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...); 449 } 450}; 451 452template <class ..._Tp> 453class _LIBCPP_VISIBLE tuple 454{ 455 typedef __tuple_impl<typename __make_tuple_indices<sizeof...(_Tp)>::type, _Tp...> base; 456 457 base base_; 458 459 template <size_t _Jp, class ..._Up> friend 460 typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT; 461 template <size_t _Jp, class ..._Up> friend 462 const typename tuple_element<_Jp, tuple<_Up...> >::type& get(const tuple<_Up...>&) _NOEXCEPT; 463 template <size_t _Jp, class ..._Up> friend 464 typename tuple_element<_Jp, tuple<_Up...> >::type&& get(tuple<_Up...>&&) _NOEXCEPT; 465public: 466 467 _LIBCPP_INLINE_VISIBILITY 468 explicit tuple(const _Tp& ... __t) 469 : base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(), 470 typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(), 471 typename __make_tuple_indices<0>::type(), 472 typename __make_tuple_types<tuple, 0>::type(), 473 __t... 474 ) {} 475 476 template <class _Alloc> 477 _LIBCPP_INLINE_VISIBILITY 478 tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t) 479 : base_(allocator_arg_t(), __a, 480 typename __make_tuple_indices<sizeof...(_Tp)>::type(), 481 typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(), 482 typename __make_tuple_indices<0>::type(), 483 typename __make_tuple_types<tuple, 0>::type(), 484 __t... 485 ) {} 486 487 template <class ..._Up, 488 class = typename enable_if 489 < 490 sizeof...(_Up) <= sizeof...(_Tp) && 491 __tuple_convertible 492 < 493 tuple<_Up...>, 494 typename __make_tuple_types<tuple, 495 sizeof...(_Up) < sizeof...(_Tp) ? 496 sizeof...(_Up) : 497 sizeof...(_Tp)>::type 498 >::value 499 >::type 500 > 501 _LIBCPP_INLINE_VISIBILITY 502 explicit 503 tuple(_Up&&... __u) 504 : base_(typename __make_tuple_indices<sizeof...(_Up)>::type(), 505 typename __make_tuple_types<tuple, sizeof...(_Up)>::type(), 506 typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(), 507 typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(), 508 _VSTD::forward<_Up>(__u)...) {} 509 510 template <class _Alloc, class ..._Up, 511 class = typename enable_if 512 < 513 sizeof...(_Up) <= sizeof...(_Tp) && 514 __tuple_convertible 515 < 516 tuple<_Up...>, 517 typename __make_tuple_types<tuple, 518 sizeof...(_Up) < sizeof...(_Tp) ? 519 sizeof...(_Up) : 520 sizeof...(_Tp)>::type 521 >::value 522 >::type 523 > 524 _LIBCPP_INLINE_VISIBILITY 525 tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u) 526 : base_(allocator_arg_t(), __a, 527 typename __make_tuple_indices<sizeof...(_Up)>::type(), 528 typename __make_tuple_types<tuple, sizeof...(_Up)>::type(), 529 typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(), 530 typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(), 531 _VSTD::forward<_Up>(__u)...) {} 532 533 template <class _Tuple, 534 class = typename enable_if 535 < 536 __tuple_convertible<_Tuple, tuple>::value 537 >::type 538 > 539 _LIBCPP_INLINE_VISIBILITY 540 tuple(_Tuple&& __t) 541 : base_(_VSTD::forward<_Tuple>(__t)) {} 542 543 template <class _Alloc, class _Tuple, 544 class = typename enable_if 545 < 546 __tuple_convertible<_Tuple, tuple>::value 547 >::type 548 > 549 _LIBCPP_INLINE_VISIBILITY 550 tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t) 551 : base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {} 552 553 template <class _Tuple, 554 class = typename enable_if 555 < 556 __tuple_assignable<_Tuple, tuple>::value 557 >::type 558 > 559 _LIBCPP_INLINE_VISIBILITY 560 tuple& 561 operator=(_Tuple&& __t) 562 { 563 base_.operator=(_VSTD::forward<_Tuple>(__t)); 564 return *this; 565 } 566 567 _LIBCPP_INLINE_VISIBILITY 568 void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value) 569 {base_.swap(__t.base_);} 570}; 571 572template <> 573class _LIBCPP_VISIBLE tuple<> 574{ 575public: 576 _LIBCPP_INLINE_VISIBILITY 577 tuple() {} 578 template <class _Alloc> 579 _LIBCPP_INLINE_VISIBILITY 580 tuple(allocator_arg_t, const _Alloc&) {} 581 template <class _Alloc> 582 _LIBCPP_INLINE_VISIBILITY 583 tuple(allocator_arg_t, const _Alloc&, const tuple&) {} 584 template <class _Up> 585 _LIBCPP_INLINE_VISIBILITY 586 tuple(array<_Up, 0>) {} 587 template <class _Alloc, class _Up> 588 _LIBCPP_INLINE_VISIBILITY 589 tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) {} 590 _LIBCPP_INLINE_VISIBILITY 591 void swap(tuple&) _NOEXCEPT {} 592}; 593 594template <class ..._Tp> 595inline _LIBCPP_INLINE_VISIBILITY 596typename enable_if 597< 598 __all<__is_swappable<_Tp>::value...>::value, 599 void 600>::type 601swap(tuple<_Tp...>& __t, tuple<_Tp...>& __u) 602 _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value) 603 {__t.swap(__u);} 604 605// get 606 607template <size_t _Ip, class ..._Tp> 608inline _LIBCPP_INLINE_VISIBILITY 609typename tuple_element<_Ip, tuple<_Tp...> >::type& 610get(tuple<_Tp...>& __t) _NOEXCEPT 611{ 612 typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type; 613 return static_cast<__tuple_leaf<_Ip, type>&>(__t.base_).get(); 614} 615 616template <size_t _Ip, class ..._Tp> 617inline _LIBCPP_INLINE_VISIBILITY 618const typename tuple_element<_Ip, tuple<_Tp...> >::type& 619get(const tuple<_Tp...>& __t) _NOEXCEPT 620{ 621 typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type; 622 return static_cast<const __tuple_leaf<_Ip, type>&>(__t.base_).get(); 623} 624 625template <size_t _Ip, class ..._Tp> 626inline _LIBCPP_INLINE_VISIBILITY 627typename tuple_element<_Ip, tuple<_Tp...> >::type&& 628get(tuple<_Tp...>&& __t) _NOEXCEPT 629{ 630 typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type; 631 return static_cast<type&&>( 632 static_cast<__tuple_leaf<_Ip, type>&&>(__t.base_).get()); 633} 634 635// tie 636 637template <class ..._Tp> 638inline _LIBCPP_INLINE_VISIBILITY 639tuple<_Tp&...> 640tie(_Tp&... __t) 641{ 642 return tuple<_Tp&...>(__t...); 643} 644 645template <class _Up> 646struct __ignore_t 647{ 648 template <class _Tp> 649 _LIBCPP_INLINE_VISIBILITY 650 const __ignore_t& operator=(_Tp&&) const {return *this;} 651}; 652 653namespace { const __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>(); } 654 655template <class _Tp> class reference_wrapper; 656 657template <class _Tp> 658struct ___make_tuple_return 659{ 660 typedef _Tp type; 661}; 662 663template <class _Tp> 664struct ___make_tuple_return<reference_wrapper<_Tp> > 665{ 666 typedef _Tp& type; 667}; 668 669template <class _Tp> 670struct __make_tuple_return 671{ 672 typedef typename ___make_tuple_return<typename decay<_Tp>::type>::type type; 673}; 674 675template <class... _Tp> 676inline _LIBCPP_INLINE_VISIBILITY 677tuple<typename __make_tuple_return<_Tp>::type...> 678make_tuple(_Tp&&... __t) 679{ 680 return tuple<typename __make_tuple_return<_Tp>::type...>(_VSTD::forward<_Tp>(__t)...); 681} 682 683template <class... _Tp> 684inline _LIBCPP_INLINE_VISIBILITY 685tuple<_Tp&&...> 686forward_as_tuple(_Tp&&... __t) 687{ 688 return tuple<_Tp&&...>(_VSTD::forward<_Tp>(__t)...); 689} 690 691template <size_t _Ip> 692struct __tuple_equal 693{ 694 template <class _Tp, class _Up> 695 _LIBCPP_INLINE_VISIBILITY 696 bool operator()(const _Tp& __x, const _Up& __y) 697 { 698 return __tuple_equal<_Ip - 1>()(__x, __y) && get<_Ip-1>(__x) == get<_Ip-1>(__y); 699 } 700}; 701 702template <> 703struct __tuple_equal<0> 704{ 705 template <class _Tp, class _Up> 706 _LIBCPP_INLINE_VISIBILITY 707 bool operator()(const _Tp&, const _Up&) 708 { 709 return true; 710 } 711}; 712 713template <class ..._Tp, class ..._Up> 714inline _LIBCPP_INLINE_VISIBILITY 715bool 716operator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) 717{ 718 return __tuple_equal<sizeof...(_Tp)>()(__x, __y); 719} 720 721template <class ..._Tp, class ..._Up> 722inline _LIBCPP_INLINE_VISIBILITY 723bool 724operator!=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) 725{ 726 return !(__x == __y); 727} 728 729template <size_t _Ip> 730struct __tuple_less 731{ 732 template <class _Tp, class _Up> 733 _LIBCPP_INLINE_VISIBILITY 734 bool operator()(const _Tp& __x, const _Up& __y) 735 { 736 return __tuple_less<_Ip-1>()(__x, __y) || 737 (!__tuple_less<_Ip-1>()(__y, __x) && get<_Ip-1>(__x) < get<_Ip-1>(__y)); 738 } 739}; 740 741template <> 742struct __tuple_less<0> 743{ 744 template <class _Tp, class _Up> 745 _LIBCPP_INLINE_VISIBILITY 746 bool operator()(const _Tp&, const _Up&) 747 { 748 return false; 749 } 750}; 751 752template <class ..._Tp, class ..._Up> 753inline _LIBCPP_INLINE_VISIBILITY 754bool 755operator<(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) 756{ 757 return __tuple_less<sizeof...(_Tp)>()(__x, __y); 758} 759 760template <class ..._Tp, class ..._Up> 761inline _LIBCPP_INLINE_VISIBILITY 762bool 763operator>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) 764{ 765 return __y < __x; 766} 767 768template <class ..._Tp, class ..._Up> 769inline _LIBCPP_INLINE_VISIBILITY 770bool 771operator>=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) 772{ 773 return !(__x < __y); 774} 775 776template <class ..._Tp, class ..._Up> 777inline _LIBCPP_INLINE_VISIBILITY 778bool 779operator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) 780{ 781 return !(__y < __x); 782} 783 784// tuple_cat 785 786template <class _Tp, class _Up> struct __tuple_cat_type; 787 788template <class ..._Ttypes, class ..._Utypes> 789struct __tuple_cat_type<tuple<_Ttypes...>, __tuple_types<_Utypes...> > 790{ 791 typedef tuple<_Ttypes..., _Utypes...> type; 792}; 793 794template <class _ResultTuple, bool _Is_Tuple0TupleLike, class ..._Tuples> 795struct __tuple_cat_return_1 796{ 797}; 798 799template <class ..._Types, class _Tuple0> 800struct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0> 801{ 802 typedef typename __tuple_cat_type<tuple<_Types...>, 803 typename __make_tuple_types<typename remove_reference<_Tuple0>::type>::type>::type 804 type; 805}; 806 807template <class ..._Types, class _Tuple0, class _Tuple1, class ..._Tuples> 808struct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0, _Tuple1, _Tuples...> 809 : public __tuple_cat_return_1< 810 typename __tuple_cat_type< 811 tuple<_Types...>, 812 typename __make_tuple_types<typename remove_reference<_Tuple0>::type>::type 813 >::type, 814 __tuple_like<typename remove_reference<_Tuple1>::type>::value, 815 _Tuple1, _Tuples...> 816{ 817}; 818 819template <class ..._Tuples> struct __tuple_cat_return; 820 821template <class _Tuple0, class ..._Tuples> 822struct __tuple_cat_return<_Tuple0, _Tuples...> 823 : public __tuple_cat_return_1<tuple<>, 824 __tuple_like<typename remove_reference<_Tuple0>::type>::value, _Tuple0, 825 _Tuples...> 826{ 827}; 828 829template <> 830struct __tuple_cat_return<> 831{ 832 typedef tuple<> type; 833}; 834 835inline _LIBCPP_INLINE_VISIBILITY 836tuple<> 837tuple_cat() 838{ 839 return tuple<>(); 840} 841 842template <class _Rp, class _Indices, class _Tuple0, class ..._Tuples> 843struct __tuple_cat_return_ref_imp; 844 845template <class ..._Types, size_t ..._I0, class _Tuple0> 846struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, _Tuple0> 847{ 848 typedef typename remove_reference<_Tuple0>::type _T0; 849 typedef tuple<_Types..., typename __apply_cv<_Tuple0, 850 typename tuple_element<_I0, _T0>::type>::type&&...> type; 851}; 852 853template <class ..._Types, size_t ..._I0, class _Tuple0, class _Tuple1, class ..._Tuples> 854struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, 855 _Tuple0, _Tuple1, _Tuples...> 856 : public __tuple_cat_return_ref_imp< 857 tuple<_Types..., typename __apply_cv<_Tuple0, 858 typename tuple_element<_I0, 859 typename remove_reference<_Tuple0>::type>::type>::type&&...>, 860 typename __make_tuple_indices<tuple_size<typename 861 remove_reference<_Tuple1>::type>::value>::type, 862 _Tuple1, _Tuples...> 863{ 864}; 865 866template <class _Tuple0, class ..._Tuples> 867struct __tuple_cat_return_ref 868 : public __tuple_cat_return_ref_imp<tuple<>, 869 typename __make_tuple_indices< 870 tuple_size<typename remove_reference<_Tuple0>::type>::value 871 >::type, _Tuple0, _Tuples...> 872{ 873}; 874 875template <class _Types, class _I0, class _J0> 876struct __tuple_cat; 877 878template <class ..._Types, size_t ..._I0, size_t ..._J0> 879struct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J0...> > 880{ 881 template <class _Tuple0> 882 _LIBCPP_INLINE_VISIBILITY 883 typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&>::type 884 operator()(tuple<_Types...> __t, _Tuple0&& __t0) 885 { 886 return _VSTD::forward_as_tuple(_VSTD::forward<_Types>(get<_I0>(__t))..., 887 get<_J0>(_VSTD::forward<_Tuple0>(__t0))...); 888 } 889 890 template <class _Tuple0, class _Tuple1, class ..._Tuples> 891 _LIBCPP_INLINE_VISIBILITY 892 typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&, _Tuple1&&, _Tuples&&...>::type 893 operator()(tuple<_Types...> __t, _Tuple0&& __t0, _Tuple1&& __t1, _Tuples&& ...__tpls) 894 { 895 typedef typename remove_reference<_Tuple0>::type _T0; 896 typedef typename remove_reference<_Tuple1>::type _T1; 897 return __tuple_cat< 898 tuple<_Types..., typename __apply_cv<_Tuple0, typename tuple_element<_J0, _T0>::type>::type&&...>, 899 typename __make_tuple_indices<sizeof ...(_Types) + tuple_size<_T0>::value>::type, 900 typename __make_tuple_indices<tuple_size<_T1>::value>::type>() 901 (_VSTD::forward_as_tuple( 902 _VSTD::forward<_Types>(get<_I0>(__t))..., 903 get<_J0>(_VSTD::forward<_Tuple0>(__t0))... 904 ), 905 _VSTD::forward<_Tuple1>(__t1), 906 _VSTD::forward<_Tuples>(__tpls)...); 907 } 908}; 909 910template <class _Tuple0, class... _Tuples> 911inline _LIBCPP_INLINE_VISIBILITY 912typename __tuple_cat_return<_Tuple0, _Tuples...>::type 913tuple_cat(_Tuple0&& __t0, _Tuples&&... __tpls) 914{ 915 typedef typename remove_reference<_Tuple0>::type _T0; 916 return __tuple_cat<tuple<>, __tuple_indices<>, 917 typename __make_tuple_indices<tuple_size<_T0>::value>::type>() 918 (tuple<>(), _VSTD::forward<_Tuple0>(__t0), 919 _VSTD::forward<_Tuples>(__tpls)...); 920} 921 922template <class ..._Tp, class _Alloc> 923struct _LIBCPP_VISIBLE uses_allocator<tuple<_Tp...>, _Alloc> 924 : true_type {}; 925 926template <class _T1, class _T2> 927template <class... _Args1, class... _Args2, size_t ..._I1, size_t ..._I2> 928inline _LIBCPP_INLINE_VISIBILITY 929pair<_T1, _T2>::pair(piecewise_construct_t, 930 tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args, 931 __tuple_indices<_I1...>, __tuple_indices<_I2...>) 932 : first(_VSTD::forward<_Args1>(get<_I1>( __first_args))...), 933 second(_VSTD::forward<_Args2>(get<_I2>(__second_args))...) 934{ 935} 936 937#endif // _LIBCPP_HAS_NO_VARIADICS 938 939_LIBCPP_END_NAMESPACE_STD 940 941#endif // _LIBCPP_TUPLE 942