tuple revision 276792
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...>>;
83227825Stheraventemplate <intsize_t I, class T> class tuple_element; // undefined
84227825Stheraventemplate <intsize_t I, class... T> class tuple_element<I, tuple<T...>>;
85276792Sdimtemplate <size_t _Ip, class ..._Tp>
86276792Sdim  using tuple_element_t = typename tuple_element <_Ip, _Tp...>::type; // C++14
87227825Stheraven
88227825Stheraven// 20.4.1.5, element access:
89227825Stheraventemplate <intsize_t I, class... T>
90227825Stheraven    typename tuple_element<I, tuple<T...>>::type&
91261272Sdim    get(tuple<T...>&) noexcept; // constexpr in C++14
92227825Stheraventemplate <intsize_t I, class... T>
93276792Sdim    typename const tuple_element<I, tuple<T...>>::type &
94261272Sdim    get(const tuple<T...>&) noexcept; // constexpr in C++14
95227825Stheraventemplate <intsize_t I, class... T>
96227825Stheraven    typename tuple_element<I, tuple<T...>>::type&&
97261272Sdim    get(tuple<T...>&&) noexcept; // constexpr in C++14
98227825Stheraven
99261272Sdimtemplate <class T1, class... T>
100261272Sdim    constexpr T1& get(tuple<T...>&) noexcept;  // C++14
101261272Sdimtemplate <class T1, class... T>
102261272Sdim    constexpr T1 const& get(const tuple<T...>&) noexcept;   // C++14
103261272Sdimtemplate <class T1, class... T>
104261272Sdim    constexpr T1&& get(tuple<T...>&&) noexcept;   // C++14
105261272Sdim
106227825Stheraven// 20.4.1.6, relational operators:
107261272Sdimtemplate<class... T, class... U> bool operator==(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
108261272Sdimtemplate<class... T, class... U> bool operator<(const tuple<T...>&, const tuple<U...>&);  // constexpr in C++14
109261272Sdimtemplate<class... T, class... U> bool operator!=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
110261272Sdimtemplate<class... T, class... U> bool operator>(const tuple<T...>&, const tuple<U...>&);  // constexpr in C++14
111261272Sdimtemplate<class... T, class... U> bool operator<=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
112261272Sdimtemplate<class... T, class... U> bool operator>=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
113227825Stheraven
114227825Stheraventemplate <class... Types, class Alloc>
115227825Stheraven  struct uses_allocator<tuple<Types...>, Alloc>;
116227825Stheraven
117227825Stheraventemplate <class... Types>
118227825Stheraven  void
119227825Stheraven  swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(noexcept(x.swap(y)));
120227825Stheraven
121227825Stheraven}  // std
122227825Stheraven
123227825Stheraven*/
124227825Stheraven
125227825Stheraven#include <__config>
126227825Stheraven#include <__tuple>
127227825Stheraven#include <cstddef>
128227825Stheraven#include <type_traits>
129232924Stheraven#include <__functional_base>
130232924Stheraven#include <utility>
131227825Stheraven
132227825Stheraven#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
133227825Stheraven#pragma GCC system_header
134227825Stheraven#endif
135227825Stheraven
136227825Stheraven_LIBCPP_BEGIN_NAMESPACE_STD
137227825Stheraven
138227825Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS
139227825Stheraven
140227825Stheraven// tuple_size
141227825Stheraven
142227825Stheraventemplate <class ..._Tp>
143261272Sdimclass _LIBCPP_TYPE_VIS_ONLY tuple_size<tuple<_Tp...> >
144227825Stheraven    : public integral_constant<size_t, sizeof...(_Tp)>
145227825Stheraven{
146227825Stheraven};
147227825Stheraven
148227825Stheraven// tuple_element
149227825Stheraven
150227825Stheraventemplate <size_t _Ip, class ..._Tp>
151261272Sdimclass _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, tuple<_Tp...> >
152227825Stheraven{
153227825Stheravenpublic:
154227825Stheraven    typedef typename tuple_element<_Ip, __tuple_types<_Tp...> >::type type;
155227825Stheraven};
156227825Stheraven
157276792Sdim#if _LIBCPP_STD_VER > 11
158276792Sdimtemplate <size_t _Ip, class ..._Tp>
159276792Sdimusing tuple_element_t = typename tuple_element <_Ip, _Tp...>::type;
160276792Sdim#endif
161276792Sdim
162227825Stheraven// __tuple_leaf
163227825Stheraven
164232924Stheraventemplate <size_t _Ip, class _Hp, bool=is_empty<_Hp>::value
165232924Stheraven#if __has_feature(is_final)
166232924Stheraven                                 && !__is_final(_Hp)
167232924Stheraven#endif
168232924Stheraven         >
169227825Stheravenclass __tuple_leaf;
170227825Stheraven
171227825Stheraventemplate <size_t _Ip, class _Hp, bool _Ep>
172227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
173227825Stheravenvoid swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y)
174227825Stheraven    _NOEXCEPT_(__is_nothrow_swappable<_Hp>::value)
175227825Stheraven{
176227825Stheraven    swap(__x.get(), __y.get());
177227825Stheraven}
178227825Stheraven
179227825Stheraventemplate <size_t _Ip, class _Hp, bool>
180227825Stheravenclass __tuple_leaf
181227825Stheraven{
182227825Stheraven    _Hp value;
183227825Stheraven
184227825Stheraven    __tuple_leaf& operator=(const __tuple_leaf&);
185227825Stheravenpublic:
186241900Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __tuple_leaf()
187241900Sdim             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) : value()
188227825Stheraven       {static_assert(!is_reference<_Hp>::value,
189227825Stheraven              "Attempted to default construct a reference element in a tuple");}
190227825Stheraven
191227825Stheraven    template <class _Alloc>
192227825Stheraven        _LIBCPP_INLINE_VISIBILITY
193227825Stheraven        __tuple_leaf(integral_constant<int, 0>, const _Alloc&)
194227825Stheraven            : value()
195227825Stheraven        {static_assert(!is_reference<_Hp>::value,
196227825Stheraven              "Attempted to default construct a reference element in a tuple");}
197227825Stheraven
198227825Stheraven    template <class _Alloc>
199227825Stheraven        _LIBCPP_INLINE_VISIBILITY
200227825Stheraven        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
201227825Stheraven            : value(allocator_arg_t(), __a)
202227825Stheraven        {static_assert(!is_reference<_Hp>::value,
203227825Stheraven              "Attempted to default construct a reference element in a tuple");}
204227825Stheraven
205227825Stheraven    template <class _Alloc>
206227825Stheraven        _LIBCPP_INLINE_VISIBILITY
207227825Stheraven        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
208227825Stheraven            : value(__a)
209227825Stheraven        {static_assert(!is_reference<_Hp>::value,
210227825Stheraven              "Attempted to default construct a reference element in a tuple");}
211227825Stheraven
212227825Stheraven    template <class _Tp,
213276792Sdim              class = typename enable_if<
214276792Sdim                  __lazy_and<
215276792Sdim                      __lazy_not<is_same<typename decay<_Tp>::type, __tuple_leaf>>
216276792Sdim                    , is_constructible<_Hp, _Tp>
217276792Sdim                    >::value
218276792Sdim                >::type
219276792Sdim            >
220261272Sdim        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
221241900Sdim        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
222227825Stheraven            : value(_VSTD::forward<_Tp>(__t))
223227825Stheraven        {static_assert(!is_reference<_Hp>::value ||
224232924Stheraven                       (is_lvalue_reference<_Hp>::value &&
225227825Stheraven                        (is_lvalue_reference<_Tp>::value ||
226227825Stheraven                         is_same<typename remove_reference<_Tp>::type,
227227825Stheraven                                 reference_wrapper<
228227825Stheraven                                    typename remove_reference<_Hp>::type
229227825Stheraven                                 >
230232924Stheraven                                >::value)) ||
231227825Stheraven                        (is_rvalue_reference<_Hp>::value &&
232227825Stheraven                         !is_lvalue_reference<_Tp>::value),
233227825Stheraven       "Attempted to construct a reference element in a tuple with an rvalue");}
234227825Stheraven
235227825Stheraven    template <class _Tp, class _Alloc>
236227825Stheraven        _LIBCPP_INLINE_VISIBILITY
237227825Stheraven        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
238227825Stheraven            : value(_VSTD::forward<_Tp>(__t))
239227825Stheraven        {static_assert(!is_lvalue_reference<_Hp>::value ||
240232924Stheraven                       (is_lvalue_reference<_Hp>::value &&
241227825Stheraven                        (is_lvalue_reference<_Tp>::value ||
242227825Stheraven                         is_same<typename remove_reference<_Tp>::type,
243227825Stheraven                                 reference_wrapper<
244227825Stheraven                                    typename remove_reference<_Hp>::type
245227825Stheraven                                 >
246232924Stheraven                                >::value)),
247227825Stheraven       "Attempted to construct a reference element in a tuple with an rvalue");}
248227825Stheraven
249227825Stheraven    template <class _Tp, class _Alloc>
250227825Stheraven        _LIBCPP_INLINE_VISIBILITY
251227825Stheraven        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
252227825Stheraven            : value(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t))
253227825Stheraven        {static_assert(!is_lvalue_reference<_Hp>::value ||
254232924Stheraven                       (is_lvalue_reference<_Hp>::value &&
255227825Stheraven                        (is_lvalue_reference<_Tp>::value ||
256227825Stheraven                         is_same<typename remove_reference<_Tp>::type,
257227825Stheraven                                 reference_wrapper<
258227825Stheraven                                    typename remove_reference<_Hp>::type
259227825Stheraven                                 >
260232924Stheraven                                >::value)),
261227825Stheraven       "Attempted to construct a reference element in a tuple with an rvalue");}
262227825Stheraven
263227825Stheraven    template <class _Tp, class _Alloc>
264227825Stheraven        _LIBCPP_INLINE_VISIBILITY
265227825Stheraven        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
266227825Stheraven            : value(_VSTD::forward<_Tp>(__t), __a)
267227825Stheraven        {static_assert(!is_lvalue_reference<_Hp>::value ||
268232924Stheraven                       (is_lvalue_reference<_Hp>::value &&
269227825Stheraven                        (is_lvalue_reference<_Tp>::value ||
270227825Stheraven                         is_same<typename remove_reference<_Tp>::type,
271227825Stheraven                                 reference_wrapper<
272227825Stheraven                                    typename remove_reference<_Hp>::type
273227825Stheraven                                 >
274232924Stheraven                                >::value)),
275227825Stheraven       "Attempted to construct a reference element in a tuple with an rvalue");}
276227825Stheraven
277276792Sdim    __tuple_leaf(const __tuple_leaf& __t) = default;
278276792Sdim    __tuple_leaf(__tuple_leaf&& __t) = default;
279227825Stheraven
280227825Stheraven    template <class _Tp>
281227825Stheraven        _LIBCPP_INLINE_VISIBILITY
282227825Stheraven        __tuple_leaf&
283241900Sdim        operator=(_Tp&& __t) _NOEXCEPT_((is_nothrow_assignable<_Hp&, _Tp>::value))
284227825Stheraven        {
285227825Stheraven            value = _VSTD::forward<_Tp>(__t);
286227825Stheraven            return *this;
287227825Stheraven        }
288227825Stheraven
289227825Stheraven    _LIBCPP_INLINE_VISIBILITY
290227825Stheraven    int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
291227825Stheraven    {
292227825Stheraven        _VSTD::swap(*this, __t);
293227825Stheraven        return 0;
294227825Stheraven    }
295227825Stheraven
296261272Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11       _Hp& get()       _NOEXCEPT {return value;}
297261272Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return value;}
298227825Stheraven};
299227825Stheraven
300227825Stheraventemplate <size_t _Ip, class _Hp>
301227825Stheravenclass __tuple_leaf<_Ip, _Hp, true>
302227825Stheraven    : private _Hp
303227825Stheraven{
304227825Stheraven
305227825Stheraven    __tuple_leaf& operator=(const __tuple_leaf&);
306227825Stheravenpublic:
307241900Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __tuple_leaf()
308241900Sdim             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) {}
309227825Stheraven
310227825Stheraven    template <class _Alloc>
311227825Stheraven        _LIBCPP_INLINE_VISIBILITY
312227825Stheraven        __tuple_leaf(integral_constant<int, 0>, const _Alloc&) {}
313227825Stheraven
314227825Stheraven    template <class _Alloc>
315227825Stheraven        _LIBCPP_INLINE_VISIBILITY
316227825Stheraven        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
317227825Stheraven            : _Hp(allocator_arg_t(), __a) {}
318227825Stheraven
319227825Stheraven    template <class _Alloc>
320227825Stheraven        _LIBCPP_INLINE_VISIBILITY
321227825Stheraven        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
322227825Stheraven            : _Hp(__a) {}
323227825Stheraven
324227825Stheraven    template <class _Tp,
325276792Sdim              class = typename enable_if<
326276792Sdim                  __lazy_and<
327276792Sdim                        __lazy_not<is_same<typename decay<_Tp>::type, __tuple_leaf>>
328276792Sdim                      , is_constructible<_Hp, _Tp>
329276792Sdim                    >::value
330276792Sdim                >::type
331276792Sdim            >
332261272Sdim        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
333241900Sdim        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
334227825Stheraven            : _Hp(_VSTD::forward<_Tp>(__t)) {}
335227825Stheraven
336227825Stheraven    template <class _Tp, class _Alloc>
337227825Stheraven        _LIBCPP_INLINE_VISIBILITY
338227825Stheraven        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
339227825Stheraven            : _Hp(_VSTD::forward<_Tp>(__t)) {}
340227825Stheraven
341227825Stheraven    template <class _Tp, class _Alloc>
342227825Stheraven        _LIBCPP_INLINE_VISIBILITY
343227825Stheraven        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
344227825Stheraven            : _Hp(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) {}
345227825Stheraven
346227825Stheraven    template <class _Tp, class _Alloc>
347227825Stheraven        _LIBCPP_INLINE_VISIBILITY
348227825Stheraven        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
349227825Stheraven            : _Hp(_VSTD::forward<_Tp>(__t), __a) {}
350227825Stheraven
351276792Sdim    __tuple_leaf(__tuple_leaf const &) = default;
352276792Sdim    __tuple_leaf(__tuple_leaf &&) = default;
353276792Sdim
354227825Stheraven    template <class _Tp>
355227825Stheraven        _LIBCPP_INLINE_VISIBILITY
356227825Stheraven        __tuple_leaf&
357241900Sdim        operator=(_Tp&& __t) _NOEXCEPT_((is_nothrow_assignable<_Hp&, _Tp>::value))
358227825Stheraven        {
359227825Stheraven            _Hp::operator=(_VSTD::forward<_Tp>(__t));
360227825Stheraven            return *this;
361227825Stheraven        }
362227825Stheraven
363227825Stheraven    _LIBCPP_INLINE_VISIBILITY
364227825Stheraven    int
365227825Stheraven    swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
366227825Stheraven    {
367227825Stheraven        _VSTD::swap(*this, __t);
368227825Stheraven        return 0;
369227825Stheraven    }
370227825Stheraven
371261272Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11       _Hp& get()       _NOEXCEPT {return static_cast<_Hp&>(*this);}
372261272Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return static_cast<const _Hp&>(*this);}
373227825Stheraven};
374227825Stheraven
375227825Stheraventemplate <class ..._Tp>
376227825Stheraven_LIBCPP_INLINE_VISIBILITY
377241900Sdimvoid __swallow(_Tp&&...) _NOEXCEPT {}
378227825Stheraven
379276792Sdimtemplate <bool ..._Pred>
380276792Sdimstruct __all
381276792Sdim    : is_same<__all<_Pred...>, __all<(_Pred, true)...>>
382276792Sdim{ };
383227825Stheraven
384276792Sdimtemplate <class _Tp>
385276792Sdimstruct __all_default_constructible;
386227825Stheraven
387276792Sdimtemplate <class ..._Tp>
388276792Sdimstruct __all_default_constructible<__tuple_types<_Tp...>>
389276792Sdim    : __all<is_default_constructible<_Tp>::value...>
390276792Sdim{ };
391227825Stheraven
392227825Stheraven// __tuple_impl
393227825Stheraven
394227825Stheraventemplate<class _Indx, class ..._Tp> struct __tuple_impl;
395227825Stheraven
396227825Stheraventemplate<size_t ..._Indx, class ..._Tp>
397227825Stheravenstruct __tuple_impl<__tuple_indices<_Indx...>, _Tp...>
398227825Stheraven    : public __tuple_leaf<_Indx, _Tp>...
399227825Stheraven{
400241900Sdim    _LIBCPP_INLINE_VISIBILITY
401241900Sdim    _LIBCPP_CONSTEXPR __tuple_impl()
402241900Sdim        _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
403241900Sdim
404227825Stheraven    template <size_t ..._Uf, class ..._Tf,
405227825Stheraven              size_t ..._Ul, class ..._Tl, class ..._Up>
406261272Sdim        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
407227825Stheraven        explicit
408227825Stheraven        __tuple_impl(__tuple_indices<_Uf...>, __tuple_types<_Tf...>,
409227825Stheraven                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
410241900Sdim                     _Up&&... __u)
411241900Sdim                     _NOEXCEPT_((__all<is_nothrow_constructible<_Tf, _Up>::value...>::value &&
412241900Sdim                                 __all<is_nothrow_default_constructible<_Tl>::value...>::value)) :
413227825Stheraven            __tuple_leaf<_Uf, _Tf>(_VSTD::forward<_Up>(__u))...,
414227825Stheraven            __tuple_leaf<_Ul, _Tl>()...
415227825Stheraven            {}
416227825Stheraven
417227825Stheraven    template <class _Alloc, size_t ..._Uf, class ..._Tf,
418227825Stheraven              size_t ..._Ul, class ..._Tl, class ..._Up>
419227825Stheraven        _LIBCPP_INLINE_VISIBILITY
420227825Stheraven        explicit
421227825Stheraven        __tuple_impl(allocator_arg_t, const _Alloc& __a,
422227825Stheraven                     __tuple_indices<_Uf...>, __tuple_types<_Tf...>,
423227825Stheraven                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
424227825Stheraven                     _Up&&... __u) :
425227825Stheraven            __tuple_leaf<_Uf, _Tf>(__uses_alloc_ctor<_Tf, _Alloc, _Up>(), __a,
426227825Stheraven            _VSTD::forward<_Up>(__u))...,
427227825Stheraven            __tuple_leaf<_Ul, _Tl>(__uses_alloc_ctor<_Tl, _Alloc>(), __a)...
428227825Stheraven            {}
429227825Stheraven
430227825Stheraven    template <class _Tuple,
431227825Stheraven              class = typename enable_if
432227825Stheraven                      <
433249989Sdim                         __tuple_constructible<_Tuple, tuple<_Tp...> >::value
434227825Stheraven                      >::type
435227825Stheraven             >
436261272Sdim        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
437241900Sdim        __tuple_impl(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_constructible<_Tp, typename tuple_element<_Indx,
438241900Sdim                                       typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))
439227825Stheraven            : __tuple_leaf<_Indx, _Tp>(_VSTD::forward<typename tuple_element<_Indx,
440227825Stheraven                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
441227825Stheraven            {}
442227825Stheraven
443227825Stheraven    template <class _Alloc, class _Tuple,
444227825Stheraven              class = typename enable_if
445227825Stheraven                      <
446227825Stheraven                         __tuple_convertible<_Tuple, tuple<_Tp...> >::value
447227825Stheraven                      >::type
448227825Stheraven             >
449227825Stheraven        _LIBCPP_INLINE_VISIBILITY
450227825Stheraven        __tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
451227825Stheraven            : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, typename tuple_element<_Indx,
452227825Stheraven                                       typename __make_tuple_types<_Tuple>::type>::type>(), __a,
453227825Stheraven                                       _VSTD::forward<typename tuple_element<_Indx,
454227825Stheraven                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
455227825Stheraven            {}
456227825Stheraven
457227825Stheraven    template <class _Tuple>
458227825Stheraven        _LIBCPP_INLINE_VISIBILITY
459227825Stheraven        typename enable_if
460227825Stheraven        <
461227825Stheraven            __tuple_assignable<_Tuple, tuple<_Tp...> >::value,
462227825Stheraven            __tuple_impl&
463227825Stheraven        >::type
464241900Sdim        operator=(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_assignable<_Tp&, typename tuple_element<_Indx,
465241900Sdim                                       typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))
466227825Stheraven        {
467227825Stheraven            __swallow(__tuple_leaf<_Indx, _Tp>::operator=(_VSTD::forward<typename tuple_element<_Indx,
468227825Stheraven                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...);
469227825Stheraven            return *this;
470227825Stheraven        }
471227825Stheraven
472261272Sdim    __tuple_impl(const __tuple_impl&) = default;
473261272Sdim    __tuple_impl(__tuple_impl&&) = default;
474232924Stheraven
475227825Stheraven    _LIBCPP_INLINE_VISIBILITY
476261272Sdim    __tuple_impl&
477261272Sdim    operator=(const __tuple_impl& __t) _NOEXCEPT_((__all<is_nothrow_copy_assignable<_Tp>::value...>::value))
478261272Sdim    {
479261272Sdim        __swallow(__tuple_leaf<_Indx, _Tp>::operator=(static_cast<const __tuple_leaf<_Indx, _Tp>&>(__t).get())...);
480261272Sdim        return *this;
481261272Sdim    }
482261272Sdim
483261272Sdim    _LIBCPP_INLINE_VISIBILITY
484261272Sdim    __tuple_impl&
485261272Sdim    operator=(__tuple_impl&& __t) _NOEXCEPT_((__all<is_nothrow_move_assignable<_Tp>::value...>::value))
486261272Sdim    {
487261272Sdim        __swallow(__tuple_leaf<_Indx, _Tp>::operator=(_VSTD::forward<_Tp>(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t).get()))...);
488261272Sdim        return *this;
489261272Sdim    }
490261272Sdim
491261272Sdim    _LIBCPP_INLINE_VISIBILITY
492227825Stheraven    void swap(__tuple_impl& __t)
493227825Stheraven        _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
494227825Stheraven    {
495227825Stheraven        __swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...);
496227825Stheraven    }
497227825Stheraven};
498227825Stheraven
499227825Stheraventemplate <class ..._Tp>
500261272Sdimclass _LIBCPP_TYPE_VIS_ONLY tuple
501227825Stheraven{
502227825Stheraven    typedef __tuple_impl<typename __make_tuple_indices<sizeof...(_Tp)>::type, _Tp...> base;
503227825Stheraven
504227825Stheraven    base base_;
505227825Stheraven
506261272Sdim    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
507232924Stheraven        typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT;
508261272Sdim    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
509232924Stheraven        const typename tuple_element<_Jp, tuple<_Up...> >::type& get(const tuple<_Up...>&) _NOEXCEPT;
510261272Sdim    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
511232924Stheraven        typename tuple_element<_Jp, tuple<_Up...> >::type&& get(tuple<_Up...>&&) _NOEXCEPT;
512227825Stheravenpublic:
513227825Stheraven
514276792Sdim    template <bool _Dummy = true, class _Up = typename enable_if<
515276792Sdim        __all<(_Dummy && is_default_constructible<_Tp>::value)...>::value
516276792Sdim    >::type>
517227825Stheraven    _LIBCPP_INLINE_VISIBILITY
518241900Sdim    _LIBCPP_CONSTEXPR tuple()
519241900Sdim        _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
520241900Sdim
521261272Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
522241900Sdim    explicit tuple(const _Tp& ... __t) _NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value)) 
523227825Stheraven        : base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
524227825Stheraven                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
525227825Stheraven                typename __make_tuple_indices<0>::type(),
526227825Stheraven                typename __make_tuple_types<tuple, 0>::type(),
527227825Stheraven                __t...
528227825Stheraven               ) {}
529227825Stheraven
530227825Stheraven    template <class _Alloc>
531227825Stheraven      _LIBCPP_INLINE_VISIBILITY
532227825Stheraven      tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
533227825Stheraven        : base_(allocator_arg_t(), __a,
534227825Stheraven                typename __make_tuple_indices<sizeof...(_Tp)>::type(),
535227825Stheraven                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
536227825Stheraven                typename __make_tuple_indices<0>::type(),
537227825Stheraven                typename __make_tuple_types<tuple, 0>::type(),
538227825Stheraven                __t...
539227825Stheraven               ) {}
540227825Stheraven
541227825Stheraven    template <class ..._Up,
542234959Stheraven              typename enable_if
543227825Stheraven                      <
544227825Stheraven                         sizeof...(_Up) <= sizeof...(_Tp) &&
545227825Stheraven                         __tuple_convertible
546227825Stheraven                         <
547227825Stheraven                            tuple<_Up...>,
548227825Stheraven                            typename __make_tuple_types<tuple,
549227825Stheraven                                     sizeof...(_Up) < sizeof...(_Tp) ?
550227825Stheraven                                        sizeof...(_Up) :
551227825Stheraven                                        sizeof...(_Tp)>::type
552276792Sdim                         >::value &&
553276792Sdim                         __all_default_constructible<
554276792Sdim                            typename __make_tuple_types<tuple, sizeof...(_Tp),
555276792Sdim                                sizeof...(_Up) < sizeof...(_Tp) ?
556276792Sdim                                    sizeof...(_Up) :
557276792Sdim                                    sizeof...(_Tp)>::type
558234959Stheraven                         >::value,
559234959Stheraven                         bool
560234959Stheraven                      >::type = false
561227825Stheraven             >
562261272Sdim        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
563234959Stheraven        tuple(_Up&&... __u)
564241900Sdim            _NOEXCEPT_((
565276792Sdim                is_nothrow_constructible<base,
566241900Sdim                    typename __make_tuple_indices<sizeof...(_Up)>::type,
567241900Sdim                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type,
568241900Sdim                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type,
569241900Sdim                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type,
570241900Sdim                    _Up...
571241900Sdim                >::value
572241900Sdim            ))
573234959Stheraven            : base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
574234959Stheraven                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
575234959Stheraven                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
576234959Stheraven                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
577234959Stheraven                    _VSTD::forward<_Up>(__u)...) {}
578234959Stheraven
579234959Stheraven    template <class ..._Up,
580234959Stheraven              typename enable_if
581234959Stheraven                      <
582234959Stheraven                         sizeof...(_Up) <= sizeof...(_Tp) &&
583234959Stheraven                         __tuple_constructible
584234959Stheraven                         <
585234959Stheraven                            tuple<_Up...>,
586234959Stheraven                            typename __make_tuple_types<tuple,
587234959Stheraven                                     sizeof...(_Up) < sizeof...(_Tp) ?
588234959Stheraven                                        sizeof...(_Up) :
589234959Stheraven                                        sizeof...(_Tp)>::type
590234959Stheraven                         >::value &&
591234959Stheraven                         !__tuple_convertible
592234959Stheraven                         <
593234959Stheraven                            tuple<_Up...>,
594234959Stheraven                            typename __make_tuple_types<tuple,
595234959Stheraven                                     sizeof...(_Up) < sizeof...(_Tp) ?
596234959Stheraven                                        sizeof...(_Up) :
597234959Stheraven                                        sizeof...(_Tp)>::type
598276792Sdim                         >::value &&
599276792Sdim                         __all_default_constructible<
600276792Sdim                            typename __make_tuple_types<tuple, sizeof...(_Tp),
601276792Sdim                                sizeof...(_Up) < sizeof...(_Tp) ?
602276792Sdim                                    sizeof...(_Up) :
603276792Sdim                                    sizeof...(_Tp)>::type
604234959Stheraven                         >::value,
605234959Stheraven                         bool
606234959Stheraven                      >::type =false
607234959Stheraven             >
608261272Sdim        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
609227825Stheraven        explicit
610227825Stheraven        tuple(_Up&&... __u)
611241900Sdim            _NOEXCEPT_((
612276792Sdim                is_nothrow_constructible<base,
613241900Sdim                    typename __make_tuple_indices<sizeof...(_Up)>::type,
614241900Sdim                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type,
615241900Sdim                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type,
616241900Sdim                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type,
617241900Sdim                    _Up...
618241900Sdim                >::value
619241900Sdim            ))
620227825Stheraven            : base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
621227825Stheraven                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
622227825Stheraven                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
623227825Stheraven                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
624227825Stheraven                    _VSTD::forward<_Up>(__u)...) {}
625227825Stheraven
626227825Stheraven    template <class _Alloc, class ..._Up,
627227825Stheraven              class = typename enable_if
628227825Stheraven                      <
629227825Stheraven                         sizeof...(_Up) <= sizeof...(_Tp) &&
630227825Stheraven                         __tuple_convertible
631227825Stheraven                         <
632227825Stheraven                            tuple<_Up...>,
633227825Stheraven                            typename __make_tuple_types<tuple,
634227825Stheraven                                     sizeof...(_Up) < sizeof...(_Tp) ?
635227825Stheraven                                        sizeof...(_Up) :
636227825Stheraven                                        sizeof...(_Tp)>::type
637276792Sdim                         >::value &&
638276792Sdim                         __all_default_constructible<
639276792Sdim                            typename __make_tuple_types<tuple, sizeof...(_Tp),
640276792Sdim                                sizeof...(_Up) < sizeof...(_Tp) ?
641276792Sdim                                    sizeof...(_Up) :
642276792Sdim                                    sizeof...(_Tp)>::type
643227825Stheraven                         >::value
644227825Stheraven                      >::type
645227825Stheraven             >
646227825Stheraven        _LIBCPP_INLINE_VISIBILITY
647227825Stheraven        tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
648227825Stheraven            : base_(allocator_arg_t(), __a,
649227825Stheraven                    typename __make_tuple_indices<sizeof...(_Up)>::type(),
650227825Stheraven                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
651227825Stheraven                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
652227825Stheraven                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
653227825Stheraven                    _VSTD::forward<_Up>(__u)...) {}
654227825Stheraven
655227825Stheraven    template <class _Tuple,
656234959Stheraven              typename enable_if
657227825Stheraven                      <
658234959Stheraven                         __tuple_convertible<_Tuple, tuple>::value,
659234959Stheraven                         bool
660234959Stheraven                      >::type = false
661227825Stheraven             >
662261272Sdim        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
663241900Sdim        tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<base, _Tuple>::value))
664227825Stheraven            : base_(_VSTD::forward<_Tuple>(__t)) {}
665227825Stheraven
666234959Stheraven    template <class _Tuple,
667234959Stheraven              typename enable_if
668234959Stheraven                      <
669234959Stheraven                         __tuple_constructible<_Tuple, tuple>::value &&
670234959Stheraven                         !__tuple_convertible<_Tuple, tuple>::value,
671234959Stheraven                         bool
672234959Stheraven                      >::type = false
673234959Stheraven             >
674261272Sdim        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
675234959Stheraven        explicit
676241900Sdim        tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<base, _Tuple>::value))
677234959Stheraven            : base_(_VSTD::forward<_Tuple>(__t)) {}
678234959Stheraven
679227825Stheraven    template <class _Alloc, class _Tuple,
680227825Stheraven              class = typename enable_if
681227825Stheraven                      <
682227825Stheraven                         __tuple_convertible<_Tuple, tuple>::value
683227825Stheraven                      >::type
684227825Stheraven             >
685227825Stheraven        _LIBCPP_INLINE_VISIBILITY
686227825Stheraven        tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
687227825Stheraven            : base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {}
688227825Stheraven
689227825Stheraven    template <class _Tuple,
690227825Stheraven              class = typename enable_if
691227825Stheraven                      <
692227825Stheraven                         __tuple_assignable<_Tuple, tuple>::value
693227825Stheraven                      >::type
694227825Stheraven             >
695227825Stheraven        _LIBCPP_INLINE_VISIBILITY
696227825Stheraven        tuple&
697241900Sdim        operator=(_Tuple&& __t) _NOEXCEPT_((is_nothrow_assignable<base&, _Tuple>::value))
698227825Stheraven        {
699227825Stheraven            base_.operator=(_VSTD::forward<_Tuple>(__t));
700227825Stheraven            return *this;
701227825Stheraven        }
702227825Stheraven
703227825Stheraven    _LIBCPP_INLINE_VISIBILITY
704227825Stheraven    void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
705227825Stheraven        {base_.swap(__t.base_);}
706227825Stheraven};
707227825Stheraven
708227825Stheraventemplate <>
709261272Sdimclass _LIBCPP_TYPE_VIS_ONLY tuple<>
710227825Stheraven{
711227825Stheravenpublic:
712227825Stheraven    _LIBCPP_INLINE_VISIBILITY
713241900Sdim    _LIBCPP_CONSTEXPR tuple() _NOEXCEPT {}
714227825Stheraven    template <class _Alloc>
715227825Stheraven    _LIBCPP_INLINE_VISIBILITY
716241900Sdim        tuple(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
717227825Stheraven    template <class _Alloc>
718227825Stheraven    _LIBCPP_INLINE_VISIBILITY
719241900Sdim        tuple(allocator_arg_t, const _Alloc&, const tuple&) _NOEXCEPT {}
720232924Stheraven    template <class _Up>
721227825Stheraven    _LIBCPP_INLINE_VISIBILITY
722241900Sdim        tuple(array<_Up, 0>) _NOEXCEPT {}
723232924Stheraven    template <class _Alloc, class _Up>
724227825Stheraven    _LIBCPP_INLINE_VISIBILITY
725241900Sdim        tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) _NOEXCEPT {}
726227825Stheraven    _LIBCPP_INLINE_VISIBILITY
727227825Stheraven    void swap(tuple&) _NOEXCEPT {}
728227825Stheraven};
729227825Stheraven
730227825Stheraventemplate <class ..._Tp>
731227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
732227825Stheraventypename enable_if
733227825Stheraven<
734227825Stheraven    __all<__is_swappable<_Tp>::value...>::value,
735227825Stheraven    void
736227825Stheraven>::type
737227825Stheravenswap(tuple<_Tp...>& __t, tuple<_Tp...>& __u)
738227825Stheraven                 _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
739227825Stheraven    {__t.swap(__u);}
740227825Stheraven
741227825Stheraven// get
742227825Stheraven
743227825Stheraventemplate <size_t _Ip, class ..._Tp>
744261272Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
745227825Stheraventypename tuple_element<_Ip, tuple<_Tp...> >::type&
746232924Stheravenget(tuple<_Tp...>& __t) _NOEXCEPT
747227825Stheraven{
748227825Stheraven    typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
749227825Stheraven    return static_cast<__tuple_leaf<_Ip, type>&>(__t.base_).get();
750227825Stheraven}
751227825Stheraven
752227825Stheraventemplate <size_t _Ip, class ..._Tp>
753261272Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
754227825Stheravenconst typename tuple_element<_Ip, tuple<_Tp...> >::type&
755232924Stheravenget(const tuple<_Tp...>& __t) _NOEXCEPT
756227825Stheraven{
757227825Stheraven    typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
758227825Stheraven    return static_cast<const __tuple_leaf<_Ip, type>&>(__t.base_).get();
759227825Stheraven}
760227825Stheraven
761227825Stheraventemplate <size_t _Ip, class ..._Tp>
762261272Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
763227825Stheraventypename tuple_element<_Ip, tuple<_Tp...> >::type&&
764232924Stheravenget(tuple<_Tp...>&& __t) _NOEXCEPT
765227825Stheraven{
766227825Stheraven    typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
767227825Stheraven    return static_cast<type&&>(
768227825Stheraven             static_cast<__tuple_leaf<_Ip, type>&&>(__t.base_).get());
769227825Stheraven}
770227825Stheraven
771261272Sdim#if _LIBCPP_STD_VER > 11
772261272Sdim// get by type
773261272Sdimtemplate <typename _T1, size_t _Idx, typename... _Args>
774261272Sdimstruct __find_exactly_one_t_helper;
775261272Sdim
776261272Sdim// -- find exactly one
777261272Sdimtemplate <typename _T1, size_t _Idx, typename... _Args>
778261272Sdimstruct __find_exactly_one_t_checker {
779261272Sdim    static constexpr size_t value = _Idx;
780261272Sdim//  Check the rest of the list to make sure there's only one
781261272Sdim    static_assert ( __find_exactly_one_t_helper<_T1, 0, _Args...>::value == -1, "type can only occur once in type list" );
782261272Sdim    };
783261272Sdim
784261272Sdim
785261272Sdimtemplate <typename _T1, size_t _Idx>
786261272Sdimstruct __find_exactly_one_t_helper <_T1, _Idx> {
787261272Sdim    static constexpr size_t value = -1;
788261272Sdim    };
789261272Sdim
790261272Sdimtemplate <typename _T1, size_t _Idx, typename _Head, typename... _Args>
791261272Sdimstruct __find_exactly_one_t_helper <_T1, _Idx, _Head, _Args...> {
792261272Sdim    static constexpr size_t value =
793261272Sdim        std::conditional<
794261272Sdim            std::is_same<_T1, _Head>::value,
795261272Sdim            __find_exactly_one_t_checker<_T1, _Idx,   _Args...>,
796261272Sdim            __find_exactly_one_t_helper <_T1, _Idx+1, _Args...>
797261272Sdim        >::type::value;
798261272Sdim    };
799261272Sdim
800261272Sdimtemplate <typename _T1, typename... _Args>
801261272Sdimstruct __find_exactly_one_t {
802261272Sdim    static constexpr size_t value = __find_exactly_one_t_helper<_T1, 0, _Args...>::value;
803261272Sdim    static_assert ( value != -1, "type not found in type list" );
804261272Sdim    };
805261272Sdim
806261272Sdimtemplate <class _T1, class... _Args>
807261272Sdiminline _LIBCPP_INLINE_VISIBILITY
808261272Sdimconstexpr _T1& get(tuple<_Args...>& __tup) noexcept
809261272Sdim{
810261272Sdim    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
811261272Sdim}
812261272Sdim
813261272Sdimtemplate <class _T1, class... _Args>
814261272Sdiminline _LIBCPP_INLINE_VISIBILITY
815261272Sdimconstexpr _T1 const& get(tuple<_Args...> const& __tup) noexcept
816261272Sdim{
817261272Sdim    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
818261272Sdim}
819261272Sdim
820261272Sdimtemplate <class _T1, class... _Args>
821261272Sdiminline _LIBCPP_INLINE_VISIBILITY
822261272Sdimconstexpr _T1&& get(tuple<_Args...>&& __tup) noexcept
823261272Sdim{
824261272Sdim    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));
825261272Sdim}
826261272Sdim
827261272Sdim#endif
828261272Sdim
829227825Stheraven// tie
830227825Stheraven
831227825Stheraventemplate <class ..._Tp>
832276792Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
833227825Stheraventuple<_Tp&...>
834241900Sdimtie(_Tp&... __t) _NOEXCEPT
835227825Stheraven{
836227825Stheraven    return tuple<_Tp&...>(__t...);
837227825Stheraven}
838227825Stheraven
839227825Stheraventemplate <class _Up>
840227825Stheravenstruct __ignore_t
841227825Stheraven{
842227825Stheraven    template <class _Tp>
843227825Stheraven        _LIBCPP_INLINE_VISIBILITY
844227825Stheraven        const __ignore_t& operator=(_Tp&&) const {return *this;}
845227825Stheraven};
846227825Stheraven
847227825Stheravennamespace { const __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>(); }
848227825Stheraven
849261272Sdimtemplate <class _Tp> class _LIBCPP_TYPE_VIS_ONLY reference_wrapper;
850227825Stheraven
851227825Stheraventemplate <class _Tp>
852276792Sdimstruct __make_tuple_return_impl
853227825Stheraven{
854227825Stheraven    typedef _Tp type;
855227825Stheraven};
856227825Stheraven
857227825Stheraventemplate <class _Tp>
858276792Sdimstruct __make_tuple_return_impl<reference_wrapper<_Tp> >
859227825Stheraven{
860227825Stheraven    typedef _Tp& type;
861227825Stheraven};
862227825Stheraven
863227825Stheraventemplate <class _Tp>
864227825Stheravenstruct __make_tuple_return
865227825Stheraven{
866276792Sdim    typedef typename __make_tuple_return_impl<typename decay<_Tp>::type>::type type;
867227825Stheraven};
868227825Stheraven
869227825Stheraventemplate <class... _Tp>
870261272Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
871227825Stheraventuple<typename __make_tuple_return<_Tp>::type...>
872227825Stheravenmake_tuple(_Tp&&... __t)
873227825Stheraven{
874227825Stheraven    return tuple<typename __make_tuple_return<_Tp>::type...>(_VSTD::forward<_Tp>(__t)...);
875227825Stheraven}
876227825Stheraven
877227825Stheraventemplate <class... _Tp>
878261272Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
879227825Stheraventuple<_Tp&&...>
880241900Sdimforward_as_tuple(_Tp&&... __t) _NOEXCEPT
881227825Stheraven{
882227825Stheraven    return tuple<_Tp&&...>(_VSTD::forward<_Tp>(__t)...);
883227825Stheraven}
884227825Stheraven
885232924Stheraventemplate <size_t _Ip>
886227825Stheravenstruct __tuple_equal
887227825Stheraven{
888227825Stheraven    template <class _Tp, class _Up>
889261272Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
890227825Stheraven    bool operator()(const _Tp& __x, const _Up& __y)
891227825Stheraven    {
892276792Sdim        return __tuple_equal<_Ip - 1>()(__x, __y) && _VSTD::get<_Ip-1>(__x) == _VSTD::get<_Ip-1>(__y);
893227825Stheraven    }
894227825Stheraven};
895227825Stheraven
896227825Stheraventemplate <>
897227825Stheravenstruct __tuple_equal<0>
898227825Stheraven{
899227825Stheraven    template <class _Tp, class _Up>
900261272Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
901227825Stheraven    bool operator()(const _Tp&, const _Up&)
902227825Stheraven    {
903227825Stheraven        return true;
904227825Stheraven    }
905227825Stheraven};
906227825Stheraven
907227825Stheraventemplate <class ..._Tp, class ..._Up>
908261272Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
909227825Stheravenbool
910227825Stheravenoperator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
911227825Stheraven{
912227825Stheraven    return __tuple_equal<sizeof...(_Tp)>()(__x, __y);
913227825Stheraven}
914227825Stheraven
915227825Stheraventemplate <class ..._Tp, class ..._Up>
916261272Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
917227825Stheravenbool
918227825Stheravenoperator!=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
919227825Stheraven{
920227825Stheraven    return !(__x == __y);
921227825Stheraven}
922227825Stheraven
923232924Stheraventemplate <size_t _Ip>
924227825Stheravenstruct __tuple_less
925227825Stheraven{
926227825Stheraven    template <class _Tp, class _Up>
927261272Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
928227825Stheraven    bool operator()(const _Tp& __x, const _Up& __y)
929227825Stheraven    {
930232924Stheraven        return __tuple_less<_Ip-1>()(__x, __y) ||
931276792Sdim             (!__tuple_less<_Ip-1>()(__y, __x) && _VSTD::get<_Ip-1>(__x) < _VSTD::get<_Ip-1>(__y));
932227825Stheraven    }
933227825Stheraven};
934227825Stheraven
935227825Stheraventemplate <>
936227825Stheravenstruct __tuple_less<0>
937227825Stheraven{
938227825Stheraven    template <class _Tp, class _Up>
939261272Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
940227825Stheraven    bool operator()(const _Tp&, const _Up&)
941227825Stheraven    {
942227825Stheraven        return false;
943227825Stheraven    }
944227825Stheraven};
945227825Stheraven
946227825Stheraventemplate <class ..._Tp, class ..._Up>
947261272Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
948227825Stheravenbool
949227825Stheravenoperator<(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
950227825Stheraven{
951227825Stheraven    return __tuple_less<sizeof...(_Tp)>()(__x, __y);
952227825Stheraven}
953227825Stheraven
954227825Stheraventemplate <class ..._Tp, class ..._Up>
955261272Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
956227825Stheravenbool
957227825Stheravenoperator>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
958227825Stheraven{
959227825Stheraven    return __y < __x;
960227825Stheraven}
961227825Stheraven
962227825Stheraventemplate <class ..._Tp, class ..._Up>
963261272Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
964227825Stheravenbool
965227825Stheravenoperator>=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
966227825Stheraven{
967227825Stheraven    return !(__x < __y);
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 !(__y < __x);
976227825Stheraven}
977227825Stheraven
978227825Stheraven// tuple_cat
979227825Stheraven
980227825Stheraventemplate <class _Tp, class _Up> struct __tuple_cat_type;
981227825Stheraven
982227825Stheraventemplate <class ..._Ttypes, class ..._Utypes>
983227825Stheravenstruct __tuple_cat_type<tuple<_Ttypes...>, __tuple_types<_Utypes...> >
984227825Stheraven{
985227825Stheraven    typedef tuple<_Ttypes..., _Utypes...> type;
986227825Stheraven};
987227825Stheraven
988227825Stheraventemplate <class _ResultTuple, bool _Is_Tuple0TupleLike, class ..._Tuples>
989227825Stheravenstruct __tuple_cat_return_1
990227825Stheraven{
991227825Stheraven};
992227825Stheraven
993227825Stheraventemplate <class ..._Types, class _Tuple0>
994227825Stheravenstruct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0>
995227825Stheraven{
996227825Stheraven    typedef typename __tuple_cat_type<tuple<_Types...>,
997227825Stheraven            typename __make_tuple_types<typename remove_reference<_Tuple0>::type>::type>::type
998227825Stheraven                                                                           type;
999227825Stheraven};
1000227825Stheraven
1001227825Stheraventemplate <class ..._Types, class _Tuple0, class _Tuple1, class ..._Tuples>
1002227825Stheravenstruct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0, _Tuple1, _Tuples...>
1003227825Stheraven    : public __tuple_cat_return_1<
1004227825Stheraven                 typename __tuple_cat_type<
1005227825Stheraven                     tuple<_Types...>,
1006227825Stheraven                     typename __make_tuple_types<typename remove_reference<_Tuple0>::type>::type
1007227825Stheraven                 >::type,
1008227825Stheraven                 __tuple_like<typename remove_reference<_Tuple1>::type>::value,
1009227825Stheraven                 _Tuple1, _Tuples...>
1010227825Stheraven{
1011227825Stheraven};
1012227825Stheraven
1013227825Stheraventemplate <class ..._Tuples> struct __tuple_cat_return;
1014227825Stheraven
1015227825Stheraventemplate <class _Tuple0, class ..._Tuples>
1016227825Stheravenstruct __tuple_cat_return<_Tuple0, _Tuples...>
1017227825Stheraven    : public __tuple_cat_return_1<tuple<>,
1018227825Stheraven         __tuple_like<typename remove_reference<_Tuple0>::type>::value, _Tuple0,
1019227825Stheraven                                                                     _Tuples...>
1020227825Stheraven{
1021227825Stheraven};
1022227825Stheraven
1023227825Stheraventemplate <>
1024227825Stheravenstruct __tuple_cat_return<>
1025227825Stheraven{
1026227825Stheraven    typedef tuple<> type;
1027227825Stheraven};
1028227825Stheraven
1029261272Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1030227825Stheraventuple<>
1031227825Stheraventuple_cat()
1032227825Stheraven{
1033227825Stheraven    return tuple<>();
1034227825Stheraven}
1035227825Stheraven
1036232924Stheraventemplate <class _Rp, class _Indices, class _Tuple0, class ..._Tuples>
1037227825Stheravenstruct __tuple_cat_return_ref_imp;
1038227825Stheraven
1039227825Stheraventemplate <class ..._Types, size_t ..._I0, class _Tuple0>
1040227825Stheravenstruct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, _Tuple0>
1041227825Stheraven{
1042227825Stheraven    typedef typename remove_reference<_Tuple0>::type _T0;
1043227825Stheraven    typedef tuple<_Types..., typename __apply_cv<_Tuple0,
1044227825Stheraven                          typename tuple_element<_I0, _T0>::type>::type&&...> type;
1045227825Stheraven};
1046227825Stheraven
1047227825Stheraventemplate <class ..._Types, size_t ..._I0, class _Tuple0, class _Tuple1, class ..._Tuples>
1048227825Stheravenstruct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>,
1049227825Stheraven                                  _Tuple0, _Tuple1, _Tuples...>
1050227825Stheraven    : public __tuple_cat_return_ref_imp<
1051227825Stheraven         tuple<_Types..., typename __apply_cv<_Tuple0,
1052227825Stheraven               typename tuple_element<_I0,
1053227825Stheraven                  typename remove_reference<_Tuple0>::type>::type>::type&&...>,
1054227825Stheraven         typename __make_tuple_indices<tuple_size<typename
1055227825Stheraven                                 remove_reference<_Tuple1>::type>::value>::type,
1056227825Stheraven         _Tuple1, _Tuples...>
1057227825Stheraven{
1058227825Stheraven};
1059227825Stheraven
1060227825Stheraventemplate <class _Tuple0, class ..._Tuples>
1061227825Stheravenstruct __tuple_cat_return_ref
1062227825Stheraven    : public __tuple_cat_return_ref_imp<tuple<>,
1063227825Stheraven               typename __make_tuple_indices<
1064227825Stheraven                        tuple_size<typename remove_reference<_Tuple0>::type>::value
1065227825Stheraven               >::type, _Tuple0, _Tuples...>
1066227825Stheraven{
1067227825Stheraven};
1068227825Stheraven
1069227825Stheraventemplate <class _Types, class _I0, class _J0>
1070227825Stheravenstruct __tuple_cat;
1071227825Stheraven
1072227825Stheraventemplate <class ..._Types, size_t ..._I0, size_t ..._J0>
1073227825Stheravenstruct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J0...> >
1074227825Stheraven{
1075227825Stheraven    template <class _Tuple0>
1076261272Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1077227825Stheraven    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&>::type
1078227825Stheraven    operator()(tuple<_Types...> __t, _Tuple0&& __t0)
1079227825Stheraven    {
1080276792Sdim        return forward_as_tuple(_VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
1081276792Sdim                                      _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...);
1082227825Stheraven    }
1083227825Stheraven
1084227825Stheraven    template <class _Tuple0, class _Tuple1, class ..._Tuples>
1085261272Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1086227825Stheraven    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&, _Tuple1&&, _Tuples&&...>::type
1087227825Stheraven    operator()(tuple<_Types...> __t, _Tuple0&& __t0, _Tuple1&& __t1, _Tuples&& ...__tpls)
1088227825Stheraven    {
1089227825Stheraven        typedef typename remove_reference<_Tuple0>::type _T0;
1090227825Stheraven        typedef typename remove_reference<_Tuple1>::type _T1;
1091227825Stheraven        return __tuple_cat<
1092227825Stheraven           tuple<_Types..., typename __apply_cv<_Tuple0, typename tuple_element<_J0, _T0>::type>::type&&...>,
1093227825Stheraven           typename __make_tuple_indices<sizeof ...(_Types) + tuple_size<_T0>::value>::type,
1094227825Stheraven           typename __make_tuple_indices<tuple_size<_T1>::value>::type>()
1095261272Sdim                           (forward_as_tuple(
1096276792Sdim                              _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
1097276792Sdim                              _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...
1098227825Stheraven                            ),
1099227825Stheraven                            _VSTD::forward<_Tuple1>(__t1),
1100227825Stheraven                            _VSTD::forward<_Tuples>(__tpls)...);
1101227825Stheraven    }
1102227825Stheraven};
1103227825Stheraven
1104227825Stheraventemplate <class _Tuple0, class... _Tuples>
1105261272Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1106227825Stheraventypename __tuple_cat_return<_Tuple0, _Tuples...>::type
1107227825Stheraventuple_cat(_Tuple0&& __t0, _Tuples&&... __tpls)
1108227825Stheraven{
1109227825Stheraven    typedef typename remove_reference<_Tuple0>::type _T0;
1110227825Stheraven    return __tuple_cat<tuple<>, __tuple_indices<>,
1111227825Stheraven                  typename __make_tuple_indices<tuple_size<_T0>::value>::type>()
1112227825Stheraven                  (tuple<>(), _VSTD::forward<_Tuple0>(__t0),
1113227825Stheraven                                            _VSTD::forward<_Tuples>(__tpls)...);
1114227825Stheraven}
1115227825Stheraven
1116227825Stheraventemplate <class ..._Tp, class _Alloc>
1117261272Sdimstruct _LIBCPP_TYPE_VIS_ONLY uses_allocator<tuple<_Tp...>, _Alloc>
1118227825Stheraven    : true_type {};
1119227825Stheraven
1120227825Stheraventemplate <class _T1, class _T2>
1121227825Stheraventemplate <class... _Args1, class... _Args2, size_t ..._I1, size_t ..._I2>
1122227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1123227825Stheravenpair<_T1, _T2>::pair(piecewise_construct_t,
1124227825Stheraven                     tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,
1125227825Stheraven                     __tuple_indices<_I1...>, __tuple_indices<_I2...>)
1126276792Sdim    :  first(_VSTD::forward<_Args1>(_VSTD::get<_I1>( __first_args))...),
1127276792Sdim      second(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...)
1128227825Stheraven{
1129227825Stheraven}
1130227825Stheraven
1131227825Stheraven#endif  // _LIBCPP_HAS_NO_VARIADICS
1132227825Stheraven
1133227825Stheraven_LIBCPP_END_NAMESPACE_STD
1134227825Stheraven
1135227825Stheraven#endif  // _LIBCPP_TUPLE
1136