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