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();
24262801Sdim    explicit tuple(const T&...);  // constexpr in C++14
25227825Stheraven    template <class... U>
26262801Sdim        explicit tuple(U&&...);  // constexpr in C++14
27227825Stheraven    tuple(const tuple&) = default;
28227825Stheraven    tuple(tuple&&) = default;
29227825Stheraven    template <class... U>
30262801Sdim        tuple(const tuple<U...>&);  // constexpr in C++14
31227825Stheraven    template <class... U>
32262801Sdim        tuple(tuple<U...>&&);  // constexpr in C++14
33227825Stheraven    template <class U1, class U2>
34262801Sdim        tuple(const pair<U1, U2>&); // iff sizeof...(T) == 2 // constexpr in C++14
35227825Stheraven    template <class U1, class U2>
36262801Sdim        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
75262801Sdimtemplate <class... T> tuple<V...>  make_tuple(T&&...); // constexpr in C++14
76262801Sdimtemplate <class... T> tuple<ATypes...> forward_as_tuple(T&&...) noexcept; // constexpr in C++14
77278724Sdimtemplate <class... T> tuple<T&...> tie(T&...) noexcept; // constexpr in C++14
78262801Sdimtemplate <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...>>;
85278724Sdimtemplate <size_t _Ip, class ..._Tp>
86278724Sdim  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&
91262801Sdim    get(tuple<T...>&) noexcept; // constexpr in C++14
92227825Stheraventemplate <intsize_t I, class... T>
93278724Sdim    typename const tuple_element<I, tuple<T...>>::type &
94262801Sdim    get(const tuple<T...>&) noexcept; // constexpr in C++14
95227825Stheraventemplate <intsize_t I, class... T>
96227825Stheraven    typename tuple_element<I, tuple<T...>>::type&&
97262801Sdim    get(tuple<T...>&&) noexcept; // constexpr in C++14
98227825Stheraven
99262801Sdimtemplate <class T1, class... T>
100262801Sdim    constexpr T1& get(tuple<T...>&) noexcept;  // C++14
101262801Sdimtemplate <class T1, class... T>
102262801Sdim    constexpr T1 const& get(const tuple<T...>&) noexcept;   // C++14
103262801Sdimtemplate <class T1, class... T>
104262801Sdim    constexpr T1&& get(tuple<T...>&&) noexcept;   // C++14
105262801Sdim
106227825Stheraven// 20.4.1.6, relational operators:
107262801Sdimtemplate<class... T, class... U> bool operator==(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
108262801Sdimtemplate<class... T, class... U> bool operator<(const tuple<T...>&, const tuple<U...>&);  // constexpr in C++14
109262801Sdimtemplate<class... T, class... U> bool operator!=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
110262801Sdimtemplate<class... T, class... U> bool operator>(const tuple<T...>&, const tuple<U...>&);  // constexpr in C++14
111262801Sdimtemplate<class... T, class... U> bool operator<=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
112262801Sdimtemplate<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>
129232950Stheraven#include <__functional_base>
130232950Stheraven#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>
143262801Sdimclass _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>
151262801Sdimclass _LIBCPP_TYPE_VIS_ONLY tuple_element<_Ip, tuple<_Tp...> >
152227825Stheraven{
153227825Stheravenpublic:
154227825Stheraven    typedef typename tuple_element<_Ip, __tuple_types<_Tp...> >::type type;
155227825Stheraven};
156227825Stheraven
157278724Sdim#if _LIBCPP_STD_VER > 11
158278724Sdimtemplate <size_t _Ip, class ..._Tp>
159278724Sdimusing tuple_element_t = typename tuple_element <_Ip, _Tp...>::type;
160278724Sdim#endif
161278724Sdim
162227825Stheraven// __tuple_leaf
163227825Stheraven
164232950Stheraventemplate <size_t _Ip, class _Hp, bool=is_empty<_Hp>::value
165232950Stheraven#if __has_feature(is_final)
166232950Stheraven                                 && !__is_final(_Hp)
167232950Stheraven#endif
168232950Stheraven         >
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:
186241903Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __tuple_leaf()
187241903Sdim             _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,
213278724Sdim              class = typename enable_if<
214278724Sdim                  __lazy_and<
215278724Sdim                      __lazy_not<is_same<typename decay<_Tp>::type, __tuple_leaf>>
216278724Sdim                    , is_constructible<_Hp, _Tp>
217278724Sdim                    >::value
218278724Sdim                >::type
219278724Sdim            >
220262801Sdim        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
221241903Sdim        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 ||
224232950Stheraven                       (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                                 >
230232950Stheraven                                >::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 ||
240232950Stheraven                       (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                                 >
246232950Stheraven                                >::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 ||
254232950Stheraven                       (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                                 >
260232950Stheraven                                >::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 ||
268232950Stheraven                       (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                                 >
274232950Stheraven                                >::value)),
275227825Stheraven       "Attempted to construct a reference element in a tuple with an rvalue");}
276227825Stheraven
277278724Sdim    __tuple_leaf(const __tuple_leaf& __t) = default;
278278724Sdim    __tuple_leaf(__tuple_leaf&& __t) = default;
279227825Stheraven
280227825Stheraven    template <class _Tp>
281227825Stheraven        _LIBCPP_INLINE_VISIBILITY
282227825Stheraven        __tuple_leaf&
283241903Sdim        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
296262801Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11       _Hp& get()       _NOEXCEPT {return value;}
297262801Sdim    _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:
307241903Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __tuple_leaf()
308241903Sdim             _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,
325278724Sdim              class = typename enable_if<
326278724Sdim                  __lazy_and<
327278724Sdim                        __lazy_not<is_same<typename decay<_Tp>::type, __tuple_leaf>>
328278724Sdim                      , is_constructible<_Hp, _Tp>
329278724Sdim                    >::value
330278724Sdim                >::type
331278724Sdim            >
332262801Sdim        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
333241903Sdim        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
351278724Sdim    __tuple_leaf(__tuple_leaf const &) = default;
352278724Sdim    __tuple_leaf(__tuple_leaf &&) = default;
353278724Sdim
354227825Stheraven    template <class _Tp>
355227825Stheraven        _LIBCPP_INLINE_VISIBILITY
356227825Stheraven        __tuple_leaf&
357241903Sdim        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
371262801Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11       _Hp& get()       _NOEXCEPT {return static_cast<_Hp&>(*this);}
372262801Sdim    _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
377241903Sdimvoid __swallow(_Tp&&...) _NOEXCEPT {}
378227825Stheraven
379278724Sdimtemplate <bool ..._Pred>
380278724Sdimstruct __all
381278724Sdim    : is_same<__all<_Pred...>, __all<(_Pred, true)...>>
382278724Sdim{ };
383227825Stheraven
384278724Sdimtemplate <class _Tp>
385278724Sdimstruct __all_default_constructible;
386227825Stheraven
387278724Sdimtemplate <class ..._Tp>
388278724Sdimstruct __all_default_constructible<__tuple_types<_Tp...>>
389278724Sdim    : __all<is_default_constructible<_Tp>::value...>
390278724Sdim{ };
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{
400241903Sdim    _LIBCPP_INLINE_VISIBILITY
401241903Sdim    _LIBCPP_CONSTEXPR __tuple_impl()
402241903Sdim        _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
403241903Sdim
404227825Stheraven    template <size_t ..._Uf, class ..._Tf,
405227825Stheraven              size_t ..._Ul, class ..._Tl, class ..._Up>
406262801Sdim        _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...>,
410241903Sdim                     _Up&&... __u)
411241903Sdim                     _NOEXCEPT_((__all<is_nothrow_constructible<_Tf, _Up>::value...>::value &&
412241903Sdim                                 __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                      <
433249998Sdim                         __tuple_constructible<_Tuple, tuple<_Tp...> >::value
434227825Stheraven                      >::type
435227825Stheraven             >
436262801Sdim        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
437241903Sdim        __tuple_impl(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_constructible<_Tp, typename tuple_element<_Indx,
438241903Sdim                                       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
464241903Sdim        operator=(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_assignable<_Tp&, typename tuple_element<_Indx,
465241903Sdim                                       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
472262801Sdim    __tuple_impl(const __tuple_impl&) = default;
473262801Sdim    __tuple_impl(__tuple_impl&&) = default;
474232950Stheraven
475227825Stheraven    _LIBCPP_INLINE_VISIBILITY
476262801Sdim    __tuple_impl&
477262801Sdim    operator=(const __tuple_impl& __t) _NOEXCEPT_((__all<is_nothrow_copy_assignable<_Tp>::value...>::value))
478262801Sdim    {
479262801Sdim        __swallow(__tuple_leaf<_Indx, _Tp>::operator=(static_cast<const __tuple_leaf<_Indx, _Tp>&>(__t).get())...);
480262801Sdim        return *this;
481262801Sdim    }
482262801Sdim
483262801Sdim    _LIBCPP_INLINE_VISIBILITY
484262801Sdim    __tuple_impl&
485262801Sdim    operator=(__tuple_impl&& __t) _NOEXCEPT_((__all<is_nothrow_move_assignable<_Tp>::value...>::value))
486262801Sdim    {
487262801Sdim        __swallow(__tuple_leaf<_Indx, _Tp>::operator=(_VSTD::forward<_Tp>(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t).get()))...);
488262801Sdim        return *this;
489262801Sdim    }
490262801Sdim
491262801Sdim    _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>
500262801Sdimclass _LIBCPP_TYPE_VIS_ONLY tuple
501227825Stheraven{
502227825Stheraven    typedef __tuple_impl<typename __make_tuple_indices<sizeof...(_Tp)>::type, _Tp...> base;
503227825Stheraven
504227825Stheraven    base base_;
505227825Stheraven
506262801Sdim    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
507232950Stheraven        typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT;
508262801Sdim    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
509232950Stheraven        const typename tuple_element<_Jp, tuple<_Up...> >::type& get(const tuple<_Up...>&) _NOEXCEPT;
510262801Sdim    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
511232950Stheraven        typename tuple_element<_Jp, tuple<_Up...> >::type&& get(tuple<_Up...>&&) _NOEXCEPT;
512227825Stheravenpublic:
513227825Stheraven
514278724Sdim    template <bool _Dummy = true, class _Up = typename enable_if<
515278724Sdim        __all<(_Dummy && is_default_constructible<_Tp>::value)...>::value
516278724Sdim    >::type>
517227825Stheraven    _LIBCPP_INLINE_VISIBILITY
518241903Sdim    _LIBCPP_CONSTEXPR tuple()
519241903Sdim        _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
520241903Sdim
521262801Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
522241903Sdim    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,
542234976Stheraven              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
552278724Sdim                         >::value &&
553278724Sdim                         __all_default_constructible<
554278724Sdim                            typename __make_tuple_types<tuple, sizeof...(_Tp),
555278724Sdim                                sizeof...(_Up) < sizeof...(_Tp) ?
556278724Sdim                                    sizeof...(_Up) :
557278724Sdim                                    sizeof...(_Tp)>::type
558234976Stheraven                         >::value,
559234976Stheraven                         bool
560234976Stheraven                      >::type = false
561227825Stheraven             >
562262801Sdim        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
563234976Stheraven        tuple(_Up&&... __u)
564241903Sdim            _NOEXCEPT_((
565278724Sdim                is_nothrow_constructible<base,
566241903Sdim                    typename __make_tuple_indices<sizeof...(_Up)>::type,
567241903Sdim                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type,
568241903Sdim                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type,
569241903Sdim                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type,
570241903Sdim                    _Up...
571241903Sdim                >::value
572241903Sdim            ))
573234976Stheraven            : base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
574234976Stheraven                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
575234976Stheraven                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
576234976Stheraven                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
577234976Stheraven                    _VSTD::forward<_Up>(__u)...) {}
578234976Stheraven
579234976Stheraven    template <class ..._Up,
580234976Stheraven              typename enable_if
581234976Stheraven                      <
582234976Stheraven                         sizeof...(_Up) <= sizeof...(_Tp) &&
583234976Stheraven                         __tuple_constructible
584234976Stheraven                         <
585234976Stheraven                            tuple<_Up...>,
586234976Stheraven                            typename __make_tuple_types<tuple,
587234976Stheraven                                     sizeof...(_Up) < sizeof...(_Tp) ?
588234976Stheraven                                        sizeof...(_Up) :
589234976Stheraven                                        sizeof...(_Tp)>::type
590234976Stheraven                         >::value &&
591234976Stheraven                         !__tuple_convertible
592234976Stheraven                         <
593234976Stheraven                            tuple<_Up...>,
594234976Stheraven                            typename __make_tuple_types<tuple,
595234976Stheraven                                     sizeof...(_Up) < sizeof...(_Tp) ?
596234976Stheraven                                        sizeof...(_Up) :
597234976Stheraven                                        sizeof...(_Tp)>::type
598278724Sdim                         >::value &&
599278724Sdim                         __all_default_constructible<
600278724Sdim                            typename __make_tuple_types<tuple, sizeof...(_Tp),
601278724Sdim                                sizeof...(_Up) < sizeof...(_Tp) ?
602278724Sdim                                    sizeof...(_Up) :
603278724Sdim                                    sizeof...(_Tp)>::type
604234976Stheraven                         >::value,
605234976Stheraven                         bool
606234976Stheraven                      >::type =false
607234976Stheraven             >
608262801Sdim        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
609227825Stheraven        explicit
610227825Stheraven        tuple(_Up&&... __u)
611241903Sdim            _NOEXCEPT_((
612278724Sdim                is_nothrow_constructible<base,
613241903Sdim                    typename __make_tuple_indices<sizeof...(_Up)>::type,
614241903Sdim                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type,
615241903Sdim                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type,
616241903Sdim                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type,
617241903Sdim                    _Up...
618241903Sdim                >::value
619241903Sdim            ))
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
637278724Sdim                         >::value &&
638278724Sdim                         __all_default_constructible<
639278724Sdim                            typename __make_tuple_types<tuple, sizeof...(_Tp),
640278724Sdim                                sizeof...(_Up) < sizeof...(_Tp) ?
641278724Sdim                                    sizeof...(_Up) :
642278724Sdim                                    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,
656234976Stheraven              typename enable_if
657227825Stheraven                      <
658234976Stheraven                         __tuple_convertible<_Tuple, tuple>::value,
659234976Stheraven                         bool
660234976Stheraven                      >::type = false
661227825Stheraven             >
662262801Sdim        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
663241903Sdim        tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<base, _Tuple>::value))
664227825Stheraven            : base_(_VSTD::forward<_Tuple>(__t)) {}
665227825Stheraven
666234976Stheraven    template <class _Tuple,
667234976Stheraven              typename enable_if
668234976Stheraven                      <
669234976Stheraven                         __tuple_constructible<_Tuple, tuple>::value &&
670234976Stheraven                         !__tuple_convertible<_Tuple, tuple>::value,
671234976Stheraven                         bool
672234976Stheraven                      >::type = false
673234976Stheraven             >
674262801Sdim        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
675234976Stheraven        explicit
676241903Sdim        tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<base, _Tuple>::value))
677234976Stheraven            : base_(_VSTD::forward<_Tuple>(__t)) {}
678234976Stheraven
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&
697241903Sdim        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 <>
709262801Sdimclass _LIBCPP_TYPE_VIS_ONLY tuple<>
710227825Stheraven{
711227825Stheravenpublic:
712227825Stheraven    _LIBCPP_INLINE_VISIBILITY
713241903Sdim    _LIBCPP_CONSTEXPR tuple() _NOEXCEPT {}
714227825Stheraven    template <class _Alloc>
715227825Stheraven    _LIBCPP_INLINE_VISIBILITY
716241903Sdim        tuple(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
717227825Stheraven    template <class _Alloc>
718227825Stheraven    _LIBCPP_INLINE_VISIBILITY
719241903Sdim        tuple(allocator_arg_t, const _Alloc&, const tuple&) _NOEXCEPT {}
720232950Stheraven    template <class _Up>
721227825Stheraven    _LIBCPP_INLINE_VISIBILITY
722241903Sdim        tuple(array<_Up, 0>) _NOEXCEPT {}
723232950Stheraven    template <class _Alloc, class _Up>
724227825Stheraven    _LIBCPP_INLINE_VISIBILITY
725241903Sdim        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>
744262801Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
745227825Stheraventypename tuple_element<_Ip, tuple<_Tp...> >::type&
746232950Stheravenget(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>
753262801Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
754227825Stheravenconst typename tuple_element<_Ip, tuple<_Tp...> >::type&
755232950Stheravenget(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>
762262801Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
763227825Stheraventypename tuple_element<_Ip, tuple<_Tp...> >::type&&
764232950Stheravenget(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
771262801Sdim#if _LIBCPP_STD_VER > 11
772262801Sdim// get by type
773262801Sdimtemplate <typename _T1, size_t _Idx, typename... _Args>
774262801Sdimstruct __find_exactly_one_t_helper;
775262801Sdim
776262801Sdim// -- find exactly one
777262801Sdimtemplate <typename _T1, size_t _Idx, typename... _Args>
778262801Sdimstruct __find_exactly_one_t_checker {
779262801Sdim    static constexpr size_t value = _Idx;
780262801Sdim//  Check the rest of the list to make sure there's only one
781262801Sdim    static_assert ( __find_exactly_one_t_helper<_T1, 0, _Args...>::value == -1, "type can only occur once in type list" );
782262801Sdim    };
783262801Sdim
784262801Sdim
785262801Sdimtemplate <typename _T1, size_t _Idx>
786262801Sdimstruct __find_exactly_one_t_helper <_T1, _Idx> {
787262801Sdim    static constexpr size_t value = -1;
788262801Sdim    };
789262801Sdim
790262801Sdimtemplate <typename _T1, size_t _Idx, typename _Head, typename... _Args>
791262801Sdimstruct __find_exactly_one_t_helper <_T1, _Idx, _Head, _Args...> {
792262801Sdim    static constexpr size_t value =
793262801Sdim        std::conditional<
794262801Sdim            std::is_same<_T1, _Head>::value,
795262801Sdim            __find_exactly_one_t_checker<_T1, _Idx,   _Args...>,
796262801Sdim            __find_exactly_one_t_helper <_T1, _Idx+1, _Args...>
797262801Sdim        >::type::value;
798262801Sdim    };
799262801Sdim
800262801Sdimtemplate <typename _T1, typename... _Args>
801262801Sdimstruct __find_exactly_one_t {
802262801Sdim    static constexpr size_t value = __find_exactly_one_t_helper<_T1, 0, _Args...>::value;
803262801Sdim    static_assert ( value != -1, "type not found in type list" );
804262801Sdim    };
805262801Sdim
806262801Sdimtemplate <class _T1, class... _Args>
807262801Sdiminline _LIBCPP_INLINE_VISIBILITY
808262801Sdimconstexpr _T1& get(tuple<_Args...>& __tup) noexcept
809262801Sdim{
810262801Sdim    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
811262801Sdim}
812262801Sdim
813262801Sdimtemplate <class _T1, class... _Args>
814262801Sdiminline _LIBCPP_INLINE_VISIBILITY
815262801Sdimconstexpr _T1 const& get(tuple<_Args...> const& __tup) noexcept
816262801Sdim{
817262801Sdim    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
818262801Sdim}
819262801Sdim
820262801Sdimtemplate <class _T1, class... _Args>
821262801Sdiminline _LIBCPP_INLINE_VISIBILITY
822262801Sdimconstexpr _T1&& get(tuple<_Args...>&& __tup) noexcept
823262801Sdim{
824262801Sdim    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));
825262801Sdim}
826262801Sdim
827262801Sdim#endif
828262801Sdim
829227825Stheraven// tie
830227825Stheraven
831227825Stheraventemplate <class ..._Tp>
832278724Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
833227825Stheraventuple<_Tp&...>
834241903Sdimtie(_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
849262801Sdimtemplate <class _Tp> class _LIBCPP_TYPE_VIS_ONLY reference_wrapper;
850227825Stheraven
851227825Stheraventemplate <class _Tp>
852278724Sdimstruct __make_tuple_return_impl
853227825Stheraven{
854227825Stheraven    typedef _Tp type;
855227825Stheraven};
856227825Stheraven
857227825Stheraventemplate <class _Tp>
858278724Sdimstruct __make_tuple_return_impl<reference_wrapper<_Tp> >
859227825Stheraven{
860227825Stheraven    typedef _Tp& type;
861227825Stheraven};
862227825Stheraven
863227825Stheraventemplate <class _Tp>
864227825Stheravenstruct __make_tuple_return
865227825Stheraven{
866278724Sdim    typedef typename __make_tuple_return_impl<typename decay<_Tp>::type>::type type;
867227825Stheraven};
868227825Stheraven
869227825Stheraventemplate <class... _Tp>
870262801Sdiminline _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>
878262801Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
879227825Stheraventuple<_Tp&&...>
880241903Sdimforward_as_tuple(_Tp&&... __t) _NOEXCEPT
881227825Stheraven{
882227825Stheraven    return tuple<_Tp&&...>(_VSTD::forward<_Tp>(__t)...);
883227825Stheraven}
884227825Stheraven
885232950Stheraventemplate <size_t _Ip>
886227825Stheravenstruct __tuple_equal
887227825Stheraven{
888227825Stheraven    template <class _Tp, class _Up>
889262801Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
890227825Stheraven    bool operator()(const _Tp& __x, const _Up& __y)
891227825Stheraven    {
892278724Sdim        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>
900262801Sdim    _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>
908262801Sdiminline _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>
916262801Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
917227825Stheravenbool
918227825Stheravenoperator!=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
919227825Stheraven{
920227825Stheraven    return !(__x == __y);
921227825Stheraven}
922227825Stheraven
923232950Stheraventemplate <size_t _Ip>
924227825Stheravenstruct __tuple_less
925227825Stheraven{
926227825Stheraven    template <class _Tp, class _Up>
927262801Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
928227825Stheraven    bool operator()(const _Tp& __x, const _Up& __y)
929227825Stheraven    {
930232950Stheraven        return __tuple_less<_Ip-1>()(__x, __y) ||
931278724Sdim             (!__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>
939262801Sdim    _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>
947262801Sdiminline _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>
955262801Sdiminline _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>
963262801Sdiminline _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>
971262801Sdiminline _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
1029262801Sdiminline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1030227825Stheraventuple<>
1031227825Stheraventuple_cat()
1032227825Stheraven{
1033227825Stheraven    return tuple<>();
1034227825Stheraven}
1035227825Stheraven
1036232950Stheraventemplate <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>
1076262801Sdim    _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    {
1080278724Sdim        return forward_as_tuple(_VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
1081278724Sdim                                      _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...);
1082227825Stheraven    }
1083227825Stheraven
1084227825Stheraven    template <class _Tuple0, class _Tuple1, class ..._Tuples>
1085262801Sdim    _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>()
1095262801Sdim                           (forward_as_tuple(
1096278724Sdim                              _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
1097278724Sdim                              _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>
1105262801Sdiminline _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>
1117262801Sdimstruct _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...>)
1126278724Sdim    :  first(_VSTD::forward<_Args1>(_VSTD::get<_I1>( __first_args))...),
1127278724Sdim      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