tuple revision 249989
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();
24227825Stheraven    explicit tuple(const T&...);
25227825Stheraven    template <class... U>
26227825Stheraven        explicit tuple(U&&...);
27227825Stheraven    tuple(const tuple&) = default;
28227825Stheraven    tuple(tuple&&) = default;
29227825Stheraven    template <class... U>
30227825Stheraven        tuple(const tuple<U...>&);
31227825Stheraven    template <class... U>
32227825Stheraven        tuple(tuple<U...>&&);
33227825Stheraven    template <class U1, class U2>
34227825Stheraven        tuple(const pair<U1, U2>&); // iff sizeof...(T) == 2
35227825Stheraven    template <class U1, class U2>
36227825Stheraven        tuple(pair<U1, U2>&&); // iff sizeof...(T) == 2
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
75227825Stheraventemplate <class... T> tuple<V...>  make_tuple(T&&...);
76227825Stheraventemplate <class... T> tuple<ATypes...> forward_as_tuple(T&&...) noexcept;
77227825Stheraventemplate <class... T> tuple<T&...> tie(T&...) noexcept;
78227825Stheraventemplate <class... Tuples> tuple<CTypes...> tuple_cat(Tuples&&... tpls);
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...>>;
85227825Stheraven
86227825Stheraven// 20.4.1.5, element access:
87227825Stheraventemplate <intsize_t I, class... T>
88227825Stheraven    typename tuple_element<I, tuple<T...>>::type&
89227825Stheraven    get(tuple<T...>&) noexcept;
90227825Stheraventemplate <intsize_t I, class... T>
91227825Stheraven    typename tuple_element<I, tuple<T...>>::type const&
92227825Stheraven    get(const tuple<T...>&) noexcept;
93227825Stheraventemplate <intsize_t I, class... T>
94227825Stheraven    typename tuple_element<I, tuple<T...>>::type&&
95227825Stheraven    get(tuple<T...>&&) noexcept;
96227825Stheraven
97227825Stheraven// 20.4.1.6, relational operators:
98227825Stheraventemplate<class... T, class... U> bool operator==(const tuple<T...>&, const tuple<U...>&);
99227825Stheraventemplate<class... T, class... U> bool operator<(const tuple<T...>&, const tuple<U...>&);
100227825Stheraventemplate<class... T, class... U> bool operator!=(const tuple<T...>&, const tuple<U...>&);
101227825Stheraventemplate<class... T, class... U> bool operator>(const tuple<T...>&, const tuple<U...>&);
102227825Stheraventemplate<class... T, class... U> bool operator<=(const tuple<T...>&, const tuple<U...>&);
103227825Stheraventemplate<class... T, class... U> bool operator>=(const tuple<T...>&, const tuple<U...>&);
104227825Stheraven
105227825Stheraventemplate <class... Types, class Alloc>
106227825Stheraven  struct uses_allocator<tuple<Types...>, Alloc>;
107227825Stheraven
108227825Stheraventemplate <class... Types>
109227825Stheraven  void
110227825Stheraven  swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(noexcept(x.swap(y)));
111227825Stheraven
112227825Stheraven}  // std
113227825Stheraven
114227825Stheraven*/
115227825Stheraven
116227825Stheraven#include <__config>
117227825Stheraven#include <__tuple>
118227825Stheraven#include <cstddef>
119227825Stheraven#include <type_traits>
120232924Stheraven#include <__functional_base>
121232924Stheraven#include <utility>
122227825Stheraven
123227825Stheraven#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
124227825Stheraven#pragma GCC system_header
125227825Stheraven#endif
126227825Stheraven
127227825Stheraven_LIBCPP_BEGIN_NAMESPACE_STD
128227825Stheraven
129232924Stheraven// allocator_arg_t
130232924Stheraven
131249989Sdimstruct _LIBCPP_TYPE_VIS allocator_arg_t { };
132232924Stheraven
133241900Sdim#if defined(_LIBCPP_HAS_NO_CONSTEXPR) || defined(_LIBCPP_BUILDING_MEMORY)
134232924Stheravenextern const allocator_arg_t allocator_arg;
135241900Sdim#else
136241900Sdimconstexpr allocator_arg_t allocator_arg = allocator_arg_t();
137241900Sdim#endif
138232924Stheraven
139232924Stheraven// uses_allocator
140232924Stheraven
141232924Stheraventemplate <class _Tp>
142232924Stheravenstruct __has_allocator_type
143232924Stheraven{
144232924Stheravenprivate:
145242939Stheraven    struct __two {char __lx; char __lxx;};
146232924Stheraven    template <class _Up> static __two __test(...);
147232924Stheraven    template <class _Up> static char __test(typename _Up::allocator_type* = 0);
148232924Stheravenpublic:
149232924Stheraven    static const bool value = sizeof(__test<_Tp>(0)) == 1;
150232924Stheraven};
151232924Stheraven
152232924Stheraventemplate <class _Tp, class _Alloc, bool = __has_allocator_type<_Tp>::value>
153232924Stheravenstruct __uses_allocator
154232924Stheraven    : public integral_constant<bool,
155232924Stheraven        is_convertible<_Alloc, typename _Tp::allocator_type>::value>
156232924Stheraven{
157232924Stheraven};
158232924Stheraven
159232924Stheraventemplate <class _Tp, class _Alloc>
160232924Stheravenstruct __uses_allocator<_Tp, _Alloc, false>
161232924Stheraven    : public false_type
162232924Stheraven{
163232924Stheraven};
164232924Stheraven
165232924Stheraventemplate <class _Tp, class _Alloc>
166249989Sdimstruct _LIBCPP_TYPE_VIS uses_allocator
167232924Stheraven    : public __uses_allocator<_Tp, _Alloc>
168232924Stheraven{
169232924Stheraven};
170232924Stheraven
171227825Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS
172227825Stheraven
173232924Stheraven// uses-allocator construction
174232924Stheraven
175232924Stheraventemplate <class _Tp, class _Alloc, class ..._Args>
176232924Stheravenstruct __uses_alloc_ctor_imp
177232924Stheraven{
178232924Stheraven    static const bool __ua = uses_allocator<_Tp, _Alloc>::value;
179232924Stheraven    static const bool __ic =
180232924Stheraven        is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value;
181232924Stheraven    static const int value = __ua ? 2 - __ic : 0;
182232924Stheraven};
183232924Stheraven
184232924Stheraventemplate <class _Tp, class _Alloc, class ..._Args>
185232924Stheravenstruct __uses_alloc_ctor
186232924Stheraven    : integral_constant<int, __uses_alloc_ctor_imp<_Tp, _Alloc, _Args...>::value>
187232924Stheraven    {};
188232924Stheraven
189232924Stheraven#endif  // _LIBCPP_HAS_NO_VARIADICS
190232924Stheraven
191232924Stheraven#ifndef _LIBCPP_HAS_NO_VARIADICS
192232924Stheraven
193227825Stheraven// tuple_size
194227825Stheraven
195227825Stheraventemplate <class ..._Tp>
196249989Sdimclass _LIBCPP_TYPE_VIS tuple_size<tuple<_Tp...> >
197227825Stheraven    : public integral_constant<size_t, sizeof...(_Tp)>
198227825Stheraven{
199227825Stheraven};
200227825Stheraven
201227825Stheraven// tuple_element
202227825Stheraven
203227825Stheraventemplate <size_t _Ip, class ..._Tp>
204249989Sdimclass _LIBCPP_TYPE_VIS tuple_element<_Ip, tuple<_Tp...> >
205227825Stheraven{
206227825Stheravenpublic:
207227825Stheraven    typedef typename tuple_element<_Ip, __tuple_types<_Tp...> >::type type;
208227825Stheraven};
209227825Stheraven
210227825Stheraven// __tuple_leaf
211227825Stheraven
212232924Stheraventemplate <size_t _Ip, class _Hp, bool=is_empty<_Hp>::value
213232924Stheraven#if __has_feature(is_final)
214232924Stheraven                                 && !__is_final(_Hp)
215232924Stheraven#endif
216232924Stheraven         >
217227825Stheravenclass __tuple_leaf;
218227825Stheraven
219227825Stheraventemplate <size_t _Ip, class _Hp, bool _Ep>
220227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
221227825Stheravenvoid swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y)
222227825Stheraven    _NOEXCEPT_(__is_nothrow_swappable<_Hp>::value)
223227825Stheraven{
224227825Stheraven    swap(__x.get(), __y.get());
225227825Stheraven}
226227825Stheraven
227227825Stheraventemplate <size_t _Ip, class _Hp, bool>
228227825Stheravenclass __tuple_leaf
229227825Stheraven{
230227825Stheraven    _Hp value;
231227825Stheraven
232227825Stheraven    __tuple_leaf& operator=(const __tuple_leaf&);
233227825Stheravenpublic:
234241900Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __tuple_leaf()
235241900Sdim             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) : value()
236227825Stheraven       {static_assert(!is_reference<_Hp>::value,
237227825Stheraven              "Attempted to default construct a reference element in a tuple");}
238227825Stheraven
239227825Stheraven    template <class _Alloc>
240227825Stheraven        _LIBCPP_INLINE_VISIBILITY
241227825Stheraven        __tuple_leaf(integral_constant<int, 0>, const _Alloc&)
242227825Stheraven            : value()
243227825Stheraven        {static_assert(!is_reference<_Hp>::value,
244227825Stheraven              "Attempted to default construct a reference element in a tuple");}
245227825Stheraven
246227825Stheraven    template <class _Alloc>
247227825Stheraven        _LIBCPP_INLINE_VISIBILITY
248227825Stheraven        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
249227825Stheraven            : value(allocator_arg_t(), __a)
250227825Stheraven        {static_assert(!is_reference<_Hp>::value,
251227825Stheraven              "Attempted to default construct a reference element in a tuple");}
252227825Stheraven
253227825Stheraven    template <class _Alloc>
254227825Stheraven        _LIBCPP_INLINE_VISIBILITY
255227825Stheraven        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
256227825Stheraven            : value(__a)
257227825Stheraven        {static_assert(!is_reference<_Hp>::value,
258227825Stheraven              "Attempted to default construct a reference element in a tuple");}
259227825Stheraven
260227825Stheraven    template <class _Tp,
261227825Stheraven              class = typename enable_if<is_constructible<_Hp, _Tp>::value>::type>
262227825Stheraven        _LIBCPP_INLINE_VISIBILITY
263241900Sdim        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
264227825Stheraven            : value(_VSTD::forward<_Tp>(__t))
265227825Stheraven        {static_assert(!is_reference<_Hp>::value ||
266232924Stheraven                       (is_lvalue_reference<_Hp>::value &&
267227825Stheraven                        (is_lvalue_reference<_Tp>::value ||
268227825Stheraven                         is_same<typename remove_reference<_Tp>::type,
269227825Stheraven                                 reference_wrapper<
270227825Stheraven                                    typename remove_reference<_Hp>::type
271227825Stheraven                                 >
272232924Stheraven                                >::value)) ||
273227825Stheraven                        (is_rvalue_reference<_Hp>::value &&
274227825Stheraven                         !is_lvalue_reference<_Tp>::value),
275227825Stheraven       "Attempted to construct a reference element in a tuple with an rvalue");}
276227825Stheraven
277227825Stheraven    template <class _Tp, class _Alloc>
278227825Stheraven        _LIBCPP_INLINE_VISIBILITY
279227825Stheraven        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
280227825Stheraven            : value(_VSTD::forward<_Tp>(__t))
281227825Stheraven        {static_assert(!is_lvalue_reference<_Hp>::value ||
282232924Stheraven                       (is_lvalue_reference<_Hp>::value &&
283227825Stheraven                        (is_lvalue_reference<_Tp>::value ||
284227825Stheraven                         is_same<typename remove_reference<_Tp>::type,
285227825Stheraven                                 reference_wrapper<
286227825Stheraven                                    typename remove_reference<_Hp>::type
287227825Stheraven                                 >
288232924Stheraven                                >::value)),
289227825Stheraven       "Attempted to construct a reference element in a tuple with an rvalue");}
290227825Stheraven
291227825Stheraven    template <class _Tp, class _Alloc>
292227825Stheraven        _LIBCPP_INLINE_VISIBILITY
293227825Stheraven        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
294227825Stheraven            : value(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t))
295227825Stheraven        {static_assert(!is_lvalue_reference<_Hp>::value ||
296232924Stheraven                       (is_lvalue_reference<_Hp>::value &&
297227825Stheraven                        (is_lvalue_reference<_Tp>::value ||
298227825Stheraven                         is_same<typename remove_reference<_Tp>::type,
299227825Stheraven                                 reference_wrapper<
300227825Stheraven                                    typename remove_reference<_Hp>::type
301227825Stheraven                                 >
302232924Stheraven                                >::value)),
303227825Stheraven       "Attempted to construct a reference element in a tuple with an rvalue");}
304227825Stheraven
305227825Stheraven    template <class _Tp, class _Alloc>
306227825Stheraven        _LIBCPP_INLINE_VISIBILITY
307227825Stheraven        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
308227825Stheraven            : value(_VSTD::forward<_Tp>(__t), __a)
309227825Stheraven        {static_assert(!is_lvalue_reference<_Hp>::value ||
310232924Stheraven                       (is_lvalue_reference<_Hp>::value &&
311227825Stheraven                        (is_lvalue_reference<_Tp>::value ||
312227825Stheraven                         is_same<typename remove_reference<_Tp>::type,
313227825Stheraven                                 reference_wrapper<
314227825Stheraven                                    typename remove_reference<_Hp>::type
315227825Stheraven                                 >
316232924Stheraven                                >::value)),
317227825Stheraven       "Attempted to construct a reference element in a tuple with an rvalue");}
318227825Stheraven
319241900Sdim    __tuple_leaf(const __tuple_leaf& __t) _NOEXCEPT_(is_nothrow_copy_constructible<_Hp>::value)
320227825Stheraven        : value(__t.get())
321227825Stheraven        {static_assert(!is_rvalue_reference<_Hp>::value, "Can not copy a tuple with rvalue reference member");}
322227825Stheraven
323227825Stheraven    template <class _Tp>
324227825Stheraven        _LIBCPP_INLINE_VISIBILITY
325227825Stheraven        explicit __tuple_leaf(const __tuple_leaf<_Ip, _Tp>& __t)
326241900Sdim                           _NOEXCEPT_((is_nothrow_constructible<_Hp, const _Tp&>::value))
327227825Stheraven            : value(__t.get()) {}
328227825Stheraven
329227825Stheraven    template <class _Tp>
330227825Stheraven        _LIBCPP_INLINE_VISIBILITY
331227825Stheraven        __tuple_leaf&
332241900Sdim        operator=(_Tp&& __t) _NOEXCEPT_((is_nothrow_assignable<_Hp&, _Tp>::value))
333227825Stheraven        {
334227825Stheraven            value = _VSTD::forward<_Tp>(__t);
335227825Stheraven            return *this;
336227825Stheraven        }
337227825Stheraven
338227825Stheraven    _LIBCPP_INLINE_VISIBILITY
339227825Stheraven    int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
340227825Stheraven    {
341227825Stheraven        _VSTD::swap(*this, __t);
342227825Stheraven        return 0;
343227825Stheraven    }
344227825Stheraven
345241900Sdim    _LIBCPP_INLINE_VISIBILITY       _Hp& get()       _NOEXCEPT {return value;}
346241900Sdim    _LIBCPP_INLINE_VISIBILITY const _Hp& get() const _NOEXCEPT {return value;}
347227825Stheraven};
348227825Stheraven
349227825Stheraventemplate <size_t _Ip, class _Hp>
350227825Stheravenclass __tuple_leaf<_Ip, _Hp, true>
351227825Stheraven    : private _Hp
352227825Stheraven{
353227825Stheraven
354227825Stheraven    __tuple_leaf& operator=(const __tuple_leaf&);
355227825Stheravenpublic:
356241900Sdim    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __tuple_leaf()
357241900Sdim             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) {}
358227825Stheraven
359227825Stheraven    template <class _Alloc>
360227825Stheraven        _LIBCPP_INLINE_VISIBILITY
361227825Stheraven        __tuple_leaf(integral_constant<int, 0>, const _Alloc&) {}
362227825Stheraven
363227825Stheraven    template <class _Alloc>
364227825Stheraven        _LIBCPP_INLINE_VISIBILITY
365227825Stheraven        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
366227825Stheraven            : _Hp(allocator_arg_t(), __a) {}
367227825Stheraven
368227825Stheraven    template <class _Alloc>
369227825Stheraven        _LIBCPP_INLINE_VISIBILITY
370227825Stheraven        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
371227825Stheraven            : _Hp(__a) {}
372227825Stheraven
373227825Stheraven    template <class _Tp,
374227825Stheraven              class = typename enable_if<is_constructible<_Hp, _Tp>::value>::type>
375227825Stheraven        _LIBCPP_INLINE_VISIBILITY
376241900Sdim        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
377227825Stheraven            : _Hp(_VSTD::forward<_Tp>(__t)) {}
378227825Stheraven
379227825Stheraven    template <class _Tp, class _Alloc>
380227825Stheraven        _LIBCPP_INLINE_VISIBILITY
381227825Stheraven        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
382227825Stheraven            : _Hp(_VSTD::forward<_Tp>(__t)) {}
383227825Stheraven
384227825Stheraven    template <class _Tp, class _Alloc>
385227825Stheraven        _LIBCPP_INLINE_VISIBILITY
386227825Stheraven        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
387227825Stheraven            : _Hp(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) {}
388227825Stheraven
389227825Stheraven    template <class _Tp, class _Alloc>
390227825Stheraven        _LIBCPP_INLINE_VISIBILITY
391227825Stheraven        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
392227825Stheraven            : _Hp(_VSTD::forward<_Tp>(__t), __a) {}
393227825Stheraven
394227825Stheraven    template <class _Tp>
395227825Stheraven        _LIBCPP_INLINE_VISIBILITY
396227825Stheraven        explicit __tuple_leaf(const __tuple_leaf<_Ip, _Tp>& __t)
397241900Sdim            _NOEXCEPT_((is_nothrow_constructible<_Hp, const _Tp&>::value))
398227825Stheraven            : _Hp(__t.get()) {}
399227825Stheraven
400227825Stheraven    template <class _Tp>
401227825Stheraven        _LIBCPP_INLINE_VISIBILITY
402227825Stheraven        __tuple_leaf&
403241900Sdim        operator=(_Tp&& __t) _NOEXCEPT_((is_nothrow_assignable<_Hp&, _Tp>::value))
404227825Stheraven        {
405227825Stheraven            _Hp::operator=(_VSTD::forward<_Tp>(__t));
406227825Stheraven            return *this;
407227825Stheraven        }
408227825Stheraven
409227825Stheraven    _LIBCPP_INLINE_VISIBILITY
410227825Stheraven    int
411227825Stheraven    swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
412227825Stheraven    {
413227825Stheraven        _VSTD::swap(*this, __t);
414227825Stheraven        return 0;
415227825Stheraven    }
416227825Stheraven
417241900Sdim    _LIBCPP_INLINE_VISIBILITY       _Hp& get()       _NOEXCEPT {return static_cast<_Hp&>(*this);}
418241900Sdim    _LIBCPP_INLINE_VISIBILITY const _Hp& get() const _NOEXCEPT {return static_cast<const _Hp&>(*this);}
419227825Stheraven};
420227825Stheraven
421227825Stheraventemplate <class ..._Tp>
422227825Stheraven_LIBCPP_INLINE_VISIBILITY
423241900Sdimvoid __swallow(_Tp&&...) _NOEXCEPT {}
424227825Stheraven
425227825Stheraventemplate <bool ...> struct __all;
426227825Stheraven
427227825Stheraventemplate <>
428227825Stheravenstruct __all<>
429227825Stheraven{
430227825Stheraven    static const bool value = true;
431227825Stheraven};
432227825Stheraven
433232924Stheraventemplate <bool _B0, bool ... _Bp>
434232924Stheravenstruct __all<_B0, _Bp...>
435227825Stheraven{
436232924Stheraven    static const bool value = _B0 && __all<_Bp...>::value;
437227825Stheraven};
438227825Stheraven
439227825Stheraven// __tuple_impl
440227825Stheraven
441227825Stheraventemplate<class _Indx, class ..._Tp> struct __tuple_impl;
442227825Stheraven
443227825Stheraventemplate<size_t ..._Indx, class ..._Tp>
444227825Stheravenstruct __tuple_impl<__tuple_indices<_Indx...>, _Tp...>
445227825Stheraven    : public __tuple_leaf<_Indx, _Tp>...
446227825Stheraven{
447241900Sdim    _LIBCPP_INLINE_VISIBILITY
448241900Sdim    _LIBCPP_CONSTEXPR __tuple_impl()
449241900Sdim        _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
450241900Sdim
451227825Stheraven    template <size_t ..._Uf, class ..._Tf,
452227825Stheraven              size_t ..._Ul, class ..._Tl, class ..._Up>
453227825Stheraven        _LIBCPP_INLINE_VISIBILITY
454227825Stheraven        explicit
455227825Stheraven        __tuple_impl(__tuple_indices<_Uf...>, __tuple_types<_Tf...>,
456227825Stheraven                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
457241900Sdim                     _Up&&... __u)
458241900Sdim                     _NOEXCEPT_((__all<is_nothrow_constructible<_Tf, _Up>::value...>::value &&
459241900Sdim                                 __all<is_nothrow_default_constructible<_Tl>::value...>::value)) :
460227825Stheraven            __tuple_leaf<_Uf, _Tf>(_VSTD::forward<_Up>(__u))...,
461227825Stheraven            __tuple_leaf<_Ul, _Tl>()...
462227825Stheraven            {}
463227825Stheraven
464227825Stheraven    template <class _Alloc, size_t ..._Uf, class ..._Tf,
465227825Stheraven              size_t ..._Ul, class ..._Tl, class ..._Up>
466227825Stheraven        _LIBCPP_INLINE_VISIBILITY
467227825Stheraven        explicit
468227825Stheraven        __tuple_impl(allocator_arg_t, const _Alloc& __a,
469227825Stheraven                     __tuple_indices<_Uf...>, __tuple_types<_Tf...>,
470227825Stheraven                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
471227825Stheraven                     _Up&&... __u) :
472227825Stheraven            __tuple_leaf<_Uf, _Tf>(__uses_alloc_ctor<_Tf, _Alloc, _Up>(), __a,
473227825Stheraven            _VSTD::forward<_Up>(__u))...,
474227825Stheraven            __tuple_leaf<_Ul, _Tl>(__uses_alloc_ctor<_Tl, _Alloc>(), __a)...
475227825Stheraven            {}
476227825Stheraven
477227825Stheraven    template <class _Tuple,
478227825Stheraven              class = typename enable_if
479227825Stheraven                      <
480249989Sdim                         __tuple_constructible<_Tuple, tuple<_Tp...> >::value
481227825Stheraven                      >::type
482227825Stheraven             >
483227825Stheraven        _LIBCPP_INLINE_VISIBILITY
484241900Sdim        __tuple_impl(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_constructible<_Tp, typename tuple_element<_Indx,
485241900Sdim                                       typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))
486227825Stheraven            : __tuple_leaf<_Indx, _Tp>(_VSTD::forward<typename tuple_element<_Indx,
487227825Stheraven                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
488227825Stheraven            {}
489227825Stheraven
490227825Stheraven    template <class _Alloc, class _Tuple,
491227825Stheraven              class = typename enable_if
492227825Stheraven                      <
493227825Stheraven                         __tuple_convertible<_Tuple, tuple<_Tp...> >::value
494227825Stheraven                      >::type
495227825Stheraven             >
496227825Stheraven        _LIBCPP_INLINE_VISIBILITY
497227825Stheraven        __tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
498227825Stheraven            : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, typename tuple_element<_Indx,
499227825Stheraven                                       typename __make_tuple_types<_Tuple>::type>::type>(), __a,
500227825Stheraven                                       _VSTD::forward<typename tuple_element<_Indx,
501227825Stheraven                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
502227825Stheraven            {}
503227825Stheraven
504227825Stheraven    template <class _Tuple>
505227825Stheraven        _LIBCPP_INLINE_VISIBILITY
506227825Stheraven        typename enable_if
507227825Stheraven        <
508227825Stheraven            __tuple_assignable<_Tuple, tuple<_Tp...> >::value,
509227825Stheraven            __tuple_impl&
510227825Stheraven        >::type
511241900Sdim        operator=(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_assignable<_Tp&, typename tuple_element<_Indx,
512241900Sdim                                       typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))
513227825Stheraven        {
514227825Stheraven            __swallow(__tuple_leaf<_Indx, _Tp>::operator=(_VSTD::forward<typename tuple_element<_Indx,
515227825Stheraven                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...);
516227825Stheraven            return *this;
517227825Stheraven        }
518227825Stheraven
519232924Stheraven        _LIBCPP_INLINE_VISIBILITY
520232924Stheraven        __tuple_impl&
521241900Sdim        operator=(const __tuple_impl& __t) _NOEXCEPT_((__all<is_nothrow_copy_assignable<_Tp>::value...>::value))
522232924Stheraven        {
523232924Stheraven            __swallow(__tuple_leaf<_Indx, _Tp>::operator=(static_cast<const __tuple_leaf<_Indx, _Tp>&>(__t).get())...);
524232924Stheraven            return *this;
525232924Stheraven        }
526232924Stheraven
527227825Stheraven    _LIBCPP_INLINE_VISIBILITY
528227825Stheraven    void swap(__tuple_impl& __t)
529227825Stheraven        _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
530227825Stheraven    {
531227825Stheraven        __swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...);
532227825Stheraven    }
533227825Stheraven};
534227825Stheraven
535227825Stheraventemplate <class ..._Tp>
536249989Sdimclass _LIBCPP_TYPE_VIS tuple
537227825Stheraven{
538227825Stheraven    typedef __tuple_impl<typename __make_tuple_indices<sizeof...(_Tp)>::type, _Tp...> base;
539227825Stheraven
540227825Stheraven    base base_;
541227825Stheraven
542227825Stheraven    template <size_t _Jp, class ..._Up> friend
543232924Stheraven        typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT;
544227825Stheraven    template <size_t _Jp, class ..._Up> friend
545232924Stheraven        const typename tuple_element<_Jp, tuple<_Up...> >::type& get(const tuple<_Up...>&) _NOEXCEPT;
546227825Stheraven    template <size_t _Jp, class ..._Up> friend
547232924Stheraven        typename tuple_element<_Jp, tuple<_Up...> >::type&& get(tuple<_Up...>&&) _NOEXCEPT;
548227825Stheravenpublic:
549227825Stheraven
550227825Stheraven    _LIBCPP_INLINE_VISIBILITY
551241900Sdim    _LIBCPP_CONSTEXPR tuple()
552241900Sdim        _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
553241900Sdim
554241900Sdim    _LIBCPP_INLINE_VISIBILITY
555241900Sdim    explicit tuple(const _Tp& ... __t) _NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value)) 
556227825Stheraven        : base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
557227825Stheraven                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
558227825Stheraven                typename __make_tuple_indices<0>::type(),
559227825Stheraven                typename __make_tuple_types<tuple, 0>::type(),
560227825Stheraven                __t...
561227825Stheraven               ) {}
562227825Stheraven
563227825Stheraven    template <class _Alloc>
564227825Stheraven      _LIBCPP_INLINE_VISIBILITY
565227825Stheraven      tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
566227825Stheraven        : base_(allocator_arg_t(), __a,
567227825Stheraven                typename __make_tuple_indices<sizeof...(_Tp)>::type(),
568227825Stheraven                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
569227825Stheraven                typename __make_tuple_indices<0>::type(),
570227825Stheraven                typename __make_tuple_types<tuple, 0>::type(),
571227825Stheraven                __t...
572227825Stheraven               ) {}
573227825Stheraven
574227825Stheraven    template <class ..._Up,
575234959Stheraven              typename enable_if
576227825Stheraven                      <
577227825Stheraven                         sizeof...(_Up) <= sizeof...(_Tp) &&
578227825Stheraven                         __tuple_convertible
579227825Stheraven                         <
580227825Stheraven                            tuple<_Up...>,
581227825Stheraven                            typename __make_tuple_types<tuple,
582227825Stheraven                                     sizeof...(_Up) < sizeof...(_Tp) ?
583227825Stheraven                                        sizeof...(_Up) :
584227825Stheraven                                        sizeof...(_Tp)>::type
585234959Stheraven                         >::value,
586234959Stheraven                         bool
587234959Stheraven                      >::type = false
588227825Stheraven             >
589227825Stheraven        _LIBCPP_INLINE_VISIBILITY
590234959Stheraven        tuple(_Up&&... __u)
591241900Sdim            _NOEXCEPT_((
592241900Sdim                is_nothrow_constructible<
593241900Sdim                    typename __make_tuple_indices<sizeof...(_Up)>::type,
594241900Sdim                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type,
595241900Sdim                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type,
596241900Sdim                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type,
597241900Sdim                    _Up...
598241900Sdim                >::value
599241900Sdim            ))
600234959Stheraven            : base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
601234959Stheraven                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
602234959Stheraven                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
603234959Stheraven                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
604234959Stheraven                    _VSTD::forward<_Up>(__u)...) {}
605234959Stheraven
606234959Stheraven    template <class ..._Up,
607234959Stheraven              typename enable_if
608234959Stheraven                      <
609234959Stheraven                         sizeof...(_Up) <= sizeof...(_Tp) &&
610234959Stheraven                         __tuple_constructible
611234959Stheraven                         <
612234959Stheraven                            tuple<_Up...>,
613234959Stheraven                            typename __make_tuple_types<tuple,
614234959Stheraven                                     sizeof...(_Up) < sizeof...(_Tp) ?
615234959Stheraven                                        sizeof...(_Up) :
616234959Stheraven                                        sizeof...(_Tp)>::type
617234959Stheraven                         >::value &&
618234959Stheraven                         !__tuple_convertible
619234959Stheraven                         <
620234959Stheraven                            tuple<_Up...>,
621234959Stheraven                            typename __make_tuple_types<tuple,
622234959Stheraven                                     sizeof...(_Up) < sizeof...(_Tp) ?
623234959Stheraven                                        sizeof...(_Up) :
624234959Stheraven                                        sizeof...(_Tp)>::type
625234959Stheraven                         >::value,
626234959Stheraven                         bool
627234959Stheraven                      >::type =false
628234959Stheraven             >
629234959Stheraven        _LIBCPP_INLINE_VISIBILITY
630227825Stheraven        explicit
631227825Stheraven        tuple(_Up&&... __u)
632241900Sdim            _NOEXCEPT_((
633241900Sdim                is_nothrow_constructible<
634241900Sdim                    typename __make_tuple_indices<sizeof...(_Up)>::type,
635241900Sdim                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type,
636241900Sdim                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type,
637241900Sdim                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type,
638241900Sdim                    _Up...
639241900Sdim                >::value
640241900Sdim            ))
641227825Stheraven            : base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
642227825Stheraven                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
643227825Stheraven                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
644227825Stheraven                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
645227825Stheraven                    _VSTD::forward<_Up>(__u)...) {}
646227825Stheraven
647227825Stheraven    template <class _Alloc, class ..._Up,
648227825Stheraven              class = typename enable_if
649227825Stheraven                      <
650227825Stheraven                         sizeof...(_Up) <= sizeof...(_Tp) &&
651227825Stheraven                         __tuple_convertible
652227825Stheraven                         <
653227825Stheraven                            tuple<_Up...>,
654227825Stheraven                            typename __make_tuple_types<tuple,
655227825Stheraven                                     sizeof...(_Up) < sizeof...(_Tp) ?
656227825Stheraven                                        sizeof...(_Up) :
657227825Stheraven                                        sizeof...(_Tp)>::type
658227825Stheraven                         >::value
659227825Stheraven                      >::type
660227825Stheraven             >
661227825Stheraven        _LIBCPP_INLINE_VISIBILITY
662227825Stheraven        tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
663227825Stheraven            : base_(allocator_arg_t(), __a,
664227825Stheraven                    typename __make_tuple_indices<sizeof...(_Up)>::type(),
665227825Stheraven                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
666227825Stheraven                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
667227825Stheraven                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
668227825Stheraven                    _VSTD::forward<_Up>(__u)...) {}
669227825Stheraven
670227825Stheraven    template <class _Tuple,
671234959Stheraven              typename enable_if
672227825Stheraven                      <
673234959Stheraven                         __tuple_convertible<_Tuple, tuple>::value,
674234959Stheraven                         bool
675234959Stheraven                      >::type = false
676227825Stheraven             >
677227825Stheraven        _LIBCPP_INLINE_VISIBILITY
678241900Sdim        tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<base, _Tuple>::value))
679227825Stheraven            : base_(_VSTD::forward<_Tuple>(__t)) {}
680227825Stheraven
681234959Stheraven    template <class _Tuple,
682234959Stheraven              typename enable_if
683234959Stheraven                      <
684234959Stheraven                         __tuple_constructible<_Tuple, tuple>::value &&
685234959Stheraven                         !__tuple_convertible<_Tuple, tuple>::value,
686234959Stheraven                         bool
687234959Stheraven                      >::type = false
688234959Stheraven             >
689234959Stheraven        _LIBCPP_INLINE_VISIBILITY
690234959Stheraven        explicit
691241900Sdim        tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<base, _Tuple>::value))
692234959Stheraven            : base_(_VSTD::forward<_Tuple>(__t)) {}
693234959Stheraven
694227825Stheraven    template <class _Alloc, class _Tuple,
695227825Stheraven              class = typename enable_if
696227825Stheraven                      <
697227825Stheraven                         __tuple_convertible<_Tuple, tuple>::value
698227825Stheraven                      >::type
699227825Stheraven             >
700227825Stheraven        _LIBCPP_INLINE_VISIBILITY
701227825Stheraven        tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
702227825Stheraven            : base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {}
703227825Stheraven
704227825Stheraven    template <class _Tuple,
705227825Stheraven              class = typename enable_if
706227825Stheraven                      <
707227825Stheraven                         __tuple_assignable<_Tuple, tuple>::value
708227825Stheraven                      >::type
709227825Stheraven             >
710227825Stheraven        _LIBCPP_INLINE_VISIBILITY
711227825Stheraven        tuple&
712241900Sdim        operator=(_Tuple&& __t) _NOEXCEPT_((is_nothrow_assignable<base&, _Tuple>::value))
713227825Stheraven        {
714227825Stheraven            base_.operator=(_VSTD::forward<_Tuple>(__t));
715227825Stheraven            return *this;
716227825Stheraven        }
717227825Stheraven
718227825Stheraven    _LIBCPP_INLINE_VISIBILITY
719227825Stheraven    void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
720227825Stheraven        {base_.swap(__t.base_);}
721227825Stheraven};
722227825Stheraven
723227825Stheraventemplate <>
724249989Sdimclass _LIBCPP_TYPE_VIS tuple<>
725227825Stheraven{
726227825Stheravenpublic:
727227825Stheraven    _LIBCPP_INLINE_VISIBILITY
728241900Sdim    _LIBCPP_CONSTEXPR tuple() _NOEXCEPT {}
729227825Stheraven    template <class _Alloc>
730227825Stheraven    _LIBCPP_INLINE_VISIBILITY
731241900Sdim        tuple(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
732227825Stheraven    template <class _Alloc>
733227825Stheraven    _LIBCPP_INLINE_VISIBILITY
734241900Sdim        tuple(allocator_arg_t, const _Alloc&, const tuple&) _NOEXCEPT {}
735232924Stheraven    template <class _Up>
736227825Stheraven    _LIBCPP_INLINE_VISIBILITY
737241900Sdim        tuple(array<_Up, 0>) _NOEXCEPT {}
738232924Stheraven    template <class _Alloc, class _Up>
739227825Stheraven    _LIBCPP_INLINE_VISIBILITY
740241900Sdim        tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) _NOEXCEPT {}
741227825Stheraven    _LIBCPP_INLINE_VISIBILITY
742227825Stheraven    void swap(tuple&) _NOEXCEPT {}
743227825Stheraven};
744227825Stheraven
745227825Stheraventemplate <class ..._Tp>
746227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
747227825Stheraventypename enable_if
748227825Stheraven<
749227825Stheraven    __all<__is_swappable<_Tp>::value...>::value,
750227825Stheraven    void
751227825Stheraven>::type
752227825Stheravenswap(tuple<_Tp...>& __t, tuple<_Tp...>& __u)
753227825Stheraven                 _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
754227825Stheraven    {__t.swap(__u);}
755227825Stheraven
756227825Stheraven// get
757227825Stheraven
758227825Stheraventemplate <size_t _Ip, class ..._Tp>
759227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
760227825Stheraventypename tuple_element<_Ip, tuple<_Tp...> >::type&
761232924Stheravenget(tuple<_Tp...>& __t) _NOEXCEPT
762227825Stheraven{
763227825Stheraven    typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
764227825Stheraven    return static_cast<__tuple_leaf<_Ip, type>&>(__t.base_).get();
765227825Stheraven}
766227825Stheraven
767227825Stheraventemplate <size_t _Ip, class ..._Tp>
768227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
769227825Stheravenconst typename tuple_element<_Ip, tuple<_Tp...> >::type&
770232924Stheravenget(const tuple<_Tp...>& __t) _NOEXCEPT
771227825Stheraven{
772227825Stheraven    typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
773227825Stheraven    return static_cast<const __tuple_leaf<_Ip, type>&>(__t.base_).get();
774227825Stheraven}
775227825Stheraven
776227825Stheraventemplate <size_t _Ip, class ..._Tp>
777227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
778227825Stheraventypename tuple_element<_Ip, tuple<_Tp...> >::type&&
779232924Stheravenget(tuple<_Tp...>&& __t) _NOEXCEPT
780227825Stheraven{
781227825Stheraven    typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
782227825Stheraven    return static_cast<type&&>(
783227825Stheraven             static_cast<__tuple_leaf<_Ip, type>&&>(__t.base_).get());
784227825Stheraven}
785227825Stheraven
786227825Stheraven// tie
787227825Stheraven
788227825Stheraventemplate <class ..._Tp>
789227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
790227825Stheraventuple<_Tp&...>
791241900Sdimtie(_Tp&... __t) _NOEXCEPT
792227825Stheraven{
793227825Stheraven    return tuple<_Tp&...>(__t...);
794227825Stheraven}
795227825Stheraven
796227825Stheraventemplate <class _Up>
797227825Stheravenstruct __ignore_t
798227825Stheraven{
799227825Stheraven    template <class _Tp>
800227825Stheraven        _LIBCPP_INLINE_VISIBILITY
801227825Stheraven        const __ignore_t& operator=(_Tp&&) const {return *this;}
802227825Stheraven};
803227825Stheraven
804227825Stheravennamespace { const __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>(); }
805227825Stheraven
806249989Sdimtemplate <class _Tp> class _LIBCPP_TYPE_VIS reference_wrapper;
807227825Stheraven
808227825Stheraventemplate <class _Tp>
809227825Stheravenstruct ___make_tuple_return
810227825Stheraven{
811227825Stheraven    typedef _Tp type;
812227825Stheraven};
813227825Stheraven
814227825Stheraventemplate <class _Tp>
815227825Stheravenstruct ___make_tuple_return<reference_wrapper<_Tp> >
816227825Stheraven{
817227825Stheraven    typedef _Tp& type;
818227825Stheraven};
819227825Stheraven
820227825Stheraventemplate <class _Tp>
821227825Stheravenstruct __make_tuple_return
822227825Stheraven{
823227825Stheraven    typedef typename ___make_tuple_return<typename decay<_Tp>::type>::type type;
824227825Stheraven};
825227825Stheraven
826227825Stheraventemplate <class... _Tp>
827227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
828227825Stheraventuple<typename __make_tuple_return<_Tp>::type...>
829227825Stheravenmake_tuple(_Tp&&... __t)
830227825Stheraven{
831227825Stheraven    return tuple<typename __make_tuple_return<_Tp>::type...>(_VSTD::forward<_Tp>(__t)...);
832227825Stheraven}
833227825Stheraven
834227825Stheraventemplate <class... _Tp>
835227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
836227825Stheraventuple<_Tp&&...>
837241900Sdimforward_as_tuple(_Tp&&... __t) _NOEXCEPT
838227825Stheraven{
839227825Stheraven    return tuple<_Tp&&...>(_VSTD::forward<_Tp>(__t)...);
840227825Stheraven}
841227825Stheraven
842232924Stheraventemplate <size_t _Ip>
843227825Stheravenstruct __tuple_equal
844227825Stheraven{
845227825Stheraven    template <class _Tp, class _Up>
846227825Stheraven    _LIBCPP_INLINE_VISIBILITY
847227825Stheraven    bool operator()(const _Tp& __x, const _Up& __y)
848227825Stheraven    {
849232924Stheraven        return __tuple_equal<_Ip - 1>()(__x, __y) && get<_Ip-1>(__x) == get<_Ip-1>(__y);
850227825Stheraven    }
851227825Stheraven};
852227825Stheraven
853227825Stheraventemplate <>
854227825Stheravenstruct __tuple_equal<0>
855227825Stheraven{
856227825Stheraven    template <class _Tp, class _Up>
857227825Stheraven    _LIBCPP_INLINE_VISIBILITY
858227825Stheraven    bool operator()(const _Tp&, const _Up&)
859227825Stheraven    {
860227825Stheraven        return true;
861227825Stheraven    }
862227825Stheraven};
863227825Stheraven
864227825Stheraventemplate <class ..._Tp, class ..._Up>
865227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
866227825Stheravenbool
867227825Stheravenoperator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
868227825Stheraven{
869227825Stheraven    return __tuple_equal<sizeof...(_Tp)>()(__x, __y);
870227825Stheraven}
871227825Stheraven
872227825Stheraventemplate <class ..._Tp, class ..._Up>
873227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
874227825Stheravenbool
875227825Stheravenoperator!=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
876227825Stheraven{
877227825Stheraven    return !(__x == __y);
878227825Stheraven}
879227825Stheraven
880232924Stheraventemplate <size_t _Ip>
881227825Stheravenstruct __tuple_less
882227825Stheraven{
883227825Stheraven    template <class _Tp, class _Up>
884227825Stheraven    _LIBCPP_INLINE_VISIBILITY
885227825Stheraven    bool operator()(const _Tp& __x, const _Up& __y)
886227825Stheraven    {
887232924Stheraven        return __tuple_less<_Ip-1>()(__x, __y) ||
888232924Stheraven             (!__tuple_less<_Ip-1>()(__y, __x) && get<_Ip-1>(__x) < get<_Ip-1>(__y));
889227825Stheraven    }
890227825Stheraven};
891227825Stheraven
892227825Stheraventemplate <>
893227825Stheravenstruct __tuple_less<0>
894227825Stheraven{
895227825Stheraven    template <class _Tp, class _Up>
896227825Stheraven    _LIBCPP_INLINE_VISIBILITY
897227825Stheraven    bool operator()(const _Tp&, const _Up&)
898227825Stheraven    {
899227825Stheraven        return false;
900227825Stheraven    }
901227825Stheraven};
902227825Stheraven
903227825Stheraventemplate <class ..._Tp, class ..._Up>
904227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
905227825Stheravenbool
906227825Stheravenoperator<(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
907227825Stheraven{
908227825Stheraven    return __tuple_less<sizeof...(_Tp)>()(__x, __y);
909227825Stheraven}
910227825Stheraven
911227825Stheraventemplate <class ..._Tp, class ..._Up>
912227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
913227825Stheravenbool
914227825Stheravenoperator>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
915227825Stheraven{
916227825Stheraven    return __y < __x;
917227825Stheraven}
918227825Stheraven
919227825Stheraventemplate <class ..._Tp, class ..._Up>
920227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
921227825Stheravenbool
922227825Stheravenoperator>=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
923227825Stheraven{
924227825Stheraven    return !(__x < __y);
925227825Stheraven}
926227825Stheraven
927227825Stheraventemplate <class ..._Tp, class ..._Up>
928227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
929227825Stheravenbool
930227825Stheravenoperator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
931227825Stheraven{
932227825Stheraven    return !(__y < __x);
933227825Stheraven}
934227825Stheraven
935227825Stheraven// tuple_cat
936227825Stheraven
937227825Stheraventemplate <class _Tp, class _Up> struct __tuple_cat_type;
938227825Stheraven
939227825Stheraventemplate <class ..._Ttypes, class ..._Utypes>
940227825Stheravenstruct __tuple_cat_type<tuple<_Ttypes...>, __tuple_types<_Utypes...> >
941227825Stheraven{
942227825Stheraven    typedef tuple<_Ttypes..., _Utypes...> type;
943227825Stheraven};
944227825Stheraven
945227825Stheraventemplate <class _ResultTuple, bool _Is_Tuple0TupleLike, class ..._Tuples>
946227825Stheravenstruct __tuple_cat_return_1
947227825Stheraven{
948227825Stheraven};
949227825Stheraven
950227825Stheraventemplate <class ..._Types, class _Tuple0>
951227825Stheravenstruct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0>
952227825Stheraven{
953227825Stheraven    typedef typename __tuple_cat_type<tuple<_Types...>,
954227825Stheraven            typename __make_tuple_types<typename remove_reference<_Tuple0>::type>::type>::type
955227825Stheraven                                                                           type;
956227825Stheraven};
957227825Stheraven
958227825Stheraventemplate <class ..._Types, class _Tuple0, class _Tuple1, class ..._Tuples>
959227825Stheravenstruct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0, _Tuple1, _Tuples...>
960227825Stheraven    : public __tuple_cat_return_1<
961227825Stheraven                 typename __tuple_cat_type<
962227825Stheraven                     tuple<_Types...>,
963227825Stheraven                     typename __make_tuple_types<typename remove_reference<_Tuple0>::type>::type
964227825Stheraven                 >::type,
965227825Stheraven                 __tuple_like<typename remove_reference<_Tuple1>::type>::value,
966227825Stheraven                 _Tuple1, _Tuples...>
967227825Stheraven{
968227825Stheraven};
969227825Stheraven
970227825Stheraventemplate <class ..._Tuples> struct __tuple_cat_return;
971227825Stheraven
972227825Stheraventemplate <class _Tuple0, class ..._Tuples>
973227825Stheravenstruct __tuple_cat_return<_Tuple0, _Tuples...>
974227825Stheraven    : public __tuple_cat_return_1<tuple<>,
975227825Stheraven         __tuple_like<typename remove_reference<_Tuple0>::type>::value, _Tuple0,
976227825Stheraven                                                                     _Tuples...>
977227825Stheraven{
978227825Stheraven};
979227825Stheraven
980227825Stheraventemplate <>
981227825Stheravenstruct __tuple_cat_return<>
982227825Stheraven{
983227825Stheraven    typedef tuple<> type;
984227825Stheraven};
985227825Stheraven
986227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
987227825Stheraventuple<>
988227825Stheraventuple_cat()
989227825Stheraven{
990227825Stheraven    return tuple<>();
991227825Stheraven}
992227825Stheraven
993232924Stheraventemplate <class _Rp, class _Indices, class _Tuple0, class ..._Tuples>
994227825Stheravenstruct __tuple_cat_return_ref_imp;
995227825Stheraven
996227825Stheraventemplate <class ..._Types, size_t ..._I0, class _Tuple0>
997227825Stheravenstruct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, _Tuple0>
998227825Stheraven{
999227825Stheraven    typedef typename remove_reference<_Tuple0>::type _T0;
1000227825Stheraven    typedef tuple<_Types..., typename __apply_cv<_Tuple0,
1001227825Stheraven                          typename tuple_element<_I0, _T0>::type>::type&&...> type;
1002227825Stheraven};
1003227825Stheraven
1004227825Stheraventemplate <class ..._Types, size_t ..._I0, class _Tuple0, class _Tuple1, class ..._Tuples>
1005227825Stheravenstruct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>,
1006227825Stheraven                                  _Tuple0, _Tuple1, _Tuples...>
1007227825Stheraven    : public __tuple_cat_return_ref_imp<
1008227825Stheraven         tuple<_Types..., typename __apply_cv<_Tuple0,
1009227825Stheraven               typename tuple_element<_I0,
1010227825Stheraven                  typename remove_reference<_Tuple0>::type>::type>::type&&...>,
1011227825Stheraven         typename __make_tuple_indices<tuple_size<typename
1012227825Stheraven                                 remove_reference<_Tuple1>::type>::value>::type,
1013227825Stheraven         _Tuple1, _Tuples...>
1014227825Stheraven{
1015227825Stheraven};
1016227825Stheraven
1017227825Stheraventemplate <class _Tuple0, class ..._Tuples>
1018227825Stheravenstruct __tuple_cat_return_ref
1019227825Stheraven    : public __tuple_cat_return_ref_imp<tuple<>,
1020227825Stheraven               typename __make_tuple_indices<
1021227825Stheraven                        tuple_size<typename remove_reference<_Tuple0>::type>::value
1022227825Stheraven               >::type, _Tuple0, _Tuples...>
1023227825Stheraven{
1024227825Stheraven};
1025227825Stheraven
1026227825Stheraventemplate <class _Types, class _I0, class _J0>
1027227825Stheravenstruct __tuple_cat;
1028227825Stheraven
1029227825Stheraventemplate <class ..._Types, size_t ..._I0, size_t ..._J0>
1030227825Stheravenstruct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J0...> >
1031227825Stheraven{
1032227825Stheraven    template <class _Tuple0>
1033227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1034227825Stheraven    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&>::type
1035227825Stheraven    operator()(tuple<_Types...> __t, _Tuple0&& __t0)
1036227825Stheraven    {
1037227825Stheraven        return _VSTD::forward_as_tuple(_VSTD::forward<_Types>(get<_I0>(__t))...,
1038227825Stheraven                                      get<_J0>(_VSTD::forward<_Tuple0>(__t0))...);
1039227825Stheraven    }
1040227825Stheraven
1041227825Stheraven    template <class _Tuple0, class _Tuple1, class ..._Tuples>
1042227825Stheraven    _LIBCPP_INLINE_VISIBILITY
1043227825Stheraven    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&, _Tuple1&&, _Tuples&&...>::type
1044227825Stheraven    operator()(tuple<_Types...> __t, _Tuple0&& __t0, _Tuple1&& __t1, _Tuples&& ...__tpls)
1045227825Stheraven    {
1046227825Stheraven        typedef typename remove_reference<_Tuple0>::type _T0;
1047227825Stheraven        typedef typename remove_reference<_Tuple1>::type _T1;
1048227825Stheraven        return __tuple_cat<
1049227825Stheraven           tuple<_Types..., typename __apply_cv<_Tuple0, typename tuple_element<_J0, _T0>::type>::type&&...>,
1050227825Stheraven           typename __make_tuple_indices<sizeof ...(_Types) + tuple_size<_T0>::value>::type,
1051227825Stheraven           typename __make_tuple_indices<tuple_size<_T1>::value>::type>()
1052227825Stheraven                           (_VSTD::forward_as_tuple(
1053227825Stheraven                              _VSTD::forward<_Types>(get<_I0>(__t))...,
1054227825Stheraven                              get<_J0>(_VSTD::forward<_Tuple0>(__t0))...
1055227825Stheraven                            ),
1056227825Stheraven                            _VSTD::forward<_Tuple1>(__t1),
1057227825Stheraven                            _VSTD::forward<_Tuples>(__tpls)...);
1058227825Stheraven    }
1059227825Stheraven};
1060227825Stheraven
1061227825Stheraventemplate <class _Tuple0, class... _Tuples>
1062227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1063227825Stheraventypename __tuple_cat_return<_Tuple0, _Tuples...>::type
1064227825Stheraventuple_cat(_Tuple0&& __t0, _Tuples&&... __tpls)
1065227825Stheraven{
1066227825Stheraven    typedef typename remove_reference<_Tuple0>::type _T0;
1067227825Stheraven    return __tuple_cat<tuple<>, __tuple_indices<>,
1068227825Stheraven                  typename __make_tuple_indices<tuple_size<_T0>::value>::type>()
1069227825Stheraven                  (tuple<>(), _VSTD::forward<_Tuple0>(__t0),
1070227825Stheraven                                            _VSTD::forward<_Tuples>(__tpls)...);
1071227825Stheraven}
1072227825Stheraven
1073227825Stheraventemplate <class ..._Tp, class _Alloc>
1074249989Sdimstruct _LIBCPP_TYPE_VIS uses_allocator<tuple<_Tp...>, _Alloc>
1075227825Stheraven    : true_type {};
1076227825Stheraven
1077227825Stheraventemplate <class _T1, class _T2>
1078227825Stheraventemplate <class... _Args1, class... _Args2, size_t ..._I1, size_t ..._I2>
1079227825Stheraveninline _LIBCPP_INLINE_VISIBILITY
1080227825Stheravenpair<_T1, _T2>::pair(piecewise_construct_t,
1081227825Stheraven                     tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,
1082227825Stheraven                     __tuple_indices<_I1...>, __tuple_indices<_I2...>)
1083227825Stheraven    :  first(_VSTD::forward<_Args1>(get<_I1>( __first_args))...),
1084227825Stheraven      second(_VSTD::forward<_Args2>(get<_I2>(__second_args))...)
1085227825Stheraven{
1086227825Stheraven}
1087227825Stheraven
1088227825Stheraven#endif  // _LIBCPP_HAS_NO_VARIADICS
1089227825Stheraven
1090227825Stheraven_LIBCPP_END_NAMESPACE_STD
1091227825Stheraven
1092227825Stheraven#endif  // _LIBCPP_TUPLE
1093