tuple revision 234959
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 <type_traits> 120#include <__functional_base> 121#include <utility> 122 123#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 124#pragma GCC system_header 125#endif 126 127_LIBCPP_BEGIN_NAMESPACE_STD 128 129// allocator_arg_t 130 131struct _LIBCPP_VISIBLE allocator_arg_t { }; 132 133extern const allocator_arg_t allocator_arg; 134 135// uses_allocator 136 137template <class _Tp> 138struct __has_allocator_type 139{ 140private: 141 struct __two {char _; char __;}; 142 template <class _Up> static __two __test(...); 143 template <class _Up> static char __test(typename _Up::allocator_type* = 0); 144public: 145 static const bool value = sizeof(__test<_Tp>(0)) == 1; 146}; 147 148template <class _Tp, class _Alloc, bool = __has_allocator_type<_Tp>::value> 149struct __uses_allocator 150 : public integral_constant<bool, 151 is_convertible<_Alloc, typename _Tp::allocator_type>::value> 152{ 153}; 154 155template <class _Tp, class _Alloc> 156struct __uses_allocator<_Tp, _Alloc, false> 157 : public false_type 158{ 159}; 160 161template <class _Tp, class _Alloc> 162struct _LIBCPP_VISIBLE uses_allocator 163 : public __uses_allocator<_Tp, _Alloc> 164{ 165}; 166 167#ifndef _LIBCPP_HAS_NO_VARIADICS 168 169// uses-allocator construction 170 171template <class _Tp, class _Alloc, class ..._Args> 172struct __uses_alloc_ctor_imp 173{ 174 static const bool __ua = uses_allocator<_Tp, _Alloc>::value; 175 static const bool __ic = 176 is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value; 177 static const int value = __ua ? 2 - __ic : 0; 178}; 179 180template <class _Tp, class _Alloc, class ..._Args> 181struct __uses_alloc_ctor 182 : integral_constant<int, __uses_alloc_ctor_imp<_Tp, _Alloc, _Args...>::value> 183 {}; 184 185#endif // _LIBCPP_HAS_NO_VARIADICS 186 187#ifndef _LIBCPP_HAS_NO_VARIADICS 188 189// tuple_size 190 191template <class ..._Tp> 192class _LIBCPP_VISIBLE tuple_size<tuple<_Tp...> > 193 : public integral_constant<size_t, sizeof...(_Tp)> 194{ 195}; 196 197// tuple_element 198 199template <size_t _Ip, class ..._Tp> 200class _LIBCPP_VISIBLE tuple_element<_Ip, tuple<_Tp...> > 201{ 202public: 203 typedef typename tuple_element<_Ip, __tuple_types<_Tp...> >::type type; 204}; 205 206// __tuple_leaf 207 208template <size_t _Ip, class _Hp, bool=is_empty<_Hp>::value 209#if __has_feature(is_final) 210 && !__is_final(_Hp) 211#endif 212 > 213class __tuple_leaf; 214 215template <size_t _Ip, class _Hp, bool _Ep> 216inline _LIBCPP_INLINE_VISIBILITY 217void swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y) 218 _NOEXCEPT_(__is_nothrow_swappable<_Hp>::value) 219{ 220 swap(__x.get(), __y.get()); 221} 222 223template <size_t _Ip, class _Hp, bool> 224class __tuple_leaf 225{ 226 _Hp value; 227 228 __tuple_leaf& operator=(const __tuple_leaf&); 229public: 230 _LIBCPP_INLINE_VISIBILITY __tuple_leaf() : value() 231 {static_assert(!is_reference<_Hp>::value, 232 "Attempted to default construct a reference element in a tuple");} 233 234 template <class _Alloc> 235 _LIBCPP_INLINE_VISIBILITY 236 __tuple_leaf(integral_constant<int, 0>, const _Alloc&) 237 : value() 238 {static_assert(!is_reference<_Hp>::value, 239 "Attempted to default construct a reference element in a tuple");} 240 241 template <class _Alloc> 242 _LIBCPP_INLINE_VISIBILITY 243 __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a) 244 : value(allocator_arg_t(), __a) 245 {static_assert(!is_reference<_Hp>::value, 246 "Attempted to default construct a reference element in a tuple");} 247 248 template <class _Alloc> 249 _LIBCPP_INLINE_VISIBILITY 250 __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a) 251 : value(__a) 252 {static_assert(!is_reference<_Hp>::value, 253 "Attempted to default construct a reference element in a tuple");} 254 255 template <class _Tp, 256 class = typename enable_if<is_constructible<_Hp, _Tp>::value>::type> 257 _LIBCPP_INLINE_VISIBILITY 258 explicit __tuple_leaf(_Tp&& __t) 259 : value(_VSTD::forward<_Tp>(__t)) 260 {static_assert(!is_reference<_Hp>::value || 261 (is_lvalue_reference<_Hp>::value && 262 (is_lvalue_reference<_Tp>::value || 263 is_same<typename remove_reference<_Tp>::type, 264 reference_wrapper< 265 typename remove_reference<_Hp>::type 266 > 267 >::value)) || 268 (is_rvalue_reference<_Hp>::value && 269 !is_lvalue_reference<_Tp>::value), 270 "Attempted to construct a reference element in a tuple with an rvalue");} 271 272 template <class _Tp, class _Alloc> 273 _LIBCPP_INLINE_VISIBILITY 274 explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t) 275 : value(_VSTD::forward<_Tp>(__t)) 276 {static_assert(!is_lvalue_reference<_Hp>::value || 277 (is_lvalue_reference<_Hp>::value && 278 (is_lvalue_reference<_Tp>::value || 279 is_same<typename remove_reference<_Tp>::type, 280 reference_wrapper< 281 typename remove_reference<_Hp>::type 282 > 283 >::value)), 284 "Attempted to construct a reference element in a tuple with an rvalue");} 285 286 template <class _Tp, class _Alloc> 287 _LIBCPP_INLINE_VISIBILITY 288 explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t) 289 : value(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) 290 {static_assert(!is_lvalue_reference<_Hp>::value || 291 (is_lvalue_reference<_Hp>::value && 292 (is_lvalue_reference<_Tp>::value || 293 is_same<typename remove_reference<_Tp>::type, 294 reference_wrapper< 295 typename remove_reference<_Hp>::type 296 > 297 >::value)), 298 "Attempted to construct a reference element in a tuple with an rvalue");} 299 300 template <class _Tp, class _Alloc> 301 _LIBCPP_INLINE_VISIBILITY 302 explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t) 303 : value(_VSTD::forward<_Tp>(__t), __a) 304 {static_assert(!is_lvalue_reference<_Hp>::value || 305 (is_lvalue_reference<_Hp>::value && 306 (is_lvalue_reference<_Tp>::value || 307 is_same<typename remove_reference<_Tp>::type, 308 reference_wrapper< 309 typename remove_reference<_Hp>::type 310 > 311 >::value)), 312 "Attempted to construct a reference element in a tuple with an rvalue");} 313 314 __tuple_leaf(const __tuple_leaf& __t) 315 : value(__t.get()) 316 {static_assert(!is_rvalue_reference<_Hp>::value, "Can not copy a tuple with rvalue reference member");} 317 318 template <class _Tp> 319 _LIBCPP_INLINE_VISIBILITY 320 explicit __tuple_leaf(const __tuple_leaf<_Ip, _Tp>& __t) 321 : value(__t.get()) {} 322 323 template <class _Tp> 324 _LIBCPP_INLINE_VISIBILITY 325 __tuple_leaf& 326 operator=(_Tp&& __t) 327 { 328 value = _VSTD::forward<_Tp>(__t); 329 return *this; 330 } 331 332 _LIBCPP_INLINE_VISIBILITY 333 int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value) 334 { 335 _VSTD::swap(*this, __t); 336 return 0; 337 } 338 339 _LIBCPP_INLINE_VISIBILITY _Hp& get() {return value;} 340 _LIBCPP_INLINE_VISIBILITY const _Hp& get() const {return value;} 341}; 342 343template <size_t _Ip, class _Hp> 344class __tuple_leaf<_Ip, _Hp, true> 345 : private _Hp 346{ 347 348 __tuple_leaf& operator=(const __tuple_leaf&); 349public: 350 _LIBCPP_INLINE_VISIBILITY __tuple_leaf() {} 351 352 template <class _Alloc> 353 _LIBCPP_INLINE_VISIBILITY 354 __tuple_leaf(integral_constant<int, 0>, const _Alloc&) {} 355 356 template <class _Alloc> 357 _LIBCPP_INLINE_VISIBILITY 358 __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a) 359 : _Hp(allocator_arg_t(), __a) {} 360 361 template <class _Alloc> 362 _LIBCPP_INLINE_VISIBILITY 363 __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a) 364 : _Hp(__a) {} 365 366 template <class _Tp, 367 class = typename enable_if<is_constructible<_Hp, _Tp>::value>::type> 368 _LIBCPP_INLINE_VISIBILITY 369 explicit __tuple_leaf(_Tp&& __t) 370 : _Hp(_VSTD::forward<_Tp>(__t)) {} 371 372 template <class _Tp, class _Alloc> 373 _LIBCPP_INLINE_VISIBILITY 374 explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t) 375 : _Hp(_VSTD::forward<_Tp>(__t)) {} 376 377 template <class _Tp, class _Alloc> 378 _LIBCPP_INLINE_VISIBILITY 379 explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t) 380 : _Hp(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) {} 381 382 template <class _Tp, class _Alloc> 383 _LIBCPP_INLINE_VISIBILITY 384 explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t) 385 : _Hp(_VSTD::forward<_Tp>(__t), __a) {} 386 387 template <class _Tp> 388 _LIBCPP_INLINE_VISIBILITY 389 explicit __tuple_leaf(const __tuple_leaf<_Ip, _Tp>& __t) 390 : _Hp(__t.get()) {} 391 392 template <class _Tp> 393 _LIBCPP_INLINE_VISIBILITY 394 __tuple_leaf& 395 operator=(_Tp&& __t) 396 { 397 _Hp::operator=(_VSTD::forward<_Tp>(__t)); 398 return *this; 399 } 400 401 _LIBCPP_INLINE_VISIBILITY 402 int 403 swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value) 404 { 405 _VSTD::swap(*this, __t); 406 return 0; 407 } 408 409 _LIBCPP_INLINE_VISIBILITY _Hp& get() {return static_cast<_Hp&>(*this);} 410 _LIBCPP_INLINE_VISIBILITY const _Hp& get() const {return static_cast<const _Hp&>(*this);} 411}; 412 413template <class ..._Tp> 414_LIBCPP_INLINE_VISIBILITY 415void __swallow(_Tp&&...) {} 416 417template <bool ...> struct __all; 418 419template <> 420struct __all<> 421{ 422 static const bool value = true; 423}; 424 425template <bool _B0, bool ... _Bp> 426struct __all<_B0, _Bp...> 427{ 428 static const bool value = _B0 && __all<_Bp...>::value; 429}; 430 431// __tuple_impl 432 433template<class _Indx, class ..._Tp> struct __tuple_impl; 434 435template<size_t ..._Indx, class ..._Tp> 436struct __tuple_impl<__tuple_indices<_Indx...>, _Tp...> 437 : public __tuple_leaf<_Indx, _Tp>... 438{ 439 template <size_t ..._Uf, class ..._Tf, 440 size_t ..._Ul, class ..._Tl, class ..._Up> 441 _LIBCPP_INLINE_VISIBILITY 442 explicit 443 __tuple_impl(__tuple_indices<_Uf...>, __tuple_types<_Tf...>, 444 __tuple_indices<_Ul...>, __tuple_types<_Tl...>, 445 _Up&&... __u) : 446 __tuple_leaf<_Uf, _Tf>(_VSTD::forward<_Up>(__u))..., 447 __tuple_leaf<_Ul, _Tl>()... 448 {} 449 450 template <class _Alloc, size_t ..._Uf, class ..._Tf, 451 size_t ..._Ul, class ..._Tl, class ..._Up> 452 _LIBCPP_INLINE_VISIBILITY 453 explicit 454 __tuple_impl(allocator_arg_t, const _Alloc& __a, 455 __tuple_indices<_Uf...>, __tuple_types<_Tf...>, 456 __tuple_indices<_Ul...>, __tuple_types<_Tl...>, 457 _Up&&... __u) : 458 __tuple_leaf<_Uf, _Tf>(__uses_alloc_ctor<_Tf, _Alloc, _Up>(), __a, 459 _VSTD::forward<_Up>(__u))..., 460 __tuple_leaf<_Ul, _Tl>(__uses_alloc_ctor<_Tl, _Alloc>(), __a)... 461 {} 462 463 template <class _Tuple, 464 class = typename enable_if 465 < 466 __tuple_convertible<_Tuple, tuple<_Tp...> >::value 467 >::type 468 > 469 _LIBCPP_INLINE_VISIBILITY 470 __tuple_impl(_Tuple&& __t) 471 : __tuple_leaf<_Indx, _Tp>(_VSTD::forward<typename tuple_element<_Indx, 472 typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))... 473 {} 474 475 template <class _Alloc, class _Tuple, 476 class = typename enable_if 477 < 478 __tuple_convertible<_Tuple, tuple<_Tp...> >::value 479 >::type 480 > 481 _LIBCPP_INLINE_VISIBILITY 482 __tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t) 483 : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, typename tuple_element<_Indx, 484 typename __make_tuple_types<_Tuple>::type>::type>(), __a, 485 _VSTD::forward<typename tuple_element<_Indx, 486 typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))... 487 {} 488 489 template <class _Tuple> 490 _LIBCPP_INLINE_VISIBILITY 491 typename enable_if 492 < 493 __tuple_assignable<_Tuple, tuple<_Tp...> >::value, 494 __tuple_impl& 495 >::type 496 operator=(_Tuple&& __t) 497 { 498 __swallow(__tuple_leaf<_Indx, _Tp>::operator=(_VSTD::forward<typename tuple_element<_Indx, 499 typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...); 500 return *this; 501 } 502 503 _LIBCPP_INLINE_VISIBILITY 504 __tuple_impl& 505 operator=(const __tuple_impl& __t) 506 { 507 __swallow(__tuple_leaf<_Indx, _Tp>::operator=(static_cast<const __tuple_leaf<_Indx, _Tp>&>(__t).get())...); 508 return *this; 509 } 510 511 _LIBCPP_INLINE_VISIBILITY 512 void swap(__tuple_impl& __t) 513 _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value) 514 { 515 __swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...); 516 } 517}; 518 519template <class ..._Tp> 520class _LIBCPP_VISIBLE tuple 521{ 522 typedef __tuple_impl<typename __make_tuple_indices<sizeof...(_Tp)>::type, _Tp...> base; 523 524 base base_; 525 526 template <size_t _Jp, class ..._Up> friend 527 typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT; 528 template <size_t _Jp, class ..._Up> friend 529 const typename tuple_element<_Jp, tuple<_Up...> >::type& get(const tuple<_Up...>&) _NOEXCEPT; 530 template <size_t _Jp, class ..._Up> friend 531 typename tuple_element<_Jp, tuple<_Up...> >::type&& get(tuple<_Up...>&&) _NOEXCEPT; 532public: 533 534 _LIBCPP_INLINE_VISIBILITY 535 explicit tuple(const _Tp& ... __t) 536 : base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(), 537 typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(), 538 typename __make_tuple_indices<0>::type(), 539 typename __make_tuple_types<tuple, 0>::type(), 540 __t... 541 ) {} 542 543 template <class _Alloc> 544 _LIBCPP_INLINE_VISIBILITY 545 tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t) 546 : base_(allocator_arg_t(), __a, 547 typename __make_tuple_indices<sizeof...(_Tp)>::type(), 548 typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(), 549 typename __make_tuple_indices<0>::type(), 550 typename __make_tuple_types<tuple, 0>::type(), 551 __t... 552 ) {} 553 554 template <class ..._Up, 555 typename enable_if 556 < 557 sizeof...(_Up) <= sizeof...(_Tp) && 558 __tuple_convertible 559 < 560 tuple<_Up...>, 561 typename __make_tuple_types<tuple, 562 sizeof...(_Up) < sizeof...(_Tp) ? 563 sizeof...(_Up) : 564 sizeof...(_Tp)>::type 565 >::value, 566 bool 567 >::type = false 568 > 569 _LIBCPP_INLINE_VISIBILITY 570 tuple(_Up&&... __u) 571 : base_(typename __make_tuple_indices<sizeof...(_Up)>::type(), 572 typename __make_tuple_types<tuple, sizeof...(_Up)>::type(), 573 typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(), 574 typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(), 575 _VSTD::forward<_Up>(__u)...) {} 576 577 template <class ..._Up, 578 typename enable_if 579 < 580 sizeof...(_Up) <= sizeof...(_Tp) && 581 __tuple_constructible 582 < 583 tuple<_Up...>, 584 typename __make_tuple_types<tuple, 585 sizeof...(_Up) < sizeof...(_Tp) ? 586 sizeof...(_Up) : 587 sizeof...(_Tp)>::type 588 >::value && 589 !__tuple_convertible 590 < 591 tuple<_Up...>, 592 typename __make_tuple_types<tuple, 593 sizeof...(_Up) < sizeof...(_Tp) ? 594 sizeof...(_Up) : 595 sizeof...(_Tp)>::type 596 >::value, 597 bool 598 >::type =false 599 > 600 _LIBCPP_INLINE_VISIBILITY 601 explicit 602 tuple(_Up&&... __u) 603 : base_(typename __make_tuple_indices<sizeof...(_Up)>::type(), 604 typename __make_tuple_types<tuple, sizeof...(_Up)>::type(), 605 typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(), 606 typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(), 607 _VSTD::forward<_Up>(__u)...) {} 608 609 template <class _Alloc, class ..._Up, 610 class = typename enable_if 611 < 612 sizeof...(_Up) <= sizeof...(_Tp) && 613 __tuple_convertible 614 < 615 tuple<_Up...>, 616 typename __make_tuple_types<tuple, 617 sizeof...(_Up) < sizeof...(_Tp) ? 618 sizeof...(_Up) : 619 sizeof...(_Tp)>::type 620 >::value 621 >::type 622 > 623 _LIBCPP_INLINE_VISIBILITY 624 tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u) 625 : base_(allocator_arg_t(), __a, 626 typename __make_tuple_indices<sizeof...(_Up)>::type(), 627 typename __make_tuple_types<tuple, sizeof...(_Up)>::type(), 628 typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(), 629 typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(), 630 _VSTD::forward<_Up>(__u)...) {} 631 632 template <class _Tuple, 633 typename enable_if 634 < 635 __tuple_convertible<_Tuple, tuple>::value, 636 bool 637 >::type = false 638 > 639 _LIBCPP_INLINE_VISIBILITY 640 tuple(_Tuple&& __t) 641 : base_(_VSTD::forward<_Tuple>(__t)) {} 642 643 template <class _Tuple, 644 typename enable_if 645 < 646 __tuple_constructible<_Tuple, tuple>::value && 647 !__tuple_convertible<_Tuple, tuple>::value, 648 bool 649 >::type = false 650 > 651 _LIBCPP_INLINE_VISIBILITY 652 explicit 653 tuple(_Tuple&& __t) 654 : base_(_VSTD::forward<_Tuple>(__t)) {} 655 656 template <class _Alloc, class _Tuple, 657 class = typename enable_if 658 < 659 __tuple_convertible<_Tuple, tuple>::value 660 >::type 661 > 662 _LIBCPP_INLINE_VISIBILITY 663 tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t) 664 : base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {} 665 666 template <class _Tuple, 667 class = typename enable_if 668 < 669 __tuple_assignable<_Tuple, tuple>::value 670 >::type 671 > 672 _LIBCPP_INLINE_VISIBILITY 673 tuple& 674 operator=(_Tuple&& __t) 675 { 676 base_.operator=(_VSTD::forward<_Tuple>(__t)); 677 return *this; 678 } 679 680 _LIBCPP_INLINE_VISIBILITY 681 void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value) 682 {base_.swap(__t.base_);} 683}; 684 685template <> 686class _LIBCPP_VISIBLE tuple<> 687{ 688public: 689 _LIBCPP_INLINE_VISIBILITY 690 tuple() {} 691 template <class _Alloc> 692 _LIBCPP_INLINE_VISIBILITY 693 tuple(allocator_arg_t, const _Alloc&) {} 694 template <class _Alloc> 695 _LIBCPP_INLINE_VISIBILITY 696 tuple(allocator_arg_t, const _Alloc&, const tuple&) {} 697 template <class _Up> 698 _LIBCPP_INLINE_VISIBILITY 699 tuple(array<_Up, 0>) {} 700 template <class _Alloc, class _Up> 701 _LIBCPP_INLINE_VISIBILITY 702 tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) {} 703 _LIBCPP_INLINE_VISIBILITY 704 void swap(tuple&) _NOEXCEPT {} 705}; 706 707template <class ..._Tp> 708inline _LIBCPP_INLINE_VISIBILITY 709typename enable_if 710< 711 __all<__is_swappable<_Tp>::value...>::value, 712 void 713>::type 714swap(tuple<_Tp...>& __t, tuple<_Tp...>& __u) 715 _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value) 716 {__t.swap(__u);} 717 718// get 719 720template <size_t _Ip, class ..._Tp> 721inline _LIBCPP_INLINE_VISIBILITY 722typename tuple_element<_Ip, tuple<_Tp...> >::type& 723get(tuple<_Tp...>& __t) _NOEXCEPT 724{ 725 typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type; 726 return static_cast<__tuple_leaf<_Ip, type>&>(__t.base_).get(); 727} 728 729template <size_t _Ip, class ..._Tp> 730inline _LIBCPP_INLINE_VISIBILITY 731const typename tuple_element<_Ip, tuple<_Tp...> >::type& 732get(const tuple<_Tp...>& __t) _NOEXCEPT 733{ 734 typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type; 735 return static_cast<const __tuple_leaf<_Ip, type>&>(__t.base_).get(); 736} 737 738template <size_t _Ip, class ..._Tp> 739inline _LIBCPP_INLINE_VISIBILITY 740typename tuple_element<_Ip, tuple<_Tp...> >::type&& 741get(tuple<_Tp...>&& __t) _NOEXCEPT 742{ 743 typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type; 744 return static_cast<type&&>( 745 static_cast<__tuple_leaf<_Ip, type>&&>(__t.base_).get()); 746} 747 748// tie 749 750template <class ..._Tp> 751inline _LIBCPP_INLINE_VISIBILITY 752tuple<_Tp&...> 753tie(_Tp&... __t) 754{ 755 return tuple<_Tp&...>(__t...); 756} 757 758template <class _Up> 759struct __ignore_t 760{ 761 template <class _Tp> 762 _LIBCPP_INLINE_VISIBILITY 763 const __ignore_t& operator=(_Tp&&) const {return *this;} 764}; 765 766namespace { const __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>(); } 767 768template <class _Tp> class reference_wrapper; 769 770template <class _Tp> 771struct ___make_tuple_return 772{ 773 typedef _Tp type; 774}; 775 776template <class _Tp> 777struct ___make_tuple_return<reference_wrapper<_Tp> > 778{ 779 typedef _Tp& type; 780}; 781 782template <class _Tp> 783struct __make_tuple_return 784{ 785 typedef typename ___make_tuple_return<typename decay<_Tp>::type>::type type; 786}; 787 788template <class... _Tp> 789inline _LIBCPP_INLINE_VISIBILITY 790tuple<typename __make_tuple_return<_Tp>::type...> 791make_tuple(_Tp&&... __t) 792{ 793 return tuple<typename __make_tuple_return<_Tp>::type...>(_VSTD::forward<_Tp>(__t)...); 794} 795 796template <class... _Tp> 797inline _LIBCPP_INLINE_VISIBILITY 798tuple<_Tp&&...> 799forward_as_tuple(_Tp&&... __t) 800{ 801 return tuple<_Tp&&...>(_VSTD::forward<_Tp>(__t)...); 802} 803 804template <size_t _Ip> 805struct __tuple_equal 806{ 807 template <class _Tp, class _Up> 808 _LIBCPP_INLINE_VISIBILITY 809 bool operator()(const _Tp& __x, const _Up& __y) 810 { 811 return __tuple_equal<_Ip - 1>()(__x, __y) && get<_Ip-1>(__x) == get<_Ip-1>(__y); 812 } 813}; 814 815template <> 816struct __tuple_equal<0> 817{ 818 template <class _Tp, class _Up> 819 _LIBCPP_INLINE_VISIBILITY 820 bool operator()(const _Tp&, const _Up&) 821 { 822 return true; 823 } 824}; 825 826template <class ..._Tp, class ..._Up> 827inline _LIBCPP_INLINE_VISIBILITY 828bool 829operator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) 830{ 831 return __tuple_equal<sizeof...(_Tp)>()(__x, __y); 832} 833 834template <class ..._Tp, class ..._Up> 835inline _LIBCPP_INLINE_VISIBILITY 836bool 837operator!=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) 838{ 839 return !(__x == __y); 840} 841 842template <size_t _Ip> 843struct __tuple_less 844{ 845 template <class _Tp, class _Up> 846 _LIBCPP_INLINE_VISIBILITY 847 bool operator()(const _Tp& __x, const _Up& __y) 848 { 849 return __tuple_less<_Ip-1>()(__x, __y) || 850 (!__tuple_less<_Ip-1>()(__y, __x) && get<_Ip-1>(__x) < get<_Ip-1>(__y)); 851 } 852}; 853 854template <> 855struct __tuple_less<0> 856{ 857 template <class _Tp, class _Up> 858 _LIBCPP_INLINE_VISIBILITY 859 bool operator()(const _Tp&, const _Up&) 860 { 861 return false; 862 } 863}; 864 865template <class ..._Tp, class ..._Up> 866inline _LIBCPP_INLINE_VISIBILITY 867bool 868operator<(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) 869{ 870 return __tuple_less<sizeof...(_Tp)>()(__x, __y); 871} 872 873template <class ..._Tp, class ..._Up> 874inline _LIBCPP_INLINE_VISIBILITY 875bool 876operator>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) 877{ 878 return __y < __x; 879} 880 881template <class ..._Tp, class ..._Up> 882inline _LIBCPP_INLINE_VISIBILITY 883bool 884operator>=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) 885{ 886 return !(__x < __y); 887} 888 889template <class ..._Tp, class ..._Up> 890inline _LIBCPP_INLINE_VISIBILITY 891bool 892operator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y) 893{ 894 return !(__y < __x); 895} 896 897// tuple_cat 898 899template <class _Tp, class _Up> struct __tuple_cat_type; 900 901template <class ..._Ttypes, class ..._Utypes> 902struct __tuple_cat_type<tuple<_Ttypes...>, __tuple_types<_Utypes...> > 903{ 904 typedef tuple<_Ttypes..., _Utypes...> type; 905}; 906 907template <class _ResultTuple, bool _Is_Tuple0TupleLike, class ..._Tuples> 908struct __tuple_cat_return_1 909{ 910}; 911 912template <class ..._Types, class _Tuple0> 913struct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0> 914{ 915 typedef typename __tuple_cat_type<tuple<_Types...>, 916 typename __make_tuple_types<typename remove_reference<_Tuple0>::type>::type>::type 917 type; 918}; 919 920template <class ..._Types, class _Tuple0, class _Tuple1, class ..._Tuples> 921struct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0, _Tuple1, _Tuples...> 922 : public __tuple_cat_return_1< 923 typename __tuple_cat_type< 924 tuple<_Types...>, 925 typename __make_tuple_types<typename remove_reference<_Tuple0>::type>::type 926 >::type, 927 __tuple_like<typename remove_reference<_Tuple1>::type>::value, 928 _Tuple1, _Tuples...> 929{ 930}; 931 932template <class ..._Tuples> struct __tuple_cat_return; 933 934template <class _Tuple0, class ..._Tuples> 935struct __tuple_cat_return<_Tuple0, _Tuples...> 936 : public __tuple_cat_return_1<tuple<>, 937 __tuple_like<typename remove_reference<_Tuple0>::type>::value, _Tuple0, 938 _Tuples...> 939{ 940}; 941 942template <> 943struct __tuple_cat_return<> 944{ 945 typedef tuple<> type; 946}; 947 948inline _LIBCPP_INLINE_VISIBILITY 949tuple<> 950tuple_cat() 951{ 952 return tuple<>(); 953} 954 955template <class _Rp, class _Indices, class _Tuple0, class ..._Tuples> 956struct __tuple_cat_return_ref_imp; 957 958template <class ..._Types, size_t ..._I0, class _Tuple0> 959struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, _Tuple0> 960{ 961 typedef typename remove_reference<_Tuple0>::type _T0; 962 typedef tuple<_Types..., typename __apply_cv<_Tuple0, 963 typename tuple_element<_I0, _T0>::type>::type&&...> type; 964}; 965 966template <class ..._Types, size_t ..._I0, class _Tuple0, class _Tuple1, class ..._Tuples> 967struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, 968 _Tuple0, _Tuple1, _Tuples...> 969 : public __tuple_cat_return_ref_imp< 970 tuple<_Types..., typename __apply_cv<_Tuple0, 971 typename tuple_element<_I0, 972 typename remove_reference<_Tuple0>::type>::type>::type&&...>, 973 typename __make_tuple_indices<tuple_size<typename 974 remove_reference<_Tuple1>::type>::value>::type, 975 _Tuple1, _Tuples...> 976{ 977}; 978 979template <class _Tuple0, class ..._Tuples> 980struct __tuple_cat_return_ref 981 : public __tuple_cat_return_ref_imp<tuple<>, 982 typename __make_tuple_indices< 983 tuple_size<typename remove_reference<_Tuple0>::type>::value 984 >::type, _Tuple0, _Tuples...> 985{ 986}; 987 988template <class _Types, class _I0, class _J0> 989struct __tuple_cat; 990 991template <class ..._Types, size_t ..._I0, size_t ..._J0> 992struct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J0...> > 993{ 994 template <class _Tuple0> 995 _LIBCPP_INLINE_VISIBILITY 996 typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&>::type 997 operator()(tuple<_Types...> __t, _Tuple0&& __t0) 998 { 999 return _VSTD::forward_as_tuple(_VSTD::forward<_Types>(get<_I0>(__t))..., 1000 get<_J0>(_VSTD::forward<_Tuple0>(__t0))...); 1001 } 1002 1003 template <class _Tuple0, class _Tuple1, class ..._Tuples> 1004 _LIBCPP_INLINE_VISIBILITY 1005 typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&, _Tuple1&&, _Tuples&&...>::type 1006 operator()(tuple<_Types...> __t, _Tuple0&& __t0, _Tuple1&& __t1, _Tuples&& ...__tpls) 1007 { 1008 typedef typename remove_reference<_Tuple0>::type _T0; 1009 typedef typename remove_reference<_Tuple1>::type _T1; 1010 return __tuple_cat< 1011 tuple<_Types..., typename __apply_cv<_Tuple0, typename tuple_element<_J0, _T0>::type>::type&&...>, 1012 typename __make_tuple_indices<sizeof ...(_Types) + tuple_size<_T0>::value>::type, 1013 typename __make_tuple_indices<tuple_size<_T1>::value>::type>() 1014 (_VSTD::forward_as_tuple( 1015 _VSTD::forward<_Types>(get<_I0>(__t))..., 1016 get<_J0>(_VSTD::forward<_Tuple0>(__t0))... 1017 ), 1018 _VSTD::forward<_Tuple1>(__t1), 1019 _VSTD::forward<_Tuples>(__tpls)...); 1020 } 1021}; 1022 1023template <class _Tuple0, class... _Tuples> 1024inline _LIBCPP_INLINE_VISIBILITY 1025typename __tuple_cat_return<_Tuple0, _Tuples...>::type 1026tuple_cat(_Tuple0&& __t0, _Tuples&&... __tpls) 1027{ 1028 typedef typename remove_reference<_Tuple0>::type _T0; 1029 return __tuple_cat<tuple<>, __tuple_indices<>, 1030 typename __make_tuple_indices<tuple_size<_T0>::value>::type>() 1031 (tuple<>(), _VSTD::forward<_Tuple0>(__t0), 1032 _VSTD::forward<_Tuples>(__tpls)...); 1033} 1034 1035template <class ..._Tp, class _Alloc> 1036struct _LIBCPP_VISIBLE uses_allocator<tuple<_Tp...>, _Alloc> 1037 : true_type {}; 1038 1039template <class _T1, class _T2> 1040template <class... _Args1, class... _Args2, size_t ..._I1, size_t ..._I2> 1041inline _LIBCPP_INLINE_VISIBILITY 1042pair<_T1, _T2>::pair(piecewise_construct_t, 1043 tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args, 1044 __tuple_indices<_I1...>, __tuple_indices<_I2...>) 1045 : first(_VSTD::forward<_Args1>(get<_I1>( __first_args))...), 1046 second(_VSTD::forward<_Args2>(get<_I2>(__second_args))...) 1047{ 1048} 1049 1050#endif // _LIBCPP_HAS_NO_VARIADICS 1051 1052_LIBCPP_END_NAMESPACE_STD 1053 1054#endif // _LIBCPP_TUPLE 1055