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