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