1227825Stheraven// -*- C++ -*-
2227825Stheraven//===--------------------------- tuple ------------------------------------===//
3227825Stheraven//
4227825Stheraven//                     The LLVM Compiler Infrastructure
5227825Stheraven//
6227825Stheraven// This file is distributed under the University of Illinois Open Source
7227825Stheraven// License. See LICENSE.TXT for details.
8227825Stheraven//
9227825Stheraven//===----------------------------------------------------------------------===//
10227825Stheraven
11227825Stheraven#ifndef _LIBCPP_TUPLE
12227825Stheraven#define _LIBCPP_TUPLE
13227825Stheraven
14227825Stheraven/*
15227825Stheraven    tuple synopsis
16227825Stheraven
17227825Stheravennamespace std
18227825Stheraven{
19227825Stheraven
20227825Stheraventemplate <class... T>
21227825Stheravenclass tuple {
22227825Stheravenpublic:
23227825Stheraven    constexpr tuple();
24261272Sdim    explicit tuple(const T&...);  // constexpr in C++14
25227825Stheraven    template <class... U>
26261272Sdim        explicit tuple(U&&...);  // constexpr in C++14
27227825Stheraven    tuple(const tuple&) = default;
28227825Stheraven    tuple(tuple&&) = default;
29227825Stheraven    template <class... U>
30261272Sdim        tuple(const tuple<U...>&);  // constexpr in C++14
31227825Stheraven    template <class... U>
32261272Sdim        tuple(tuple<U...>&&);  // constexpr in C++14
33227825Stheraven    template <class U1, class U2>
34261272Sdim        tuple(const pair<U1, U2>&); // iff sizeof...(T) == 2 // constexpr in C++14
35227825Stheraven    template <class U1, class U2>
36261272Sdim        tuple(pair<U1, U2>&&); // iff sizeof...(T) == 2  // constexpr in C++14
37227825Stheraven
38227825Stheraven    // allocator-extended constructors
39227825Stheraven    template <class Alloc>
40227825Stheraven        tuple(allocator_arg_t, const Alloc& a);
41227825Stheraven    template <class Alloc>
42227825Stheraven        tuple(allocator_arg_t, const Alloc& a, const T&...);
43227825Stheraven    template <class Alloc, class... U>
44227825Stheraven        tuple(allocator_arg_t, const Alloc& a, U&&...);
45227825Stheraven    template <class Alloc>
46227825Stheraven        tuple(allocator_arg_t, const Alloc& a, const tuple&);
47227825Stheraven    template <class Alloc>
48227825Stheraven        tuple(allocator_arg_t, const Alloc& a, tuple&&);
49227825Stheraven    template <class Alloc, class... U>
50227825Stheraven        tuple(allocator_arg_t, const Alloc& a, const tuple<U...>&);
51227825Stheraven    template <class Alloc, class... U>
52227825Stheraven        tuple(allocator_arg_t, const Alloc& a, tuple<U...>&&);
53227825Stheraven    template <class Alloc, class U1, class U2>
54227825Stheraven        tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&);
55227825Stheraven    template <class Alloc, class U1, class U2>
56227825Stheraven        tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&);
57227825Stheraven
58227825Stheraven    tuple& operator=(const tuple&);
59227825Stheraven    tuple&
60227825Stheraven        operator=(tuple&&) noexcept(AND(is_nothrow_move_assignable<T>::value ...));
61227825Stheraven    template <class... U>
62227825Stheraven        tuple& operator=(const tuple<U...>&);
63227825Stheraven    template <class... U>
64227825Stheraven        tuple& operator=(tuple<U...>&&);
65227825Stheraven    template <class U1, class U2>
66227825Stheraven        tuple& operator=(const pair<U1, U2>&); // iff sizeof...(T) == 2
67227825Stheraven    template <class U1, class U2>
68227825Stheraven        tuple& operator=(pair<U1, U2>&&); //iffsizeof...(T) == 2
69227825Stheraven
70227825Stheraven    void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...));
71227825Stheraven};
72227825Stheraven
73227825Stheravenconst unspecified ignore;
74227825Stheraven
75261272Sdimtemplate <class... T> tuple<V...>  make_tuple(T&&...); // constexpr in C++14
76261272Sdimtemplate <class... T> tuple<ATypes...> forward_as_tuple(T&&...) noexcept; // constexpr in C++14
77276792Sdimtemplate <class... T> tuple<T&...> tie(T&...) noexcept; // constexpr in C++14
78261272Sdimtemplate <class... Tuples> tuple<CTypes...> tuple_cat(Tuples&&... tpls); // constexpr in C++14
79227825Stheraven  
80227825Stheraven// 20.4.1.4, tuple helper classes:
81227825Stheraventemplate <class T> class tuple_size; // undefined
82227825Stheraventemplate <class... T> class tuple_size<tuple<T...>>;
83300770Sdimtemplate <size_t I, class T> class tuple_element; // undefined
84300770Sdimtemplate <size_t I, class... T> class tuple_element<I, tuple<T...>>;
85300770Sdimtemplate <size_t I, class T>
86300770Sdim  using tuple_element_t = typename tuple_element <I, T>::type; // C++14
87227825Stheraven
88227825Stheraven// 20.4.1.5, element access:
89300770Sdimtemplate <size_t I, class... T>
90227825Stheraven    typename tuple_element<I, tuple<T...>>::type&
91261272Sdim    get(tuple<T...>&) noexcept; // constexpr in C++14
92300770Sdimtemplate <size_t I, class... T>
93300770Sdim    const typename tuple_element<I, tuple<T...>>::type&
94261272Sdim    get(const tuple<T...>&) noexcept; // constexpr in C++14
95300770Sdimtemplate <size_t I, class... T>
96227825Stheraven    typename tuple_element<I, tuple<T...>>::type&&
97261272Sdim    get(tuple<T...>&&) noexcept; // constexpr in C++14
98300770Sdimtemplate <size_t I, class... T>
99300770Sdim    const typename tuple_element<I, tuple<T...>>::type&&
100300770Sdim    get(const tuple<T...>&&) noexcept; // constexpr in C++14
101227825Stheraven
102261272Sdimtemplate <class T1, class... T>
103261272Sdim    constexpr T1& get(tuple<T...>&) noexcept;  // C++14
104261272Sdimtemplate <class T1, class... T>
105300770Sdim    constexpr const T1& get(const tuple<T...>&) noexcept;   // C++14
106261272Sdimtemplate <class T1, class... T>
107261272Sdim    constexpr T1&& get(tuple<T...>&&) noexcept;   // C++14
108300770Sdimtemplate <class T1, class... T>
109300770Sdim    constexpr const T1&& get(const tuple<T...>&&) noexcept;   // C++14
110261272Sdim
111227825Stheraven// 20.4.1.6, relational operators:
112261272Sdimtemplate<class... T, class... U> bool operator==(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
113261272Sdimtemplate<class... T, class... U> bool operator<(const tuple<T...>&, const tuple<U...>&);  // constexpr in C++14
114261272Sdimtemplate<class... T, class... U> bool operator!=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
115261272Sdimtemplate<class... T, class... U> bool operator>(const tuple<T...>&, const tuple<U...>&);  // constexpr in C++14
116261272Sdimtemplate<class... T, class... U> bool operator<=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
117261272Sdimtemplate<class... T, class... U> bool operator>=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
118227825Stheraven
119227825Stheraventemplate <class... Types, class Alloc>
120227825Stheraven  struct uses_allocator<tuple<Types...>, Alloc>;
121227825Stheraven
122227825Stheraventemplate <class... Types>
123227825Stheraven  void
124227825Stheraven  swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(noexcept(x.swap(y)));
125227825Stheraven
126227825Stheraven}  // std
127227825Stheraven
128227825Stheraven*/
129227825Stheraven
130227825Stheraven#include <__config>
131227825Stheraven#include <__tuple>
132227825Stheraven#include <cstddef>
133227825Stheraven#include <type_traits>
134232924Stheraven#include <__functional_base>
135232924Stheraven#include <utility>
136227825Stheraven
137227825Stheraven#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
138227825Stheraven#pragma GCC system_header
139227825Stheraven#endif
140227825Stheraven
141227825Stheraven_LIBCPP_BEGIN_NAMESPACE_STD
142227825Stheraven
143227825Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS
144227825Stheraven
145227825Stheraven// tuple_size
146227825Stheraven
147227825Stheraventemplate <class ..._Tp>
148261272Sdimclass _LIBCPP_TYPE_VIS_ONLY tuple_size<tuple<_Tp...> >
149227825Stheraven    : public integral_constant<size_t, sizeof...(_Tp)>
150227825Stheraven{
151227825Stheraven};
152227825Stheraven
153227825Stheraven// tuple_element
154227825Stheraven
155227825Stheraventemplate <size_t _Ip, class ..._Tp>
156261272Sdimclass _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, tuple<_Tp...> >
157227825Stheraven{
158227825Stheravenpublic:
159227825Stheraven    typedef typename tuple_element<_Ip, __tuple_types<_Tp...> >::type type;
160227825Stheraven};
161227825Stheraven
162276792Sdim#if _LIBCPP_STD_VER > 11
163276792Sdimtemplate <size_t _Ip, class ..._Tp>
164276792Sdimusing tuple_element_t = typename tuple_element <_Ip, _Tp...>::type;
165276792Sdim#endif
166276792Sdim
167227825Stheraven// __tuple_leaf
168227825Stheraven
169288943Sdimtemplate <size_t _Ip, class _Hp,
170288943Sdim          bool=is_empty<_Hp>::value && !__libcpp_is_final<_Hp>::value
171232924Stheraven         >
172227825Stheravenclass __tuple_leaf;
173227825Stheraven
174227825Stheraventemplate <size_t _Ip, class _Hp, bool _Ep>
175227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
176227825Stheravenvoid swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y)
177227825Stheraven    _NOEXCEPT_(__is_nothrow_swappable<_Hp>::value)
178227825Stheraven{
179227825Stheraven    swap(__x.get(), __y.get());
180227825Stheraven}
181227825Stheraven
182227825Stheraventemplate <size_t _Ip, class _Hp, bool>
183227825Stheravenclass __tuple_leaf
184227825Stheraven{
185227825Stheraven    _Hp value;
186227825Stheraven
187227825Stheraven    __tuple_leaf& operator=(const __tuple_leaf&);
188227825Stheravenpublic:
189241900Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __tuple_leaf()
190241900Sdim             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) : value()
191227825Stheraven       {static_assert(!is_reference<_Hp>::value,
192227825Stheraven              "Attempted to default construct a reference element in a tuple");}
193227825Stheraven
194227825Stheraven    template <class _Alloc>
195227825Stheraven        _LIBCPP_INLINE_VISIBILITY
196227825Stheraven        __tuple_leaf(integral_constant<int, 0>, const _Alloc&)
197227825Stheraven            : value()
198227825Stheraven        {static_assert(!is_reference<_Hp>::value,
199227825Stheraven              "Attempted to default construct a reference element in a tuple");}
200227825Stheraven
201227825Stheraven    template <class _Alloc>
202227825Stheraven        _LIBCPP_INLINE_VISIBILITY
203227825Stheraven        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
204227825Stheraven            : value(allocator_arg_t(), __a)
205227825Stheraven        {static_assert(!is_reference<_Hp>::value,
206227825Stheraven              "Attempted to default construct a reference element in a tuple");}
207227825Stheraven
208227825Stheraven    template <class _Alloc>
209227825Stheraven        _LIBCPP_INLINE_VISIBILITY
210227825Stheraven        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
211227825Stheraven            : value(__a)
212227825Stheraven        {static_assert(!is_reference<_Hp>::value,
213227825Stheraven              "Attempted to default construct a reference element in a tuple");}
214227825Stheraven
215227825Stheraven    template <class _Tp,
216276792Sdim              class = typename enable_if<
217276792Sdim                  __lazy_and<
218276792Sdim                      __lazy_not<is_same<typename decay<_Tp>::type, __tuple_leaf>>
219276792Sdim                    , is_constructible<_Hp, _Tp>
220276792Sdim                    >::value
221276792Sdim                >::type
222276792Sdim            >
223261272Sdim        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
224241900Sdim        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
225227825Stheraven            : value(_VSTD::forward<_Tp>(__t))
226227825Stheraven        {static_assert(!is_reference<_Hp>::value ||
227232924Stheraven                       (is_lvalue_reference<_Hp>::value &&
228227825Stheraven                        (is_lvalue_reference<_Tp>::value ||
229227825Stheraven                         is_same<typename remove_reference<_Tp>::type,
230227825Stheraven                                 reference_wrapper<
231227825Stheraven                                    typename remove_reference<_Hp>::type
232227825Stheraven                                 >
233232924Stheraven                                >::value)) ||
234227825Stheraven                        (is_rvalue_reference<_Hp>::value &&
235227825Stheraven                         !is_lvalue_reference<_Tp>::value),
236227825Stheraven       "Attempted to construct a reference element in a tuple with an rvalue");}
237227825Stheraven
238227825Stheraven    template <class _Tp, class _Alloc>
239227825Stheraven        _LIBCPP_INLINE_VISIBILITY
240227825Stheraven        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
241227825Stheraven            : value(_VSTD::forward<_Tp>(__t))
242227825Stheraven        {static_assert(!is_lvalue_reference<_Hp>::value ||
243232924Stheraven                       (is_lvalue_reference<_Hp>::value &&
244227825Stheraven                        (is_lvalue_reference<_Tp>::value ||
245227825Stheraven                         is_same<typename remove_reference<_Tp>::type,
246227825Stheraven                                 reference_wrapper<
247227825Stheraven                                    typename remove_reference<_Hp>::type
248227825Stheraven                                 >
249232924Stheraven                                >::value)),
250227825Stheraven       "Attempted to construct a reference element in a tuple with an rvalue");}
251227825Stheraven
252227825Stheraven    template <class _Tp, class _Alloc>
253227825Stheraven        _LIBCPP_INLINE_VISIBILITY
254227825Stheraven        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
255227825Stheraven            : value(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t))
256227825Stheraven        {static_assert(!is_lvalue_reference<_Hp>::value ||
257232924Stheraven                       (is_lvalue_reference<_Hp>::value &&
258227825Stheraven                        (is_lvalue_reference<_Tp>::value ||
259227825Stheraven                         is_same<typename remove_reference<_Tp>::type,
260227825Stheraven                                 reference_wrapper<
261227825Stheraven                                    typename remove_reference<_Hp>::type
262227825Stheraven                                 >
263232924Stheraven                                >::value)),
264227825Stheraven       "Attempted to construct a reference element in a tuple with an rvalue");}
265227825Stheraven
266227825Stheraven    template <class _Tp, class _Alloc>
267227825Stheraven        _LIBCPP_INLINE_VISIBILITY
268227825Stheraven        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
269227825Stheraven            : value(_VSTD::forward<_Tp>(__t), __a)
270227825Stheraven        {static_assert(!is_lvalue_reference<_Hp>::value ||
271232924Stheraven                       (is_lvalue_reference<_Hp>::value &&
272227825Stheraven                        (is_lvalue_reference<_Tp>::value ||
273227825Stheraven                         is_same<typename remove_reference<_Tp>::type,
274227825Stheraven                                 reference_wrapper<
275227825Stheraven                                    typename remove_reference<_Hp>::type
276227825Stheraven                                 >
277232924Stheraven                                >::value)),
278227825Stheraven       "Attempted to construct a reference element in a tuple with an rvalue");}
279227825Stheraven
280276792Sdim    __tuple_leaf(const __tuple_leaf& __t) = default;
281276792Sdim    __tuple_leaf(__tuple_leaf&& __t) = default;
282227825Stheraven
283227825Stheraven    template <class _Tp>
284227825Stheraven        _LIBCPP_INLINE_VISIBILITY
285227825Stheraven        __tuple_leaf&
286241900Sdim        operator=(_Tp&& __t) _NOEXCEPT_((is_nothrow_assignable<_Hp&, _Tp>::value))
287227825Stheraven        {
288227825Stheraven            value = _VSTD::forward<_Tp>(__t);
289227825Stheraven            return *this;
290227825Stheraven        }
291227825Stheraven
292227825Stheraven    _LIBCPP_INLINE_VISIBILITY
293227825Stheraven    int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
294227825Stheraven    {
295227825Stheraven        _VSTD::swap(*this, __t);
296227825Stheraven        return 0;
297227825Stheraven    }
298227825Stheraven
299261272Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11       _Hp& get()       _NOEXCEPT {return value;}
300261272Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return value;}
301227825Stheraven};
302227825Stheraven
303227825Stheraventemplate <size_t _Ip, class _Hp>
304227825Stheravenclass __tuple_leaf<_Ip, _Hp, true>
305227825Stheraven    : private _Hp
306227825Stheraven{
307227825Stheraven
308227825Stheraven    __tuple_leaf& operator=(const __tuple_leaf&);
309227825Stheravenpublic:
310241900Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __tuple_leaf()
311241900Sdim             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) {}
312227825Stheraven
313227825Stheraven    template <class _Alloc>
314227825Stheraven        _LIBCPP_INLINE_VISIBILITY
315227825Stheraven        __tuple_leaf(integral_constant<int, 0>, const _Alloc&) {}
316227825Stheraven
317227825Stheraven    template <class _Alloc>
318227825Stheraven        _LIBCPP_INLINE_VISIBILITY
319227825Stheraven        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
320227825Stheraven            : _Hp(allocator_arg_t(), __a) {}
321227825Stheraven
322227825Stheraven    template <class _Alloc>
323227825Stheraven        _LIBCPP_INLINE_VISIBILITY
324227825Stheraven        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
325227825Stheraven            : _Hp(__a) {}
326227825Stheraven
327227825Stheraven    template <class _Tp,
328276792Sdim              class = typename enable_if<
329276792Sdim                  __lazy_and<
330276792Sdim                        __lazy_not<is_same<typename decay<_Tp>::type, __tuple_leaf>>
331276792Sdim                      , is_constructible<_Hp, _Tp>
332276792Sdim                    >::value
333276792Sdim                >::type
334276792Sdim            >
335261272Sdim        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
336241900Sdim        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
337227825Stheraven            : _Hp(_VSTD::forward<_Tp>(__t)) {}
338227825Stheraven
339227825Stheraven    template <class _Tp, class _Alloc>
340227825Stheraven        _LIBCPP_INLINE_VISIBILITY
341227825Stheraven        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
342227825Stheraven            : _Hp(_VSTD::forward<_Tp>(__t)) {}
343227825Stheraven
344227825Stheraven    template <class _Tp, class _Alloc>
345227825Stheraven        _LIBCPP_INLINE_VISIBILITY
346227825Stheraven        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
347227825Stheraven            : _Hp(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) {}
348227825Stheraven
349227825Stheraven    template <class _Tp, class _Alloc>
350227825Stheraven        _LIBCPP_INLINE_VISIBILITY
351227825Stheraven        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
352227825Stheraven            : _Hp(_VSTD::forward<_Tp>(__t), __a) {}
353227825Stheraven
354276792Sdim    __tuple_leaf(__tuple_leaf const &) = default;
355276792Sdim    __tuple_leaf(__tuple_leaf &&) = default;
356276792Sdim
357227825Stheraven    template <class _Tp>
358227825Stheraven        _LIBCPP_INLINE_VISIBILITY
359227825Stheraven        __tuple_leaf&
360241900Sdim        operator=(_Tp&& __t) _NOEXCEPT_((is_nothrow_assignable<_Hp&, _Tp>::value))
361227825Stheraven        {
362227825Stheraven            _Hp::operator=(_VSTD::forward<_Tp>(__t));
363227825Stheraven            return *this;
364227825Stheraven        }
365227825Stheraven
366227825Stheraven    _LIBCPP_INLINE_VISIBILITY
367227825Stheraven    int
368227825Stheraven    swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
369227825Stheraven    {
370227825Stheraven        _VSTD::swap(*this, __t);
371227825Stheraven        return 0;
372227825Stheraven    }
373227825Stheraven
374261272Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11       _Hp& get()       _NOEXCEPT {return static_cast<_Hp&>(*this);}
375261272Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return static_cast<const _Hp&>(*this);}
376227825Stheraven};
377227825Stheraven
378227825Stheraventemplate <class ..._Tp>
379227825Stheraven_LIBCPP_INLINE_VISIBILITY
380241900Sdimvoid __swallow(_Tp&&...) _NOEXCEPT {}
381227825Stheraven
382276792Sdimtemplate <bool ..._Pred>
383276792Sdimstruct __all
384276792Sdim    : is_same<__all<_Pred...>, __all<(_Pred, true)...>>
385276792Sdim{ };
386227825Stheraven
387276792Sdimtemplate <class _Tp>
388276792Sdimstruct __all_default_constructible;
389227825Stheraven
390276792Sdimtemplate <class ..._Tp>
391276792Sdimstruct __all_default_constructible<__tuple_types<_Tp...>>
392276792Sdim    : __all<is_default_constructible<_Tp>::value...>
393276792Sdim{ };
394227825Stheraven
395227825Stheraven// __tuple_impl
396227825Stheraven
397227825Stheraventemplate<class _Indx, class ..._Tp> struct __tuple_impl;
398227825Stheraven
399227825Stheraventemplate<size_t ..._Indx, class ..._Tp>
400227825Stheravenstruct __tuple_impl<__tuple_indices<_Indx...>, _Tp...>
401227825Stheraven    : public __tuple_leaf<_Indx, _Tp>...
402227825Stheraven{
403241900Sdim    _LIBCPP_INLINE_VISIBILITY
404241900Sdim    _LIBCPP_CONSTEXPR __tuple_impl()
405241900Sdim        _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
406241900Sdim
407227825Stheraven    template <size_t ..._Uf, class ..._Tf,
408227825Stheraven              size_t ..._Ul, class ..._Tl, class ..._Up>
409261272Sdim        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
410227825Stheraven        explicit
411227825Stheraven        __tuple_impl(__tuple_indices<_Uf...>, __tuple_types<_Tf...>,
412227825Stheraven                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
413241900Sdim                     _Up&&... __u)
414241900Sdim                     _NOEXCEPT_((__all<is_nothrow_constructible<_Tf, _Up>::value...>::value &&
415241900Sdim                                 __all<is_nothrow_default_constructible<_Tl>::value...>::value)) :
416227825Stheraven            __tuple_leaf<_Uf, _Tf>(_VSTD::forward<_Up>(__u))...,
417227825Stheraven            __tuple_leaf<_Ul, _Tl>()...
418227825Stheraven            {}
419227825Stheraven
420227825Stheraven    template <class _Alloc, size_t ..._Uf, class ..._Tf,
421227825Stheraven              size_t ..._Ul, class ..._Tl, class ..._Up>
422227825Stheraven        _LIBCPP_INLINE_VISIBILITY
423227825Stheraven        explicit
424227825Stheraven        __tuple_impl(allocator_arg_t, const _Alloc& __a,
425227825Stheraven                     __tuple_indices<_Uf...>, __tuple_types<_Tf...>,
426227825Stheraven                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
427227825Stheraven                     _Up&&... __u) :
428227825Stheraven            __tuple_leaf<_Uf, _Tf>(__uses_alloc_ctor<_Tf, _Alloc, _Up>(), __a,
429227825Stheraven            _VSTD::forward<_Up>(__u))...,
430227825Stheraven            __tuple_leaf<_Ul, _Tl>(__uses_alloc_ctor<_Tl, _Alloc>(), __a)...
431227825Stheraven            {}
432227825Stheraven
433227825Stheraven    template <class _Tuple,
434227825Stheraven              class = typename enable_if
435227825Stheraven                      <
436249989Sdim                         __tuple_constructible<_Tuple, tuple<_Tp...> >::value
437227825Stheraven                      >::type
438227825Stheraven             >
439261272Sdim        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
440241900Sdim        __tuple_impl(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_constructible<_Tp, typename tuple_element<_Indx,
441241900Sdim                                       typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))
442227825Stheraven            : __tuple_leaf<_Indx, _Tp>(_VSTD::forward<typename tuple_element<_Indx,
443227825Stheraven                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
444227825Stheraven            {}
445227825Stheraven
446227825Stheraven    template <class _Alloc, class _Tuple,
447227825Stheraven              class = typename enable_if
448227825Stheraven                      <
449227825Stheraven                         __tuple_convertible<_Tuple, tuple<_Tp...> >::value
450227825Stheraven                      >::type
451227825Stheraven             >
452227825Stheraven        _LIBCPP_INLINE_VISIBILITY
453227825Stheraven        __tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
454227825Stheraven            : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, typename tuple_element<_Indx,
455227825Stheraven                                       typename __make_tuple_types<_Tuple>::type>::type>(), __a,
456227825Stheraven                                       _VSTD::forward<typename tuple_element<_Indx,
457227825Stheraven                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
458227825Stheraven            {}
459227825Stheraven
460227825Stheraven    template <class _Tuple>
461227825Stheraven        _LIBCPP_INLINE_VISIBILITY
462227825Stheraven        typename enable_if
463227825Stheraven        <
464227825Stheraven            __tuple_assignable<_Tuple, tuple<_Tp...> >::value,
465227825Stheraven            __tuple_impl&
466227825Stheraven        >::type
467241900Sdim        operator=(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_assignable<_Tp&, typename tuple_element<_Indx,
468241900Sdim                                       typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))
469227825Stheraven        {
470227825Stheraven            __swallow(__tuple_leaf<_Indx, _Tp>::operator=(_VSTD::forward<typename tuple_element<_Indx,
471227825Stheraven                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...);
472227825Stheraven            return *this;
473227825Stheraven        }
474227825Stheraven
475261272Sdim    __tuple_impl(const __tuple_impl&) = default;
476261272Sdim    __tuple_impl(__tuple_impl&&) = default;
477232924Stheraven
478227825Stheraven    _LIBCPP_INLINE_VISIBILITY
479261272Sdim    __tuple_impl&
480261272Sdim    operator=(const __tuple_impl& __t) _NOEXCEPT_((__all<is_nothrow_copy_assignable<_Tp>::value...>::value))
481261272Sdim    {
482261272Sdim        __swallow(__tuple_leaf<_Indx, _Tp>::operator=(static_cast<const __tuple_leaf<_Indx, _Tp>&>(__t).get())...);
483261272Sdim        return *this;
484261272Sdim    }
485261272Sdim
486261272Sdim    _LIBCPP_INLINE_VISIBILITY
487261272Sdim    __tuple_impl&
488261272Sdim    operator=(__tuple_impl&& __t) _NOEXCEPT_((__all<is_nothrow_move_assignable<_Tp>::value...>::value))
489261272Sdim    {
490261272Sdim        __swallow(__tuple_leaf<_Indx, _Tp>::operator=(_VSTD::forward<_Tp>(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t).get()))...);
491261272Sdim        return *this;
492261272Sdim    }
493261272Sdim
494261272Sdim    _LIBCPP_INLINE_VISIBILITY
495227825Stheraven    void swap(__tuple_impl& __t)
496227825Stheraven        _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
497227825Stheraven    {
498227825Stheraven        __swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...);
499227825Stheraven    }
500227825Stheraven};
501227825Stheraven
502227825Stheraventemplate <class ..._Tp>
503261272Sdimclass _LIBCPP_TYPE_VIS_ONLY tuple
504227825Stheraven{
505227825Stheraven    typedef __tuple_impl<typename __make_tuple_indices<sizeof...(_Tp)>::type, _Tp...> base;
506227825Stheraven
507227825Stheraven    base base_;
508227825Stheraven
509261272Sdim    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
510232924Stheraven        typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT;
511261272Sdim    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
512232924Stheraven        const typename tuple_element<_Jp, tuple<_Up...> >::type& get(const tuple<_Up...>&) _NOEXCEPT;
513261272Sdim    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
514232924Stheraven        typename tuple_element<_Jp, tuple<_Up...> >::type&& get(tuple<_Up...>&&) _NOEXCEPT;
515300770Sdim    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
516300770Sdim        const typename tuple_element<_Jp, tuple<_Up...> >::type&& get(const tuple<_Up...>&&) _NOEXCEPT;
517227825Stheravenpublic:
518227825Stheraven
519288943Sdim    template <bool _Dummy = true, class = typename enable_if<
520288943Sdim        __all<__dependent_type<is_default_constructible<_Tp>, _Dummy>::value...>::value
521276792Sdim    >::type>
522227825Stheraven    _LIBCPP_INLINE_VISIBILITY
523241900Sdim    _LIBCPP_CONSTEXPR tuple()
524241900Sdim        _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
525241900Sdim
526261272Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
527241900Sdim    explicit tuple(const _Tp& ... __t) _NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value)) 
528227825Stheraven        : base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
529227825Stheraven                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
530227825Stheraven                typename __make_tuple_indices<0>::type(),
531227825Stheraven                typename __make_tuple_types<tuple, 0>::type(),
532227825Stheraven                __t...
533227825Stheraven               ) {}
534227825Stheraven
535227825Stheraven    template <class _Alloc>
536227825Stheraven      _LIBCPP_INLINE_VISIBILITY
537227825Stheraven      tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
538227825Stheraven        : base_(allocator_arg_t(), __a,
539227825Stheraven                typename __make_tuple_indices<sizeof...(_Tp)>::type(),
540227825Stheraven                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
541227825Stheraven                typename __make_tuple_indices<0>::type(),
542227825Stheraven                typename __make_tuple_types<tuple, 0>::type(),
543227825Stheraven                __t...
544227825Stheraven               ) {}
545227825Stheraven
546227825Stheraven    template <class ..._Up,
547234959Stheraven              typename enable_if
548227825Stheraven                      <
549227825Stheraven                         sizeof...(_Up) <= sizeof...(_Tp) &&
550227825Stheraven                         __tuple_convertible
551227825Stheraven                         <
552227825Stheraven                            tuple<_Up...>,
553227825Stheraven                            typename __make_tuple_types<tuple,
554227825Stheraven                                     sizeof...(_Up) < sizeof...(_Tp) ?
555227825Stheraven                                        sizeof...(_Up) :
556227825Stheraven                                        sizeof...(_Tp)>::type
557276792Sdim                         >::value &&
558276792Sdim                         __all_default_constructible<
559276792Sdim                            typename __make_tuple_types<tuple, sizeof...(_Tp),
560276792Sdim                                sizeof...(_Up) < sizeof...(_Tp) ?
561276792Sdim                                    sizeof...(_Up) :
562276792Sdim                                    sizeof...(_Tp)>::type
563234959Stheraven                         >::value,
564234959Stheraven                         bool
565234959Stheraven                      >::type = false
566227825Stheraven             >
567261272Sdim        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
568234959Stheraven        tuple(_Up&&... __u)
569241900Sdim            _NOEXCEPT_((
570276792Sdim                is_nothrow_constructible<base,
571241900Sdim                    typename __make_tuple_indices<sizeof...(_Up)>::type,
572241900Sdim                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type,
573241900Sdim                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type,
574241900Sdim                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type,
575241900Sdim                    _Up...
576241900Sdim                >::value
577241900Sdim            ))
578234959Stheraven            : base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
579234959Stheraven                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
580234959Stheraven                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
581234959Stheraven                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
582234959Stheraven                    _VSTD::forward<_Up>(__u)...) {}
583234959Stheraven
584234959Stheraven    template <class ..._Up,
585234959Stheraven              typename enable_if
586234959Stheraven                      <
587234959Stheraven                         sizeof...(_Up) <= sizeof...(_Tp) &&
588234959Stheraven                         __tuple_constructible
589234959Stheraven                         <
590234959Stheraven                            tuple<_Up...>,
591234959Stheraven                            typename __make_tuple_types<tuple,
592234959Stheraven                                     sizeof...(_Up) < sizeof...(_Tp) ?
593234959Stheraven                                        sizeof...(_Up) :
594234959Stheraven                                        sizeof...(_Tp)>::type
595234959Stheraven                         >::value &&
596234959Stheraven                         !__tuple_convertible
597234959Stheraven                         <
598234959Stheraven                            tuple<_Up...>,
599234959Stheraven                            typename __make_tuple_types<tuple,
600234959Stheraven                                     sizeof...(_Up) < sizeof...(_Tp) ?
601234959Stheraven                                        sizeof...(_Up) :
602234959Stheraven                                        sizeof...(_Tp)>::type
603276792Sdim                         >::value &&
604276792Sdim                         __all_default_constructible<
605276792Sdim                            typename __make_tuple_types<tuple, sizeof...(_Tp),
606276792Sdim                                sizeof...(_Up) < sizeof...(_Tp) ?
607276792Sdim                                    sizeof...(_Up) :
608276792Sdim                                    sizeof...(_Tp)>::type
609234959Stheraven                         >::value,
610234959Stheraven                         bool
611234959Stheraven                      >::type =false
612234959Stheraven             >
613261272Sdim        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
614227825Stheraven        explicit
615227825Stheraven        tuple(_Up&&... __u)
616241900Sdim            _NOEXCEPT_((
617276792Sdim                is_nothrow_constructible<base,
618241900Sdim                    typename __make_tuple_indices<sizeof...(_Up)>::type,
619241900Sdim                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type,
620241900Sdim                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type,
621241900Sdim                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type,
622241900Sdim                    _Up...
623241900Sdim                >::value
624241900Sdim            ))
625227825Stheraven            : base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
626227825Stheraven                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
627227825Stheraven                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
628227825Stheraven                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
629227825Stheraven                    _VSTD::forward<_Up>(__u)...) {}
630227825Stheraven
631227825Stheraven    template <class _Alloc, class ..._Up,
632227825Stheraven              class = typename enable_if
633227825Stheraven                      <
634227825Stheraven                         sizeof...(_Up) <= sizeof...(_Tp) &&
635227825Stheraven                         __tuple_convertible
636227825Stheraven                         <
637227825Stheraven                            tuple<_Up...>,
638227825Stheraven                            typename __make_tuple_types<tuple,
639227825Stheraven                                     sizeof...(_Up) < sizeof...(_Tp) ?
640227825Stheraven                                        sizeof...(_Up) :
641227825Stheraven                                        sizeof...(_Tp)>::type
642276792Sdim                         >::value &&
643276792Sdim                         __all_default_constructible<
644276792Sdim                            typename __make_tuple_types<tuple, sizeof...(_Tp),
645276792Sdim                                sizeof...(_Up) < sizeof...(_Tp) ?
646276792Sdim                                    sizeof...(_Up) :
647276792Sdim                                    sizeof...(_Tp)>::type
648227825Stheraven                         >::value
649227825Stheraven                      >::type
650227825Stheraven             >
651227825Stheraven        _LIBCPP_INLINE_VISIBILITY
652227825Stheraven        tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
653227825Stheraven            : base_(allocator_arg_t(), __a,
654227825Stheraven                    typename __make_tuple_indices<sizeof...(_Up)>::type(),
655227825Stheraven                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
656227825Stheraven                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
657227825Stheraven                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
658227825Stheraven                    _VSTD::forward<_Up>(__u)...) {}
659227825Stheraven
660227825Stheraven    template <class _Tuple,
661234959Stheraven              typename enable_if
662227825Stheraven                      <
663234959Stheraven                         __tuple_convertible<_Tuple, tuple>::value,
664234959Stheraven                         bool
665234959Stheraven                      >::type = false
666227825Stheraven             >
667261272Sdim        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
668241900Sdim        tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<base, _Tuple>::value))
669227825Stheraven            : base_(_VSTD::forward<_Tuple>(__t)) {}
670227825Stheraven
671234959Stheraven    template <class _Tuple,
672234959Stheraven              typename enable_if
673234959Stheraven                      <
674234959Stheraven                         __tuple_constructible<_Tuple, tuple>::value &&
675234959Stheraven                         !__tuple_convertible<_Tuple, tuple>::value,
676234959Stheraven                         bool
677234959Stheraven                      >::type = false
678234959Stheraven             >
679261272Sdim        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
680234959Stheraven        explicit
681241900Sdim        tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<base, _Tuple>::value))
682234959Stheraven            : base_(_VSTD::forward<_Tuple>(__t)) {}
683234959Stheraven
684227825Stheraven    template <class _Alloc, class _Tuple,
685227825Stheraven              class = typename enable_if
686227825Stheraven                      <
687227825Stheraven                         __tuple_convertible<_Tuple, tuple>::value
688227825Stheraven                      >::type
689227825Stheraven             >
690227825Stheraven        _LIBCPP_INLINE_VISIBILITY
691227825Stheraven        tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
692227825Stheraven            : base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {}
693227825Stheraven
694227825Stheraven    template <class _Tuple,
695227825Stheraven              class = typename enable_if
696227825Stheraven                      <
697227825Stheraven                         __tuple_assignable<_Tuple, tuple>::value
698227825Stheraven                      >::type
699227825Stheraven             >
700227825Stheraven        _LIBCPP_INLINE_VISIBILITY
701227825Stheraven        tuple&
702241900Sdim        operator=(_Tuple&& __t) _NOEXCEPT_((is_nothrow_assignable<base&, _Tuple>::value))
703227825Stheraven        {
704227825Stheraven            base_.operator=(_VSTD::forward<_Tuple>(__t));
705227825Stheraven            return *this;
706227825Stheraven        }
707227825Stheraven
708227825Stheraven    _LIBCPP_INLINE_VISIBILITY
709227825Stheraven    void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
710227825Stheraven        {base_.swap(__t.base_);}
711227825Stheraven};
712227825Stheraven
713227825Stheraventemplate <>
714261272Sdimclass _LIBCPP_TYPE_VIS_ONLY tuple<>
715227825Stheraven{
716227825Stheravenpublic:
717227825Stheraven    _LIBCPP_INLINE_VISIBILITY
718241900Sdim    _LIBCPP_CONSTEXPR tuple() _NOEXCEPT {}
719227825Stheraven    template <class _Alloc>
720227825Stheraven    _LIBCPP_INLINE_VISIBILITY
721241900Sdim        tuple(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
722227825Stheraven    template <class _Alloc>
723227825Stheraven    _LIBCPP_INLINE_VISIBILITY
724241900Sdim        tuple(allocator_arg_t, const _Alloc&, const tuple&) _NOEXCEPT {}
725232924Stheraven    template <class _Up>
726227825Stheraven    _LIBCPP_INLINE_VISIBILITY
727241900Sdim        tuple(array<_Up, 0>) _NOEXCEPT {}
728232924Stheraven    template <class _Alloc, class _Up>
729227825Stheraven    _LIBCPP_INLINE_VISIBILITY
730241900Sdim        tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) _NOEXCEPT {}
731227825Stheraven    _LIBCPP_INLINE_VISIBILITY
732227825Stheraven    void swap(tuple&) _NOEXCEPT {}
733227825Stheraven};
734227825Stheraven
735227825Stheraventemplate <class ..._Tp>
736227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
737227825Stheraventypename enable_if
738227825Stheraven<
739227825Stheraven    __all<__is_swappable<_Tp>::value...>::value,
740227825Stheraven    void
741227825Stheraven>::type
742227825Stheravenswap(tuple<_Tp...>& __t, tuple<_Tp...>& __u)
743227825Stheraven                 _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
744227825Stheraven    {__t.swap(__u);}
745227825Stheraven
746227825Stheraven// get
747227825Stheraven
748227825Stheraventemplate <size_t _Ip, class ..._Tp>
749261272Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
750227825Stheraventypename tuple_element<_Ip, tuple<_Tp...> >::type&
751232924Stheravenget(tuple<_Tp...>& __t) _NOEXCEPT
752227825Stheraven{
753227825Stheraven    typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
754227825Stheraven    return static_cast<__tuple_leaf<_Ip, type>&>(__t.base_).get();
755227825Stheraven}
756227825Stheraven
757227825Stheraventemplate <size_t _Ip, class ..._Tp>
758261272Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
759227825Stheravenconst typename tuple_element<_Ip, tuple<_Tp...> >::type&
760232924Stheravenget(const tuple<_Tp...>& __t) _NOEXCEPT
761227825Stheraven{
762227825Stheraven    typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
763227825Stheraven    return static_cast<const __tuple_leaf<_Ip, type>&>(__t.base_).get();
764227825Stheraven}
765227825Stheraven
766227825Stheraventemplate <size_t _Ip, class ..._Tp>
767261272Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
768227825Stheraventypename tuple_element<_Ip, tuple<_Tp...> >::type&&
769232924Stheravenget(tuple<_Tp...>&& __t) _NOEXCEPT
770227825Stheraven{
771227825Stheraven    typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
772227825Stheraven    return static_cast<type&&>(
773227825Stheraven             static_cast<__tuple_leaf<_Ip, type>&&>(__t.base_).get());
774227825Stheraven}
775227825Stheraven
776300770Sdimtemplate <size_t _Ip, class ..._Tp>
777300770Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
778300770Sdimconst typename tuple_element<_Ip, tuple<_Tp...> >::type&&
779300770Sdimget(const tuple<_Tp...>&& __t) _NOEXCEPT
780300770Sdim{
781300770Sdim    typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
782300770Sdim    return static_cast<const type&&>(
783300770Sdim             static_cast<const __tuple_leaf<_Ip, type>&&>(__t.base_).get());
784300770Sdim}
785300770Sdim
786261272Sdim#if _LIBCPP_STD_VER > 11
787261272Sdim// get by type
788261272Sdimtemplate <typename _T1, size_t _Idx, typename... _Args>
789261272Sdimstruct __find_exactly_one_t_helper;
790261272Sdim
791261272Sdim// -- find exactly one
792261272Sdimtemplate <typename _T1, size_t _Idx, typename... _Args>
793261272Sdimstruct __find_exactly_one_t_checker {
794261272Sdim    static constexpr size_t value = _Idx;
795261272Sdim//  Check the rest of the list to make sure there's only one
796261272Sdim    static_assert ( __find_exactly_one_t_helper<_T1, 0, _Args...>::value == -1, "type can only occur once in type list" );
797261272Sdim    };
798261272Sdim
799261272Sdim
800261272Sdimtemplate <typename _T1, size_t _Idx>
801261272Sdimstruct __find_exactly_one_t_helper <_T1, _Idx> {
802261272Sdim    static constexpr size_t value = -1;
803261272Sdim    };
804261272Sdim
805261272Sdimtemplate <typename _T1, size_t _Idx, typename _Head, typename... _Args>
806261272Sdimstruct __find_exactly_one_t_helper <_T1, _Idx, _Head, _Args...> {
807261272Sdim    static constexpr size_t value =
808261272Sdim        std::conditional<
809261272Sdim            std::is_same<_T1, _Head>::value,
810261272Sdim            __find_exactly_one_t_checker<_T1, _Idx,   _Args...>,
811261272Sdim            __find_exactly_one_t_helper <_T1, _Idx+1, _Args...>
812261272Sdim        >::type::value;
813261272Sdim    };
814261272Sdim
815261272Sdimtemplate <typename _T1, typename... _Args>
816261272Sdimstruct __find_exactly_one_t {
817261272Sdim    static constexpr size_t value = __find_exactly_one_t_helper<_T1, 0, _Args...>::value;
818261272Sdim    static_assert ( value != -1, "type not found in type list" );
819261272Sdim    };
820261272Sdim
821261272Sdimtemplate <class _T1, class... _Args>
822261272Sdiminline _LIBCPP_INLINE_VISIBILITY
823261272Sdimconstexpr _T1& get(tuple<_Args...>& __tup) noexcept
824261272Sdim{
825261272Sdim    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
826261272Sdim}
827261272Sdim
828261272Sdimtemplate <class _T1, class... _Args>
829261272Sdiminline _LIBCPP_INLINE_VISIBILITY
830261272Sdimconstexpr _T1 const& get(tuple<_Args...> const& __tup) noexcept
831261272Sdim{
832261272Sdim    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
833261272Sdim}
834261272Sdim
835261272Sdimtemplate <class _T1, class... _Args>
836261272Sdiminline _LIBCPP_INLINE_VISIBILITY
837261272Sdimconstexpr _T1&& get(tuple<_Args...>&& __tup) noexcept
838261272Sdim{
839261272Sdim    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));
840261272Sdim}
841261272Sdim
842300770Sdimtemplate <class _T1, class... _Args>
843300770Sdiminline _LIBCPP_INLINE_VISIBILITY
844300770Sdimconstexpr _T1 const&& get(tuple<_Args...> const&& __tup) noexcept
845300770Sdim{
846300770Sdim    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));
847300770Sdim}
848300770Sdim
849261272Sdim#endif
850261272Sdim
851227825Stheraven// tie
852227825Stheraven
853227825Stheraventemplate <class ..._Tp>
854276792Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
855227825Stheraventuple<_Tp&...>
856241900Sdimtie(_Tp&... __t) _NOEXCEPT
857227825Stheraven{
858227825Stheraven    return tuple<_Tp&...>(__t...);
859227825Stheraven}
860227825Stheraven
861227825Stheraventemplate <class _Up>
862227825Stheravenstruct __ignore_t
863227825Stheraven{
864227825Stheraven    template <class _Tp>
865227825Stheraven        _LIBCPP_INLINE_VISIBILITY
866227825Stheraven        const __ignore_t& operator=(_Tp&&) const {return *this;}
867227825Stheraven};
868227825Stheraven
869227825Stheravennamespace { const __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>(); }
870227825Stheraven
871227825Stheraventemplate <class _Tp>
872276792Sdimstruct __make_tuple_return_impl
873227825Stheraven{
874227825Stheraven    typedef _Tp type;
875227825Stheraven};
876227825Stheraven
877227825Stheraventemplate <class _Tp>
878276792Sdimstruct __make_tuple_return_impl<reference_wrapper<_Tp> >
879227825Stheraven{
880227825Stheraven    typedef _Tp& type;
881227825Stheraven};
882227825Stheraven
883227825Stheraventemplate <class _Tp>
884227825Stheravenstruct __make_tuple_return
885227825Stheraven{
886276792Sdim    typedef typename __make_tuple_return_impl<typename decay<_Tp>::type>::type type;
887227825Stheraven};
888227825Stheraven
889227825Stheraventemplate <class... _Tp>
890261272Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
891227825Stheraventuple<typename __make_tuple_return<_Tp>::type...>
892227825Stheravenmake_tuple(_Tp&&... __t)
893227825Stheraven{
894227825Stheraven    return tuple<typename __make_tuple_return<_Tp>::type...>(_VSTD::forward<_Tp>(__t)...);
895227825Stheraven}
896227825Stheraven
897227825Stheraventemplate <class... _Tp>
898261272Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
899227825Stheraventuple<_Tp&&...>
900241900Sdimforward_as_tuple(_Tp&&... __t) _NOEXCEPT
901227825Stheraven{
902227825Stheraven    return tuple<_Tp&&...>(_VSTD::forward<_Tp>(__t)...);
903227825Stheraven}
904227825Stheraven
905232924Stheraventemplate <size_t _Ip>
906227825Stheravenstruct __tuple_equal
907227825Stheraven{
908227825Stheraven    template <class _Tp, class _Up>
909261272Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
910227825Stheraven    bool operator()(const _Tp& __x, const _Up& __y)
911227825Stheraven    {
912276792Sdim        return __tuple_equal<_Ip - 1>()(__x, __y) && _VSTD::get<_Ip-1>(__x) == _VSTD::get<_Ip-1>(__y);
913227825Stheraven    }
914227825Stheraven};
915227825Stheraven
916227825Stheraventemplate <>
917227825Stheravenstruct __tuple_equal<0>
918227825Stheraven{
919227825Stheraven    template <class _Tp, class _Up>
920261272Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
921227825Stheraven    bool operator()(const _Tp&, const _Up&)
922227825Stheraven    {
923227825Stheraven        return true;
924227825Stheraven    }
925227825Stheraven};
926227825Stheraven
927227825Stheraventemplate <class ..._Tp, class ..._Up>
928261272Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
929227825Stheravenbool
930227825Stheravenoperator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
931227825Stheraven{
932227825Stheraven    return __tuple_equal<sizeof...(_Tp)>()(__x, __y);
933227825Stheraven}
934227825Stheraven
935227825Stheraventemplate <class ..._Tp, class ..._Up>
936261272Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
937227825Stheravenbool
938227825Stheravenoperator!=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
939227825Stheraven{
940227825Stheraven    return !(__x == __y);
941227825Stheraven}
942227825Stheraven
943232924Stheraventemplate <size_t _Ip>
944227825Stheravenstruct __tuple_less
945227825Stheraven{
946227825Stheraven    template <class _Tp, class _Up>
947261272Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
948227825Stheraven    bool operator()(const _Tp& __x, const _Up& __y)
949227825Stheraven    {
950288943Sdim        const size_t __idx = tuple_size<_Tp>::value - _Ip;
951288943Sdim        if (_VSTD::get<__idx>(__x) < _VSTD::get<__idx>(__y))
952288943Sdim            return true;
953288943Sdim        if (_VSTD::get<__idx>(__y) < _VSTD::get<__idx>(__x))
954288943Sdim            return false;
955288943Sdim        return __tuple_less<_Ip-1>()(__x, __y);
956227825Stheraven    }
957227825Stheraven};
958227825Stheraven
959227825Stheraventemplate <>
960227825Stheravenstruct __tuple_less<0>
961227825Stheraven{
962227825Stheraven    template <class _Tp, class _Up>
963261272Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
964227825Stheraven    bool operator()(const _Tp&, const _Up&)
965227825Stheraven    {
966227825Stheraven        return false;
967227825Stheraven    }
968227825Stheraven};
969227825Stheraven
970227825Stheraventemplate <class ..._Tp, class ..._Up>
971261272Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
972227825Stheravenbool
973227825Stheravenoperator<(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
974227825Stheraven{
975227825Stheraven    return __tuple_less<sizeof...(_Tp)>()(__x, __y);
976227825Stheraven}
977227825Stheraven
978227825Stheraventemplate <class ..._Tp, class ..._Up>
979261272Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
980227825Stheravenbool
981227825Stheravenoperator>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
982227825Stheraven{
983227825Stheraven    return __y < __x;
984227825Stheraven}
985227825Stheraven
986227825Stheraventemplate <class ..._Tp, class ..._Up>
987261272Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
988227825Stheravenbool
989227825Stheravenoperator>=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
990227825Stheraven{
991227825Stheraven    return !(__x < __y);
992227825Stheraven}
993227825Stheraven
994227825Stheraventemplate <class ..._Tp, class ..._Up>
995261272Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
996227825Stheravenbool
997227825Stheravenoperator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
998227825Stheraven{
999227825Stheraven    return !(__y < __x);
1000227825Stheraven}
1001227825Stheraven
1002227825Stheraven// tuple_cat
1003227825Stheraven
1004227825Stheraventemplate <class _Tp, class _Up> struct __tuple_cat_type;
1005227825Stheraven
1006227825Stheraventemplate <class ..._Ttypes, class ..._Utypes>
1007227825Stheravenstruct __tuple_cat_type<tuple<_Ttypes...>, __tuple_types<_Utypes...> >
1008227825Stheraven{
1009227825Stheraven    typedef tuple<_Ttypes..., _Utypes...> type;
1010227825Stheraven};
1011227825Stheraven
1012227825Stheraventemplate <class _ResultTuple, bool _Is_Tuple0TupleLike, class ..._Tuples>
1013227825Stheravenstruct __tuple_cat_return_1
1014227825Stheraven{
1015227825Stheraven};
1016227825Stheraven
1017227825Stheraventemplate <class ..._Types, class _Tuple0>
1018227825Stheravenstruct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0>
1019227825Stheraven{
1020227825Stheraven    typedef typename __tuple_cat_type<tuple<_Types...>,
1021227825Stheraven            typename __make_tuple_types<typename remove_reference<_Tuple0>::type>::type>::type
1022227825Stheraven                                                                           type;
1023227825Stheraven};
1024227825Stheraven
1025227825Stheraventemplate <class ..._Types, class _Tuple0, class _Tuple1, class ..._Tuples>
1026227825Stheravenstruct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0, _Tuple1, _Tuples...>
1027227825Stheraven    : public __tuple_cat_return_1<
1028227825Stheraven                 typename __tuple_cat_type<
1029227825Stheraven                     tuple<_Types...>,
1030227825Stheraven                     typename __make_tuple_types<typename remove_reference<_Tuple0>::type>::type
1031227825Stheraven                 >::type,
1032227825Stheraven                 __tuple_like<typename remove_reference<_Tuple1>::type>::value,
1033227825Stheraven                 _Tuple1, _Tuples...>
1034227825Stheraven{
1035227825Stheraven};
1036227825Stheraven
1037227825Stheraventemplate <class ..._Tuples> struct __tuple_cat_return;
1038227825Stheraven
1039227825Stheraventemplate <class _Tuple0, class ..._Tuples>
1040227825Stheravenstruct __tuple_cat_return<_Tuple0, _Tuples...>
1041227825Stheraven    : public __tuple_cat_return_1<tuple<>,
1042227825Stheraven         __tuple_like<typename remove_reference<_Tuple0>::type>::value, _Tuple0,
1043227825Stheraven                                                                     _Tuples...>
1044227825Stheraven{
1045227825Stheraven};
1046227825Stheraven
1047227825Stheraventemplate <>
1048227825Stheravenstruct __tuple_cat_return<>
1049227825Stheraven{
1050227825Stheraven    typedef tuple<> type;
1051227825Stheraven};
1052227825Stheraven
1053261272Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1054227825Stheraventuple<>
1055227825Stheraventuple_cat()
1056227825Stheraven{
1057227825Stheraven    return tuple<>();
1058227825Stheraven}
1059227825Stheraven
1060232924Stheraventemplate <class _Rp, class _Indices, class _Tuple0, class ..._Tuples>
1061227825Stheravenstruct __tuple_cat_return_ref_imp;
1062227825Stheraven
1063227825Stheraventemplate <class ..._Types, size_t ..._I0, class _Tuple0>
1064227825Stheravenstruct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, _Tuple0>
1065227825Stheraven{
1066227825Stheraven    typedef typename remove_reference<_Tuple0>::type _T0;
1067227825Stheraven    typedef tuple<_Types..., typename __apply_cv<_Tuple0,
1068227825Stheraven                          typename tuple_element<_I0, _T0>::type>::type&&...> type;
1069227825Stheraven};
1070227825Stheraven
1071227825Stheraventemplate <class ..._Types, size_t ..._I0, class _Tuple0, class _Tuple1, class ..._Tuples>
1072227825Stheravenstruct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>,
1073227825Stheraven                                  _Tuple0, _Tuple1, _Tuples...>
1074227825Stheraven    : public __tuple_cat_return_ref_imp<
1075227825Stheraven         tuple<_Types..., typename __apply_cv<_Tuple0,
1076227825Stheraven               typename tuple_element<_I0,
1077227825Stheraven                  typename remove_reference<_Tuple0>::type>::type>::type&&...>,
1078227825Stheraven         typename __make_tuple_indices<tuple_size<typename
1079227825Stheraven                                 remove_reference<_Tuple1>::type>::value>::type,
1080227825Stheraven         _Tuple1, _Tuples...>
1081227825Stheraven{
1082227825Stheraven};
1083227825Stheraven
1084227825Stheraventemplate <class _Tuple0, class ..._Tuples>
1085227825Stheravenstruct __tuple_cat_return_ref
1086227825Stheraven    : public __tuple_cat_return_ref_imp<tuple<>,
1087227825Stheraven               typename __make_tuple_indices<
1088227825Stheraven                        tuple_size<typename remove_reference<_Tuple0>::type>::value
1089227825Stheraven               >::type, _Tuple0, _Tuples...>
1090227825Stheraven{
1091227825Stheraven};
1092227825Stheraven
1093227825Stheraventemplate <class _Types, class _I0, class _J0>
1094227825Stheravenstruct __tuple_cat;
1095227825Stheraven
1096227825Stheraventemplate <class ..._Types, size_t ..._I0, size_t ..._J0>
1097227825Stheravenstruct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J0...> >
1098227825Stheraven{
1099227825Stheraven    template <class _Tuple0>
1100261272Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1101227825Stheraven    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&>::type
1102227825Stheraven    operator()(tuple<_Types...> __t, _Tuple0&& __t0)
1103227825Stheraven    {
1104276792Sdim        return forward_as_tuple(_VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
1105276792Sdim                                      _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...);
1106227825Stheraven    }
1107227825Stheraven
1108227825Stheraven    template <class _Tuple0, class _Tuple1, class ..._Tuples>
1109261272Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1110227825Stheraven    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&, _Tuple1&&, _Tuples&&...>::type
1111227825Stheraven    operator()(tuple<_Types...> __t, _Tuple0&& __t0, _Tuple1&& __t1, _Tuples&& ...__tpls)
1112227825Stheraven    {
1113227825Stheraven        typedef typename remove_reference<_Tuple0>::type _T0;
1114227825Stheraven        typedef typename remove_reference<_Tuple1>::type _T1;
1115227825Stheraven        return __tuple_cat<
1116227825Stheraven           tuple<_Types..., typename __apply_cv<_Tuple0, typename tuple_element<_J0, _T0>::type>::type&&...>,
1117227825Stheraven           typename __make_tuple_indices<sizeof ...(_Types) + tuple_size<_T0>::value>::type,
1118227825Stheraven           typename __make_tuple_indices<tuple_size<_T1>::value>::type>()
1119261272Sdim                           (forward_as_tuple(
1120276792Sdim                              _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
1121276792Sdim                              _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...
1122227825Stheraven                            ),
1123227825Stheraven                            _VSTD::forward<_Tuple1>(__t1),
1124227825Stheraven                            _VSTD::forward<_Tuples>(__tpls)...);
1125227825Stheraven    }
1126227825Stheraven};
1127227825Stheraven
1128227825Stheraventemplate <class _Tuple0, class... _Tuples>
1129261272Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1130227825Stheraventypename __tuple_cat_return<_Tuple0, _Tuples...>::type
1131227825Stheraventuple_cat(_Tuple0&& __t0, _Tuples&&... __tpls)
1132227825Stheraven{
1133227825Stheraven    typedef typename remove_reference<_Tuple0>::type _T0;
1134227825Stheraven    return __tuple_cat<tuple<>, __tuple_indices<>,
1135227825Stheraven                  typename __make_tuple_indices<tuple_size<_T0>::value>::type>()
1136227825Stheraven                  (tuple<>(), _VSTD::forward<_Tuple0>(__t0),
1137227825Stheraven                                            _VSTD::forward<_Tuples>(__tpls)...);
1138227825Stheraven}
1139227825Stheraven
1140227825Stheraventemplate <class ..._Tp, class _Alloc>
1141261272Sdimstruct _LIBCPP_TYPE_VIS_ONLY uses_allocator<tuple<_Tp...>, _Alloc>
1142227825Stheraven    : true_type {};
1143227825Stheraven
1144227825Stheraventemplate <class _T1, class _T2>
1145227825Stheraventemplate <class... _Args1, class... _Args2, size_t ..._I1, size_t ..._I2>
1146227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1147227825Stheravenpair<_T1, _T2>::pair(piecewise_construct_t,
1148227825Stheraven                     tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,
1149227825Stheraven                     __tuple_indices<_I1...>, __tuple_indices<_I2...>)
1150276792Sdim    :  first(_VSTD::forward<_Args1>(_VSTD::get<_I1>( __first_args))...),
1151276792Sdim      second(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...)
1152227825Stheraven{
1153227825Stheraven}
1154227825Stheraven
1155227825Stheraven#endif  // _LIBCPP_HAS_NO_VARIADICS
1156227825Stheraven
1157227825Stheraven_LIBCPP_END_NAMESPACE_STD
1158227825Stheraven
1159227825Stheraven#endif  // _LIBCPP_TUPLE
1160