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