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