tuple revision 249998
153813Simp// -*- C++ -*-
2120330Simp//===--------------------------- tuple ------------------------------------===//
3100213Simp//
452506Simp//                     The LLVM Compiler Infrastructure
552506Simp//
6140752Simp// This file is distributed under the University of Illinois Open Source
752506Simp// License. See LICENSE.TXT for details.
852506Simp//
952506Simp//===----------------------------------------------------------------------===//
1052506Simp
1152506Simp#ifndef _LIBCPP_TUPLE
1252506Simp#define _LIBCPP_TUPLE
1352506Simp
1452506Simp/*
1552506Simp    tuple synopsis
1652506Simp
1752506Simpnamespace std
1852506Simp{
1952506Simp
2052506Simptemplate <class... T>
2152506Simpclass tuple {
2252506Simppublic:
2352506Simp    constexpr tuple();
2452506Simp    explicit tuple(const T&...);
2552506Simp    template <class... U>
2652506Simp        explicit tuple(U&&...);
2752506Simp    tuple(const tuple&) = default;
2852506Simp    tuple(tuple&&) = default;
2952506Simp    template <class... U>
3052506Simp        tuple(const tuple<U...>&);
3152506Simp    template <class... U>
3252506Simp        tuple(tuple<U...>&&);
3352506Simp    template <class U1, class U2>
3452506Simp        tuple(const pair<U1, U2>&); // iff sizeof...(T) == 2
3552506Simp    template <class U1, class U2>
3652506Simp        tuple(pair<U1, U2>&&); // iff sizeof...(T) == 2
3752506Simp
3852506Simp    // allocator-extended constructors
3952506Simp    template <class Alloc>
4052506Simp        tuple(allocator_arg_t, const Alloc& a);
41140752Simp    template <class Alloc>
42140752Simp        tuple(allocator_arg_t, const Alloc& a, const T&...);
43140752Simp    template <class Alloc, class... U>
44140752Simp        tuple(allocator_arg_t, const Alloc& a, U&&...);
45140752Simp    template <class Alloc>
46140752Simp        tuple(allocator_arg_t, const Alloc& a, const tuple&);
47140752Simp    template <class Alloc>
48140752Simp        tuple(allocator_arg_t, const Alloc& a, tuple&&);
49140752Simp    template <class Alloc, class... U>
50140752Simp        tuple(allocator_arg_t, const Alloc& a, const tuple<U...>&);
51140752Simp    template <class Alloc, class... U>
52140752Simp        tuple(allocator_arg_t, const Alloc& a, tuple<U...>&&);
53140752Simp    template <class Alloc, class U1, class U2>
54140752Simp        tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&);
55140752Simp    template <class Alloc, class U1, class U2>
56140752Simp        tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&);
57140752Simp
58140752Simp    tuple& operator=(const tuple&);
59140752Simp    tuple&
60140752Simp        operator=(tuple&&) noexcept(AND(is_nothrow_move_assignable<T>::value ...));
61140752Simp    template <class... U>
62140752Simp        tuple& operator=(const tuple<U...>&);
63140752Simp    template <class... U>
64140752Simp        tuple& operator=(tuple<U...>&&);
65140752Simp    template <class U1, class U2>
66140752Simp        tuple& operator=(const pair<U1, U2>&); // iff sizeof...(T) == 2
67140752Simp    template <class U1, class U2>
6852506Simp        tuple& operator=(pair<U1, U2>&&); //iffsizeof...(T) == 2
69140749Simp
70140749Simp    void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...));
71140749Simp};
72140749Simp
73140749Simpconst unspecified ignore;
74149561Simp
75149561Simptemplate <class... T> tuple<V...>  make_tuple(T&&...);
76149561Simptemplate <class... T> tuple<ATypes...> forward_as_tuple(T&&...) noexcept;
77149561Simptemplate <class... T> tuple<T&...> tie(T&...) noexcept;
78149561Simptemplate <class... Tuples> tuple<CTypes...> tuple_cat(Tuples&&... tpls);
7952506Simp  
8052506Simp// 20.4.1.4, tuple helper classes:
81140793Simptemplate <class T> class tuple_size; // undefined
82140793Simptemplate <class... T> class tuple_size<tuple<T...>>;
8358545Simptemplate <intsize_t I, class T> class tuple_element; // undefined
8452506Simptemplate <intsize_t I, class... T> class tuple_element<I, tuple<T...>>;
8565039Simp
8665039Simp// 20.4.1.5, element access:
8752506Simptemplate <intsize_t I, class... T>
88140793Simp    typename tuple_element<I, tuple<T...>>::type&
89148141Simp    get(tuple<T...>&) noexcept;
90140793Simptemplate <intsize_t I, class... T>
9152506Simp    typename tuple_element<I, tuple<T...>>::type const&
9252506Simp    get(const tuple<T...>&) noexcept;
9352506Simptemplate <intsize_t I, class... T>
9452506Simp    typename tuple_element<I, tuple<T...>>::type&&
9558545Simp    get(tuple<T...>&&) noexcept;
9652506Simp
9786455Simp// 20.4.1.6, relational operators:
9879270Simptemplate<class... T, class... U> bool operator==(const tuple<T...>&, const tuple<U...>&);
99107359Snontemplate<class... T, class... U> bool operator<(const tuple<T...>&, const tuple<U...>&);
10052506Simptemplate<class... T, class... U> bool operator!=(const tuple<T...>&, const tuple<U...>&);
10186269Simptemplate<class... T, class... U> bool operator>(const tuple<T...>&, const tuple<U...>&);
10286455Simptemplate<class... T, class... U> bool operator<=(const tuple<T...>&, const tuple<U...>&);
103119225Simptemplate<class... T, class... U> bool operator>=(const tuple<T...>&, const tuple<U...>&);
10452506Simp
105140749Simptemplate <class... Types, class Alloc>
10686455Simp  struct uses_allocator<tuple<Types...>, Alloc>;
10758545Simp
108104854Simptemplate <class... Types>
109140886Simp  void
11052506Simp  swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(noexcept(x.swap(y)));
11186455Simp
11252506Simp}  // std
11386455Simp
11453813Simp*/
115148141Simp
116100213Simp#include <__config>
11758545Simp#include <__tuple>
11889945Simp#include <cstddef>
11984514Simp#include <type_traits>
120147872Simp#include <__functional_base>
12158545Simp#include <utility>
122119234Simp
12369138Speter#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
124118634Simp#pragma GCC system_header
125149561Simp#endif
12652506Simp
12758545Simp_LIBCPP_BEGIN_NAMESPACE_STD
128140837Simp
129140793Simp// allocator_arg_t
130140793Simp
131147872Simpstruct _LIBCPP_TYPE_VIS allocator_arg_t { };
132140793Simp
13358545Simp#if defined(_LIBCPP_HAS_NO_CONSTEXPR) || defined(_LIBCPP_BUILDING_MEMORY)
13465039Simpextern const allocator_arg_t allocator_arg;
13592471Simp#else
136140793Simpconstexpr allocator_arg_t allocator_arg = allocator_arg_t();
137116207Simp#endif
13884514Simp
13979270Simp// uses_allocator
140140793Simp
14179270Simptemplate <class _Tp>
142117438Simpstruct __has_allocator_type
143117602Simp{
144148141Simpprivate:
145118895Simp    struct __two {char __lx; char __lxx;};
146119240Simp    template <class _Up> static __two __test(...);
147119240Simp    template <class _Up> static char __test(typename _Up::allocator_type* = 0);
148119240Simppublic:
149119240Simp    static const bool value = sizeof(__test<_Tp>(0)) == 1;
15093620Simp};
15186455Simp
152119240Simptemplate <class _Tp, class _Alloc, bool = __has_allocator_type<_Tp>::value>
153119240Simpstruct __uses_allocator
154119240Simp    : public integral_constant<bool,
155119240Simp        is_convertible<_Alloc, typename _Tp::allocator_type>::value>
156119240Simp{
157147872Simp};
158140793Simp
159119240Simptemplate <class _Tp, class _Alloc>
160141122Simpstruct __uses_allocator<_Tp, _Alloc, false>
161141122Simp    : public false_type
162141122Simp{
163141122Simp};
164141122Simp
165141122Simptemplate <class _Tp, class _Alloc>
166141122Simpstruct _LIBCPP_TYPE_VIS uses_allocator
167141122Simp    : public __uses_allocator<_Tp, _Alloc>
168145247Sdamien{
169141122Simp};
170119240Simp
171119240Simp#ifndef _LIBCPP_HAS_NO_VARIADICS
172140792Simp
173140792Simp// uses-allocator construction
174141122Simp
175119240Simptemplate <class _Tp, class _Alloc, class ..._Args>
176140793Simpstruct __uses_alloc_ctor_imp
17786455Simp{
17886455Simp    static const bool __ua = uses_allocator<_Tp, _Alloc>::value;
17989945Simp    static const bool __ic =
18053813Simp        is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value;
18171279Simp    static const int value = __ua ? 2 - __ic : 0;
18271283Simp};
183113667Ssanpei
18453813Simptemplate <class _Tp, class _Alloc, class ..._Args>
18552506Simpstruct __uses_alloc_ctor
186140793Simp    : integral_constant<int, __uses_alloc_ctor_imp<_Tp, _Alloc, _Args...>::value>
187140792Simp    {};
188107359Snon
18971283Simp#endif  // _LIBCPP_HAS_NO_VARIADICS
19052506Simp
19152506Simp#ifndef _LIBCPP_HAS_NO_VARIADICS
19286269Simp
19386269Simp// tuple_size
19452506Simp
19553813Simptemplate <class ..._Tp>
19652506Simpclass _LIBCPP_TYPE_VIS tuple_size<tuple<_Tp...> >
19765039Simp    : public integral_constant<size_t, sizeof...(_Tp)>
19886269Simp{
19986269Simp};
20086269Simp
201135002Semax// tuple_element
20286269Simp
20352506Simptemplate <size_t _Ip, class ..._Tp>
20452506Simpclass _LIBCPP_TYPE_VIS tuple_element<_Ip, tuple<_Tp...> >
20552506Simp{
20693893Simppublic:
20786455Simp    typedef typename tuple_element<_Ip, __tuple_types<_Tp...> >::type type;
20884514Simp};
20952506Simp
210104854Simp// __tuple_leaf
211104854Simp
21294461Simptemplate <size_t _Ip, class _Hp, bool=is_empty<_Hp>::value
21386269Simp#if __has_feature(is_final)
21486269Simp                                 && !__is_final(_Hp)
21586269Simp#endif
216147872Simp         >
21786269Simpclass __tuple_leaf;
21886269Simp
21986269Simptemplate <size_t _Ip, class _Hp, bool _Ep>
22086269Simpinline _LIBCPP_INLINE_VISIBILITY
22186269Simpvoid swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y)
22286269Simp    _NOEXCEPT_(__is_nothrow_swappable<_Hp>::value)
223117614Simp{
224117614Simp    swap(__x.get(), __y.get());
225117614Simp}
22686269Simp
22786269Simptemplate <size_t _Ip, class _Hp, bool>
22886269Simpclass __tuple_leaf
229140793Simp{
230140793Simp    _Hp value;
231140793Simp
232140793Simp    __tuple_leaf& operator=(const __tuple_leaf&);
23386455Simppublic:
23486455Simp    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __tuple_leaf()
23586455Simp             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) : value()
236116207Simp       {static_assert(!is_reference<_Hp>::value,
237116207Simp              "Attempted to default construct a reference element in a tuple");}
238116207Simp
239117438Simp    template <class _Alloc>
240117445Ssimokawa        _LIBCPP_INLINE_VISIBILITY
241117438Simp        __tuple_leaf(integral_constant<int, 0>, const _Alloc&)
24286269Simp            : value()
24386269Simp        {static_assert(!is_reference<_Hp>::value,
24486269Simp              "Attempted to default construct a reference element in a tuple");}
24586269Simp
246104854Simp    template <class _Alloc>
24786269Simp        _LIBCPP_INLINE_VISIBILITY
24887757Simp        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
24987757Simp            : value(allocator_arg_t(), __a)
25087757Simp        {static_assert(!is_reference<_Hp>::value,
25186455Simp              "Attempted to default construct a reference element in a tuple");}
25286455Simp
25386455Simp    template <class _Alloc>
254119231Simp        _LIBCPP_INLINE_VISIBILITY
255147872Simp        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
256147872Simp            : value(__a)
257119231Simp        {static_assert(!is_reference<_Hp>::value,
258147956Simp              "Attempted to default construct a reference element in a tuple");}
259119231Simp
260119231Simp    template <class _Tp,
26186269Simp              class = typename enable_if<is_constructible<_Hp, _Tp>::value>::type>
262147872Simp        _LIBCPP_INLINE_VISIBILITY
263117759Simp        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
264147872Simp            : value(_VSTD::forward<_Tp>(__t))
26586269Simp        {static_assert(!is_reference<_Hp>::value ||
266109455Sshiba                       (is_lvalue_reference<_Hp>::value &&
267104854Simp                        (is_lvalue_reference<_Tp>::value ||
26887044Simp                         is_same<typename remove_reference<_Tp>::type,
26986269Simp                                 reference_wrapper<
27065039Simp                                    typename remove_reference<_Hp>::type
27186269Simp                                 >
272147872Simp                                >::value)) ||
27365039Simp                        (is_rvalue_reference<_Hp>::value &&
27465039Simp                         !is_lvalue_reference<_Tp>::value),
27552506Simp       "Attempted to construct a reference element in a tuple with an rvalue");}
27686455Simp
27752506Simp    template <class _Tp, class _Alloc>
278147872Simp        _LIBCPP_INLINE_VISIBILITY
279147872Simp        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
28052506Simp            : value(_VSTD::forward<_Tp>(__t))
28186269Simp        {static_assert(!is_lvalue_reference<_Hp>::value ||
28286269Simp                       (is_lvalue_reference<_Hp>::value &&
28386269Simp                        (is_lvalue_reference<_Tp>::value ||
28453813Simp                         is_same<typename remove_reference<_Tp>::type,
28552506Simp                                 reference_wrapper<
28652506Simp                                    typename remove_reference<_Hp>::type
28752506Simp                                 >
28852506Simp                                >::value)),
28952506Simp       "Attempted to construct a reference element in a tuple with an rvalue");}
29052506Simp
29152506Simp    template <class _Tp, class _Alloc>
292119225Simp        _LIBCPP_INLINE_VISIBILITY
293119225Simp        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
294119225Simp            : value(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t))
295119225Simp        {static_assert(!is_lvalue_reference<_Hp>::value ||
29686455Simp                       (is_lvalue_reference<_Hp>::value &&
29786455Simp                        (is_lvalue_reference<_Tp>::value ||
29886455Simp                         is_same<typename remove_reference<_Tp>::type,
29989945Simp                                 reference_wrapper<
30089945Simp                                    typename remove_reference<_Hp>::type
30189945Simp                                 >
30271279Simp                                >::value)),
30371279Simp       "Attempted to construct a reference element in a tuple with an rvalue");}
30471279Simp
30586269Simp    template <class _Tp, class _Alloc>
306100213Simp        _LIBCPP_INLINE_VISIBILITY
307147579Simp        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
30871279Simp            : value(_VSTD::forward<_Tp>(__t), __a)
30986269Simp        {static_assert(!is_lvalue_reference<_Hp>::value ||
31086269Simp                       (is_lvalue_reference<_Hp>::value &&
31186269Simp                        (is_lvalue_reference<_Tp>::value ||
31289945Simp                         is_same<typename remove_reference<_Tp>::type,
31389945Simp                                 reference_wrapper<
31489945Simp                                    typename remove_reference<_Hp>::type
31586269Simp                                 >
31686269Simp                                >::value)),
31786269Simp       "Attempted to construct a reference element in a tuple with an rvalue");}
31852506Simp
319139963Simp    __tuple_leaf(const __tuple_leaf& __t) _NOEXCEPT_(is_nothrow_copy_constructible<_Hp>::value)
32052506Simp        : value(__t.get())
32186269Simp        {static_assert(!is_rvalue_reference<_Hp>::value, "Can not copy a tuple with rvalue reference member");}
32253813Simp
323120330Simp    template <class _Tp>
32453813Simp        _LIBCPP_INLINE_VISIBILITY
325100213Simp        explicit __tuple_leaf(const __tuple_leaf<_Ip, _Tp>& __t)
326100213Simp                           _NOEXCEPT_((is_nothrow_constructible<_Hp, const _Tp&>::value))
327100213Simp            : value(__t.get()) {}
328140886Simp
329147872Simp    template <class _Tp>
330140887Simp        _LIBCPP_INLINE_VISIBILITY
331140886Simp        __tuple_leaf&
33292471Simp        operator=(_Tp&& __t) _NOEXCEPT_((is_nothrow_assignable<_Hp&, _Tp>::value))
33392471Simp        {
33492471Simp            value = _VSTD::forward<_Tp>(__t);
33552506Simp            return *this;
33671279Simp        }
33765039Simp
33865039Simp    _LIBCPP_INLINE_VISIBILITY
33965039Simp    int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
34065039Simp    {
34187044Simp        _VSTD::swap(*this, __t);
34265039Simp        return 0;
34352506Simp    }
34465039Simp
34589103Simp    _LIBCPP_INLINE_VISIBILITY       _Hp& get()       _NOEXCEPT {return value;}
34653813Simp    _LIBCPP_INLINE_VISIBILITY const _Hp& get() const _NOEXCEPT {return value;}
34752506Simp};
34865039Simp
34986269Simptemplate <size_t _Ip, class _Hp>
35065039Simpclass __tuple_leaf<_Ip, _Hp, true>
351121960Simp    : private _Hp
352129164Simp{
35365039Simp
354119213Simp    __tuple_leaf& operator=(const __tuple_leaf&);
355127422Simppublic:
356140520Simp    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __tuple_leaf()
357140520Simp             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) {}
358140520Simp
359119213Simp    template <class _Alloc>
36052506Simp        _LIBCPP_INLINE_VISIBILITY
36179270Simp        __tuple_leaf(integral_constant<int, 0>, const _Alloc&) {}
362117764Simp
36352506Simp    template <class _Alloc>
36486269Simp        _LIBCPP_INLINE_VISIBILITY
36586269Simp        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
366147872Simp            : _Hp(allocator_arg_t(), __a) {}
36765039Simp
36886269Simp    template <class _Alloc>
36986269Simp        _LIBCPP_INLINE_VISIBILITY
37086269Simp        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
37158545Simp            : _Hp(__a) {}
37271279Simp
37358545Simp    template <class _Tp,
37452506Simp              class = typename enable_if<is_constructible<_Hp, _Tp>::value>::type>
37586269Simp        _LIBCPP_INLINE_VISIBILITY
37658545Simp        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
37752506Simp            : _Hp(_VSTD::forward<_Tp>(__t)) {}
37852506Simp
37952506Simp    template <class _Tp, class _Alloc>
38086269Simp        _LIBCPP_INLINE_VISIBILITY
38186269Simp        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
382148141Simp            : _Hp(_VSTD::forward<_Tp>(__t)) {}
383148141Simp
38486269Simp    template <class _Tp, class _Alloc>
38586269Simp        _LIBCPP_INLINE_VISIBILITY
38686269Simp        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
387107359Snon            : _Hp(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) {}
38886269Simp
389140749Simp    template <class _Tp, class _Alloc>
390140749Simp        _LIBCPP_INLINE_VISIBILITY
391140749Simp        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
39252506Simp            : _Hp(_VSTD::forward<_Tp>(__t), __a) {}
393147956Simp
39486269Simp    template <class _Tp>
39552506Simp        _LIBCPP_INLINE_VISIBILITY
39653813Simp        explicit __tuple_leaf(const __tuple_leaf<_Ip, _Tp>& __t)
39752506Simp            _NOEXCEPT_((is_nothrow_constructible<_Hp, const _Tp&>::value))
39852506Simp            : _Hp(__t.get()) {}
39958545Simp
400140515Simp    template <class _Tp>
40158545Simp        _LIBCPP_INLINE_VISIBILITY
40258545Simp        __tuple_leaf&
403118895Simp        operator=(_Tp&& __t) _NOEXCEPT_((is_nothrow_assignable<_Hp&, _Tp>::value))
404118895Simp        {
405118895Simp            _Hp::operator=(_VSTD::forward<_Tp>(__t));
40686269Simp            return *this;
40786269Simp        }
40886269Simp
409147872Simp    _LIBCPP_INLINE_VISIBILITY
41086455Simp    int
41186269Simp    swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
41286269Simp    {
41386269Simp        _VSTD::swap(*this, __t);
414147872Simp        return 0;
415147872Simp    }
416147872Simp
417104831Simp    _LIBCPP_INLINE_VISIBILITY       _Hp& get()       _NOEXCEPT {return static_cast<_Hp&>(*this);}
418106891Simp    _LIBCPP_INLINE_VISIBILITY const _Hp& get() const _NOEXCEPT {return static_cast<const _Hp&>(*this);}
419106891Simp};
420147872Simp
421147872Simptemplate <class ..._Tp>
42286269Simp_LIBCPP_INLINE_VISIBILITY
42386455Simpvoid __swallow(_Tp&&...) _NOEXCEPT {}
42486455Simp
42593620Simptemplate <bool ...> struct __all;
42686455Simp
42779270Simptemplate <>
428147872Simpstruct __all<>
429147872Simp{
430147872Simp    static const bool value = true;
431147872Simp};
43279270Simp
433147872Simptemplate <bool _B0, bool ... _Bp>
43479270Simpstruct __all<_B0, _Bp...>
435140792Simp{
436140792Simp    static const bool value = _B0 && __all<_Bp...>::value;
437140792Simp};
43858545Simp
439100213Simp// __tuple_impl
44058545Simp
44158545Simptemplate<class _Indx, class ..._Tp> struct __tuple_impl;
44293620Simp
44393620Simptemplate<size_t ..._Indx, class ..._Tp>
44493620Simpstruct __tuple_impl<__tuple_indices<_Indx...>, _Tp...>
44593620Simp    : public __tuple_leaf<_Indx, _Tp>...
44665039Simp{
447140957Simp    _LIBCPP_INLINE_VISIBILITY
448149674Simp    _LIBCPP_CONSTEXPR __tuple_impl()
449121586Simp        _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
450149674Simp
451121584Simp    template <size_t ..._Uf, class ..._Tf,
452149674Simp              size_t ..._Ul, class ..._Tl, class ..._Up>
45365039Simp        _LIBCPP_INLINE_VISIBILITY
454104854Simp        explicit
455147956Simp        __tuple_impl(__tuple_indices<_Uf...>, __tuple_types<_Tf...>,
456147956Simp                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
457147956Simp                     _Up&&... __u)
458147872Simp                     _NOEXCEPT_((__all<is_nothrow_constructible<_Tf, _Up>::value...>::value &&
459147872Simp                                 __all<is_nothrow_default_constructible<_Tl>::value...>::value)) :
460104854Simp            __tuple_leaf<_Uf, _Tf>(_VSTD::forward<_Up>(__u))...,
46158545Simp            __tuple_leaf<_Ul, _Tl>()...
46258545Simp            {}
46365039Simp
464107359Snon    template <class _Alloc, size_t ..._Uf, class ..._Tf,
465148141Simp              size_t ..._Ul, class ..._Tl, class ..._Up>
466141223Simp        _LIBCPP_INLINE_VISIBILITY
46786269Simp        explicit
468124789Sume        __tuple_impl(allocator_arg_t, const _Alloc& __a,
46958545Simp                     __tuple_indices<_Uf...>, __tuple_types<_Tf...>,
470104831Simp                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
471141122Simp                     _Up&&... __u) :
472104831Simp            __tuple_leaf<_Uf, _Tf>(__uses_alloc_ctor<_Tf, _Alloc, _Up>(), __a,
473147872Simp            _VSTD::forward<_Up>(__u))...,
474147872Simp            __tuple_leaf<_Ul, _Tl>(__uses_alloc_ctor<_Tl, _Alloc>(), __a)...
475147872Simp            {}
47686455Simp
477120275Simp    template <class _Tuple,
47886455Simp              class = typename enable_if
47986455Simp                      <
48093622Simp                         __tuple_constructible<_Tuple, tuple<_Tp...> >::value
48186455Simp                      >::type
48284514Simp             >
48384514Simp        _LIBCPP_INLINE_VISIBILITY
484147872Simp        __tuple_impl(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_constructible<_Tp, typename tuple_element<_Indx,
485147872Simp                                       typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))
486147872Simp            : __tuple_leaf<_Indx, _Tp>(_VSTD::forward<typename tuple_element<_Indx,
48784514Simp                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
488107359Snon            {}
489107359Snon
490107359Snon    template <class _Alloc, class _Tuple,
49186455Simp              class = typename enable_if
492120330Simp                      <
49386455Simp                         __tuple_convertible<_Tuple, tuple<_Tp...> >::value
494147872Simp                      >::type
495147872Simp             >
496147872Simp        _LIBCPP_INLINE_VISIBILITY
497147872Simp        __tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
498147872Simp            : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, typename tuple_element<_Indx,
49986455Simp                                       typename __make_tuple_types<_Tuple>::type>::type>(), __a,
50086269Simp                                       _VSTD::forward<typename tuple_element<_Indx,
501109103Sshiba                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
502147988Stakawata            {}
50352506Simp
504140837Simp    template <class _Tuple>
505147872Simp        _LIBCPP_INLINE_VISIBILITY
506140837Simp        typename enable_if
507142260Simp        <
508147872Simp            __tuple_assignable<_Tuple, tuple<_Tp...> >::value,
509140837Simp            __tuple_impl&
510145247Sdamien        >::type
511145247Sdamien        operator=(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_assignable<_Tp&, typename tuple_element<_Indx,
512145247Sdamien                                       typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))
51386269Simp        {
51486269Simp            __swallow(__tuple_leaf<_Indx, _Tp>::operator=(_VSTD::forward<typename tuple_element<_Indx,
51586269Simp                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...);
516147872Simp            return *this;
517147872Simp        }
518147872Simp
51986269Simp        _LIBCPP_INLINE_VISIBILITY
52086269Simp        __tuple_impl&
52186269Simp        operator=(const __tuple_impl& __t) _NOEXCEPT_((__all<is_nothrow_copy_assignable<_Tp>::value...>::value))
52286269Simp        {
52386269Simp            __swallow(__tuple_leaf<_Indx, _Tp>::operator=(static_cast<const __tuple_leaf<_Indx, _Tp>&>(__t).get())...);
52486269Simp            return *this;
52552506Simp        }
52652506Simp
52752506Simp    _LIBCPP_INLINE_VISIBILITY
528118063Simp    void swap(__tuple_impl& __t)
529118063Simp        _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
530118063Simp    {
531117602Simp        __swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...);
532117602Simp    }
533117602Simp};
53452506Simp
53552506Simptemplate <class ..._Tp>
53653813Simpclass _LIBCPP_TYPE_VIS tuple
53753813Simp{
53852506Simp    typedef __tuple_impl<typename __make_tuple_indices<sizeof...(_Tp)>::type, _Tp...> base;
53986269Simp
540147796Simp    base base_;
54186269Simp
54286269Simp    template <size_t _Jp, class ..._Up> friend
54386269Simp        typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT;
54452506Simp    template <size_t _Jp, class ..._Up> friend
54579270Simp        const typename tuple_element<_Jp, tuple<_Up...> >::type& get(const tuple<_Up...>&) _NOEXCEPT;
54689103Simp    template <size_t _Jp, class ..._Up> friend
54752506Simp        typename tuple_element<_Jp, tuple<_Up...> >::type&& get(tuple<_Up...>&&) _NOEXCEPT;
54852506Simppublic:
549147872Simp
55086269Simp    _LIBCPP_INLINE_VISIBILITY
551147872Simp    _LIBCPP_CONSTEXPR tuple()
55271279Simp        _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
553118063Simp
55452506Simp    _LIBCPP_INLINE_VISIBILITY
55586269Simp    explicit tuple(const _Tp& ... __t) _NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value)) 
55686269Simp        : base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
55786269Simp                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
55852506Simp                typename __make_tuple_indices<0>::type(),
55986269Simp                typename __make_tuple_types<tuple, 0>::type(),
56052506Simp                __t...
56186269Simp               ) {}
56252506Simp
563104854Simp    template <class _Alloc>
564148141Simp      _LIBCPP_INLINE_VISIBILITY
565124015Skato      tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
566147872Simp        : base_(allocator_arg_t(), __a,
56752506Simp                typename __make_tuple_indices<sizeof...(_Tp)>::type(),
56886269Simp                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
569147872Simp                typename __make_tuple_indices<0>::type(),
57086269Simp                typename __make_tuple_types<tuple, 0>::type(),
57186269Simp                __t...
57286269Simp               ) {}
57386269Simp
57486269Simp    template <class ..._Up,
575107359Snon              typename enable_if
576107359Snon                      <
577107359Snon                         sizeof...(_Up) <= sizeof...(_Tp) &&
57865039Simp                         __tuple_convertible
579120898Simp                         <
58065039Simp                            tuple<_Up...>,
581128064Srsm                            typename __make_tuple_types<tuple,
582128064Srsm                                     sizeof...(_Up) < sizeof...(_Tp) ?
583128064Srsm                                        sizeof...(_Up) :
58486571Simp                                        sizeof...(_Tp)>::type
58586269Simp                         >::value,
58686269Simp                         bool
58779270Simp                      >::type = false
58865039Simp             >
589128064Srsm        _LIBCPP_INLINE_VISIBILITY
590128064Srsm        tuple(_Up&&... __u)
591128064Srsm            _NOEXCEPT_((
59286269Simp                is_nothrow_constructible<
593128064Srsm                    typename __make_tuple_indices<sizeof...(_Up)>::type,
594128064Srsm                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type,
595128064Srsm                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type,
596128064Srsm                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type,
597128064Srsm                    _Up...
59852506Simp                >::value
59984514Simp            ))
60084514Simp            : base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
60184514Simp                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
60286269Simp                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
60386269Simp                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
60486269Simp                    _VSTD::forward<_Up>(__u)...) {}
60586269Simp
60652506Simp    template <class ..._Up,
60793622Simp              typename enable_if
608103169Simp                      <
60986269Simp                         sizeof...(_Up) <= sizeof...(_Tp) &&
61086269Simp                         __tuple_constructible
61186269Simp                         <
612113667Ssanpei                            tuple<_Up...>,
61386269Simp                            typename __make_tuple_types<tuple,
614104854Simp                                     sizeof...(_Up) < sizeof...(_Tp) ?
61586269Simp                                        sizeof...(_Up) :
61658545Simp                                        sizeof...(_Tp)>::type
61758545Simp                         >::value &&
618120330Simp                         !__tuple_convertible
619107359Snon                         <
620116481Simp                            tuple<_Up...>,
62186281Simp                            typename __make_tuple_types<tuple,
62258545Simp                                     sizeof...(_Up) < sizeof...(_Tp) ?
623119215Simp                                        sizeof...(_Up) :
624107359Snon                                        sizeof...(_Tp)>::type
62593620Simp                         >::value,
626118634Simp                         bool
62786392Simp                      >::type =false
628107359Snon             >
629114089Simp        _LIBCPP_INLINE_VISIBILITY
63086269Simp        explicit
63186269Simp        tuple(_Up&&... __u)
63286269Simp            _NOEXCEPT_((
63386269Simp                is_nothrow_constructible<
634141930Simp                    typename __make_tuple_indices<sizeof...(_Up)>::type,
63586269Simp                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type,
636113318Simp                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type,
637107359Snon                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type,
63886269Simp                    _Up...
639110935Sshiba                >::value
64086580Simp            ))
64152506Simp            : base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
64252506Simp                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
643104854Simp                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
64493622Simp                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
645110175Sshiba                    _VSTD::forward<_Up>(__u)...) {}
64686269Simp
647104854Simp    template <class _Alloc, class ..._Up,
648103169Simp              class = typename enable_if
649113318Simp                      <
65086269Simp                         sizeof...(_Up) <= sizeof...(_Tp) &&
651113322Simp                         __tuple_convertible
65258545Simp                         <
65386269Simp                            tuple<_Up...>,
65458545Simp                            typename __make_tuple_types<tuple,
655104854Simp                                     sizeof...(_Up) < sizeof...(_Tp) ?
65658545Simp                                        sizeof...(_Up) :
65779270Simp                                        sizeof...(_Tp)>::type
65879270Simp                         >::value
65965039Simp                      >::type
66079270Simp             >
66186269Simp        _LIBCPP_INLINE_VISIBILITY
662113318Simp        tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
66386269Simp            : base_(allocator_arg_t(), __a,
66486269Simp                    typename __make_tuple_indices<sizeof...(_Up)>::type(),
66586269Simp                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
66686269Simp                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
667104854Simp                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
668112356Simp                    _VSTD::forward<_Up>(__u)...) {}
669104854Simp
67058545Simp    template <class _Tuple,
67186269Simp              typename enable_if
67286269Simp                      <
67358545Simp                         __tuple_convertible<_Tuple, tuple>::value,
67486269Simp                         bool
67558545Simp                      >::type = false
676107359Snon             >
67758545Simp        _LIBCPP_INLINE_VISIBILITY
678120290Simp        tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<base, _Tuple>::value))
679116481Simp            : base_(_VSTD::forward<_Tuple>(__t)) {}
680120330Simp
681120330Simp    template <class _Tuple,
682120330Simp              typename enable_if
683120330Simp                      <
684107359Snon                         __tuple_constructible<_Tuple, tuple>::value &&
68586269Simp                         !__tuple_convertible<_Tuple, tuple>::value,
686107359Snon                         bool
68758545Simp                      >::type = false
688119215Simp             >
689140837Simp        _LIBCPP_INLINE_VISIBILITY
690107359Snon        explicit
691140837Simp        tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<base, _Tuple>::value))
69293620Simp            : base_(_VSTD::forward<_Tuple>(__t)) {}
69386269Simp
694107359Snon    template <class _Alloc, class _Tuple,
69586269Simp              class = typename enable_if
696118634Simp                      <
69771283Simp                         __tuple_convertible<_Tuple, tuple>::value
69886269Simp                      >::type
69979270Simp             >
700107359Snon        _LIBCPP_INLINE_VISIBILITY
701107359Snon        tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
70279270Simp            : base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {}
703114089Simp
704115754Simp    template <class _Tuple,
705141930Simp              class = typename enable_if
70686269Simp                      <
70786269Simp                         __tuple_assignable<_Tuple, tuple>::value
70886269Simp                      >::type
70986269Simp             >
710109103Sshiba        _LIBCPP_INLINE_VISIBILITY
711107359Snon        tuple&
712107359Snon        operator=(_Tuple&& __t) _NOEXCEPT_((is_nothrow_assignable<base&, _Tuple>::value))
713107359Snon        {
714107359Snon            base_.operator=(_VSTD::forward<_Tuple>(__t));
715109103Sshiba            return *this;
716147988Stakawata        }
71789103Simp
71886269Simp    _LIBCPP_INLINE_VISIBILITY
719147872Simp    void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
720147872Simp        {base_.swap(__t.base_);}
721147872Simp};
72286269Simp
72386269Simptemplate <>
724141930Simpclass _LIBCPP_TYPE_VIS tuple<>
72586269Simp{
726113318Simppublic:
727107359Snon    _LIBCPP_INLINE_VISIBILITY
72886269Simp    _LIBCPP_CONSTEXPR tuple() _NOEXCEPT {}
72986269Simp    template <class _Alloc>
730110935Sshiba    _LIBCPP_INLINE_VISIBILITY
73174634Simp        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
745template <class ..._Tp>
746inline _LIBCPP_INLINE_VISIBILITY
747typename enable_if
748<
749    __all<__is_swappable<_Tp>::value...>::value,
750    void
751>::type
752swap(tuple<_Tp...>& __t, tuple<_Tp...>& __u)
753                 _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
754    {__t.swap(__u);}
755
756// get
757
758template <size_t _Ip, class ..._Tp>
759inline _LIBCPP_INLINE_VISIBILITY
760typename tuple_element<_Ip, tuple<_Tp...> >::type&
761get(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
767template <size_t _Ip, class ..._Tp>
768inline _LIBCPP_INLINE_VISIBILITY
769const typename tuple_element<_Ip, tuple<_Tp...> >::type&
770get(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
776template <size_t _Ip, class ..._Tp>
777inline _LIBCPP_INLINE_VISIBILITY
778typename tuple_element<_Ip, tuple<_Tp...> >::type&&
779get(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
788template <class ..._Tp>
789inline _LIBCPP_INLINE_VISIBILITY
790tuple<_Tp&...>
791tie(_Tp&... __t) _NOEXCEPT
792{
793    return tuple<_Tp&...>(__t...);
794}
795
796template <class _Up>
797struct __ignore_t
798{
799    template <class _Tp>
800        _LIBCPP_INLINE_VISIBILITY
801        const __ignore_t& operator=(_Tp&&) const {return *this;}
802};
803
804namespace { const __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>(); }
805
806template <class _Tp> class _LIBCPP_TYPE_VIS reference_wrapper;
807
808template <class _Tp>
809struct ___make_tuple_return
810{
811    typedef _Tp type;
812};
813
814template <class _Tp>
815struct ___make_tuple_return<reference_wrapper<_Tp> >
816{
817    typedef _Tp& type;
818};
819
820template <class _Tp>
821struct __make_tuple_return
822{
823    typedef typename ___make_tuple_return<typename decay<_Tp>::type>::type type;
824};
825
826template <class... _Tp>
827inline _LIBCPP_INLINE_VISIBILITY
828tuple<typename __make_tuple_return<_Tp>::type...>
829make_tuple(_Tp&&... __t)
830{
831    return tuple<typename __make_tuple_return<_Tp>::type...>(_VSTD::forward<_Tp>(__t)...);
832}
833
834template <class... _Tp>
835inline _LIBCPP_INLINE_VISIBILITY
836tuple<_Tp&&...>
837forward_as_tuple(_Tp&&... __t) _NOEXCEPT
838{
839    return tuple<_Tp&&...>(_VSTD::forward<_Tp>(__t)...);
840}
841
842template <size_t _Ip>
843struct __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
853template <>
854struct __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
864template <class ..._Tp, class ..._Up>
865inline _LIBCPP_INLINE_VISIBILITY
866bool
867operator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
868{
869    return __tuple_equal<sizeof...(_Tp)>()(__x, __y);
870}
871
872template <class ..._Tp, class ..._Up>
873inline _LIBCPP_INLINE_VISIBILITY
874bool
875operator!=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
876{
877    return !(__x == __y);
878}
879
880template <size_t _Ip>
881struct __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
892template <>
893struct __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
903template <class ..._Tp, class ..._Up>
904inline _LIBCPP_INLINE_VISIBILITY
905bool
906operator<(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
907{
908    return __tuple_less<sizeof...(_Tp)>()(__x, __y);
909}
910
911template <class ..._Tp, class ..._Up>
912inline _LIBCPP_INLINE_VISIBILITY
913bool
914operator>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
915{
916    return __y < __x;
917}
918
919template <class ..._Tp, class ..._Up>
920inline _LIBCPP_INLINE_VISIBILITY
921bool
922operator>=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
923{
924    return !(__x < __y);
925}
926
927template <class ..._Tp, class ..._Up>
928inline _LIBCPP_INLINE_VISIBILITY
929bool
930operator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
931{
932    return !(__y < __x);
933}
934
935// tuple_cat
936
937template <class _Tp, class _Up> struct __tuple_cat_type;
938
939template <class ..._Ttypes, class ..._Utypes>
940struct __tuple_cat_type<tuple<_Ttypes...>, __tuple_types<_Utypes...> >
941{
942    typedef tuple<_Ttypes..., _Utypes...> type;
943};
944
945template <class _ResultTuple, bool _Is_Tuple0TupleLike, class ..._Tuples>
946struct __tuple_cat_return_1
947{
948};
949
950template <class ..._Types, class _Tuple0>
951struct __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
958template <class ..._Types, class _Tuple0, class _Tuple1, class ..._Tuples>
959struct __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
970template <class ..._Tuples> struct __tuple_cat_return;
971
972template <class _Tuple0, class ..._Tuples>
973struct __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
980template <>
981struct __tuple_cat_return<>
982{
983    typedef tuple<> type;
984};
985
986inline _LIBCPP_INLINE_VISIBILITY
987tuple<>
988tuple_cat()
989{
990    return tuple<>();
991}
992
993template <class _Rp, class _Indices, class _Tuple0, class ..._Tuples>
994struct __tuple_cat_return_ref_imp;
995
996template <class ..._Types, size_t ..._I0, class _Tuple0>
997struct __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
1004template <class ..._Types, size_t ..._I0, class _Tuple0, class _Tuple1, class ..._Tuples>
1005struct __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
1017template <class _Tuple0, class ..._Tuples>
1018struct __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
1026template <class _Types, class _I0, class _J0>
1027struct __tuple_cat;
1028
1029template <class ..._Types, size_t ..._I0, size_t ..._J0>
1030struct __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
1061template <class _Tuple0, class... _Tuples>
1062inline _LIBCPP_INLINE_VISIBILITY
1063typename __tuple_cat_return<_Tuple0, _Tuples...>::type
1064tuple_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
1073template <class ..._Tp, class _Alloc>
1074struct _LIBCPP_TYPE_VIS uses_allocator<tuple<_Tp...>, _Alloc>
1075    : true_type {};
1076
1077template <class _T1, class _T2>
1078template <class... _Args1, class... _Args2, size_t ..._I1, size_t ..._I2>
1079inline _LIBCPP_INLINE_VISIBILITY
1080pair<_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