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