tuple revision 234959
1// -*- C++ -*-
2//===--------------------------- tuple ------------------------------------===//
3//
4//                     The LLVM Compiler Infrastructure
5//
6// This file is distributed under the University of Illinois Open Source
7// License. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_TUPLE
12#define _LIBCPP_TUPLE
13
14/*
15    tuple synopsis
16
17namespace std
18{
19
20template <class... T>
21class tuple {
22public:
23    constexpr tuple();
24    explicit tuple(const T&...);
25    template <class... U>
26        explicit tuple(U&&...);
27    tuple(const tuple&) = default;
28    tuple(tuple&&) = default;
29    template <class... U>
30        tuple(const tuple<U...>&);
31    template <class... U>
32        tuple(tuple<U...>&&);
33    template <class U1, class U2>
34        tuple(const pair<U1, U2>&); // iff sizeof...(T) == 2
35    template <class U1, class U2>
36        tuple(pair<U1, U2>&&); // iff sizeof...(T) == 2
37
38    // allocator-extended constructors
39    template <class Alloc>
40        tuple(allocator_arg_t, const Alloc& a);
41    template <class Alloc>
42        tuple(allocator_arg_t, const Alloc& a, const T&...);
43    template <class Alloc, class... U>
44        tuple(allocator_arg_t, const Alloc& a, U&&...);
45    template <class Alloc>
46        tuple(allocator_arg_t, const Alloc& a, const tuple&);
47    template <class Alloc>
48        tuple(allocator_arg_t, const Alloc& a, tuple&&);
49    template <class Alloc, class... U>
50        tuple(allocator_arg_t, const Alloc& a, const tuple<U...>&);
51    template <class Alloc, class... U>
52        tuple(allocator_arg_t, const Alloc& a, tuple<U...>&&);
53    template <class Alloc, class U1, class U2>
54        tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&);
55    template <class Alloc, class U1, class U2>
56        tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&);
57
58    tuple& operator=(const tuple&);
59    tuple&
60        operator=(tuple&&) noexcept(AND(is_nothrow_move_assignable<T>::value ...));
61    template <class... U>
62        tuple& operator=(const tuple<U...>&);
63    template <class... U>
64        tuple& operator=(tuple<U...>&&);
65    template <class U1, class U2>
66        tuple& operator=(const pair<U1, U2>&); // iff sizeof...(T) == 2
67    template <class U1, class U2>
68        tuple& operator=(pair<U1, U2>&&); //iffsizeof...(T) == 2
69
70    void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...));
71};
72
73const unspecified ignore;
74
75template <class... T> tuple<V...>  make_tuple(T&&...);
76template <class... T> tuple<ATypes...> forward_as_tuple(T&&...) noexcept;
77template <class... T> tuple<T&...> tie(T&...) noexcept;
78template <class... Tuples> tuple<CTypes...> tuple_cat(Tuples&&... tpls);
79  
80// 20.4.1.4, tuple helper classes:
81template <class T> class tuple_size; // undefined
82template <class... T> class tuple_size<tuple<T...>>;
83template <intsize_t I, class T> class tuple_element; // undefined
84template <intsize_t I, class... T> class tuple_element<I, tuple<T...>>;
85
86// 20.4.1.5, element access:
87template <intsize_t I, class... T>
88    typename tuple_element<I, tuple<T...>>::type&
89    get(tuple<T...>&) noexcept;
90template <intsize_t I, class... T>
91    typename tuple_element<I, tuple<T...>>::type const&
92    get(const tuple<T...>&) noexcept;
93template <intsize_t I, class... T>
94    typename tuple_element<I, tuple<T...>>::type&&
95    get(tuple<T...>&&) noexcept;
96
97// 20.4.1.6, relational operators:
98template<class... T, class... U> bool operator==(const tuple<T...>&, const tuple<U...>&);
99template<class... T, class... U> bool operator<(const tuple<T...>&, const tuple<U...>&);
100template<class... T, class... U> bool operator!=(const tuple<T...>&, const tuple<U...>&);
101template<class... T, class... U> bool operator>(const tuple<T...>&, const tuple<U...>&);
102template<class... T, class... U> bool operator<=(const tuple<T...>&, const tuple<U...>&);
103template<class... T, class... U> bool operator>=(const tuple<T...>&, const tuple<U...>&);
104
105template <class... Types, class Alloc>
106  struct uses_allocator<tuple<Types...>, Alloc>;
107
108template <class... Types>
109  void
110  swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(noexcept(x.swap(y)));
111
112}  // std
113
114*/
115
116#include <__config>
117#include <__tuple>
118#include <cstddef>
119#include <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
131struct _LIBCPP_VISIBLE allocator_arg_t { };
132
133extern const allocator_arg_t allocator_arg;
134
135// uses_allocator
136
137template <class _Tp>
138struct __has_allocator_type
139{
140private:
141    struct __two {char _; char __;};
142    template <class _Up> static __two __test(...);
143    template <class _Up> static char __test(typename _Up::allocator_type* = 0);
144public:
145    static const bool value = sizeof(__test<_Tp>(0)) == 1;
146};
147
148template <class _Tp, class _Alloc, bool = __has_allocator_type<_Tp>::value>
149struct __uses_allocator
150    : public integral_constant<bool,
151        is_convertible<_Alloc, typename _Tp::allocator_type>::value>
152{
153};
154
155template <class _Tp, class _Alloc>
156struct __uses_allocator<_Tp, _Alloc, false>
157    : public false_type
158{
159};
160
161template <class _Tp, class _Alloc>
162struct _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
171template <class _Tp, class _Alloc, class ..._Args>
172struct __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
180template <class _Tp, class _Alloc, class ..._Args>
181struct __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
191template <class ..._Tp>
192class _LIBCPP_VISIBLE tuple_size<tuple<_Tp...> >
193    : public integral_constant<size_t, sizeof...(_Tp)>
194{
195};
196
197// tuple_element
198
199template <size_t _Ip, class ..._Tp>
200class _LIBCPP_VISIBLE tuple_element<_Ip, tuple<_Tp...> >
201{
202public:
203    typedef typename tuple_element<_Ip, __tuple_types<_Tp...> >::type type;
204};
205
206// __tuple_leaf
207
208template <size_t _Ip, class _Hp, bool=is_empty<_Hp>::value
209#if __has_feature(is_final)
210                                 && !__is_final(_Hp)
211#endif
212         >
213class __tuple_leaf;
214
215template <size_t _Ip, class _Hp, bool _Ep>
216inline _LIBCPP_INLINE_VISIBILITY
217void 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
223template <size_t _Ip, class _Hp, bool>
224class __tuple_leaf
225{
226    _Hp value;
227
228    __tuple_leaf& operator=(const __tuple_leaf&);
229public:
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
343template <size_t _Ip, class _Hp>
344class __tuple_leaf<_Ip, _Hp, true>
345    : private _Hp
346{
347
348    __tuple_leaf& operator=(const __tuple_leaf&);
349public:
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
413template <class ..._Tp>
414_LIBCPP_INLINE_VISIBILITY
415void __swallow(_Tp&&...) {}
416
417template <bool ...> struct __all;
418
419template <>
420struct __all<>
421{
422    static const bool value = true;
423};
424
425template <bool _B0, bool ... _Bp>
426struct __all<_B0, _Bp...>
427{
428    static const bool value = _B0 && __all<_Bp...>::value;
429};
430
431// __tuple_impl
432
433template<class _Indx, class ..._Tp> struct __tuple_impl;
434
435template<size_t ..._Indx, class ..._Tp>
436struct __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
519template <class ..._Tp>
520class _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;
532public:
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
685template <>
686class _LIBCPP_VISIBLE tuple<>
687{
688public:
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
707template <class ..._Tp>
708inline _LIBCPP_INLINE_VISIBILITY
709typename enable_if
710<
711    __all<__is_swappable<_Tp>::value...>::value,
712    void
713>::type
714swap(tuple<_Tp...>& __t, tuple<_Tp...>& __u)
715                 _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
716    {__t.swap(__u);}
717
718// get
719
720template <size_t _Ip, class ..._Tp>
721inline _LIBCPP_INLINE_VISIBILITY
722typename tuple_element<_Ip, tuple<_Tp...> >::type&
723get(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
729template <size_t _Ip, class ..._Tp>
730inline _LIBCPP_INLINE_VISIBILITY
731const typename tuple_element<_Ip, tuple<_Tp...> >::type&
732get(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
738template <size_t _Ip, class ..._Tp>
739inline _LIBCPP_INLINE_VISIBILITY
740typename tuple_element<_Ip, tuple<_Tp...> >::type&&
741get(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
750template <class ..._Tp>
751inline _LIBCPP_INLINE_VISIBILITY
752tuple<_Tp&...>
753tie(_Tp&... __t)
754{
755    return tuple<_Tp&...>(__t...);
756}
757
758template <class _Up>
759struct __ignore_t
760{
761    template <class _Tp>
762        _LIBCPP_INLINE_VISIBILITY
763        const __ignore_t& operator=(_Tp&&) const {return *this;}
764};
765
766namespace { const __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>(); }
767
768template <class _Tp> class reference_wrapper;
769
770template <class _Tp>
771struct ___make_tuple_return
772{
773    typedef _Tp type;
774};
775
776template <class _Tp>
777struct ___make_tuple_return<reference_wrapper<_Tp> >
778{
779    typedef _Tp& type;
780};
781
782template <class _Tp>
783struct __make_tuple_return
784{
785    typedef typename ___make_tuple_return<typename decay<_Tp>::type>::type type;
786};
787
788template <class... _Tp>
789inline _LIBCPP_INLINE_VISIBILITY
790tuple<typename __make_tuple_return<_Tp>::type...>
791make_tuple(_Tp&&... __t)
792{
793    return tuple<typename __make_tuple_return<_Tp>::type...>(_VSTD::forward<_Tp>(__t)...);
794}
795
796template <class... _Tp>
797inline _LIBCPP_INLINE_VISIBILITY
798tuple<_Tp&&...>
799forward_as_tuple(_Tp&&... __t)
800{
801    return tuple<_Tp&&...>(_VSTD::forward<_Tp>(__t)...);
802}
803
804template <size_t _Ip>
805struct __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
815template <>
816struct __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
826template <class ..._Tp, class ..._Up>
827inline _LIBCPP_INLINE_VISIBILITY
828bool
829operator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
830{
831    return __tuple_equal<sizeof...(_Tp)>()(__x, __y);
832}
833
834template <class ..._Tp, class ..._Up>
835inline _LIBCPP_INLINE_VISIBILITY
836bool
837operator!=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
838{
839    return !(__x == __y);
840}
841
842template <size_t _Ip>
843struct __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
854template <>
855struct __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
865template <class ..._Tp, class ..._Up>
866inline _LIBCPP_INLINE_VISIBILITY
867bool
868operator<(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
869{
870    return __tuple_less<sizeof...(_Tp)>()(__x, __y);
871}
872
873template <class ..._Tp, class ..._Up>
874inline _LIBCPP_INLINE_VISIBILITY
875bool
876operator>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
877{
878    return __y < __x;
879}
880
881template <class ..._Tp, class ..._Up>
882inline _LIBCPP_INLINE_VISIBILITY
883bool
884operator>=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
885{
886    return !(__x < __y);
887}
888
889template <class ..._Tp, class ..._Up>
890inline _LIBCPP_INLINE_VISIBILITY
891bool
892operator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
893{
894    return !(__y < __x);
895}
896
897// tuple_cat
898
899template <class _Tp, class _Up> struct __tuple_cat_type;
900
901template <class ..._Ttypes, class ..._Utypes>
902struct __tuple_cat_type<tuple<_Ttypes...>, __tuple_types<_Utypes...> >
903{
904    typedef tuple<_Ttypes..., _Utypes...> type;
905};
906
907template <class _ResultTuple, bool _Is_Tuple0TupleLike, class ..._Tuples>
908struct __tuple_cat_return_1
909{
910};
911
912template <class ..._Types, class _Tuple0>
913struct __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
920template <class ..._Types, class _Tuple0, class _Tuple1, class ..._Tuples>
921struct __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
932template <class ..._Tuples> struct __tuple_cat_return;
933
934template <class _Tuple0, class ..._Tuples>
935struct __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
942template <>
943struct __tuple_cat_return<>
944{
945    typedef tuple<> type;
946};
947
948inline _LIBCPP_INLINE_VISIBILITY
949tuple<>
950tuple_cat()
951{
952    return tuple<>();
953}
954
955template <class _Rp, class _Indices, class _Tuple0, class ..._Tuples>
956struct __tuple_cat_return_ref_imp;
957
958template <class ..._Types, size_t ..._I0, class _Tuple0>
959struct __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
966template <class ..._Types, size_t ..._I0, class _Tuple0, class _Tuple1, class ..._Tuples>
967struct __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
979template <class _Tuple0, class ..._Tuples>
980struct __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
988template <class _Types, class _I0, class _J0>
989struct __tuple_cat;
990
991template <class ..._Types, size_t ..._I0, size_t ..._J0>
992struct __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
1023template <class _Tuple0, class... _Tuples>
1024inline _LIBCPP_INLINE_VISIBILITY
1025typename __tuple_cat_return<_Tuple0, _Tuples...>::type
1026tuple_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
1035template <class ..._Tp, class _Alloc>
1036struct _LIBCPP_VISIBLE uses_allocator<tuple<_Tp...>, _Alloc>
1037    : true_type {};
1038
1039template <class _T1, class _T2>
1040template <class... _Args1, class... _Args2, size_t ..._I1, size_t ..._I2>
1041inline _LIBCPP_INLINE_VISIBILITY
1042pair<_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
1055