xref: /llvm-project-15.0.7/libcxx/include/tuple (revision 72868c74)
1// -*- C++ -*-
2//===--------------------------- tuple ------------------------------------===//
3//
4//                     The LLVM Compiler Infrastructure
5//
6// This file is distributed under the University of Illinois Open Source
7// License. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_TUPLE
12#define _LIBCPP_TUPLE
13
14/*
15    tuple synopsis
16
17namespace std
18{
19
20template <class... T>
21class tuple {
22public:
23    constexpr tuple();
24    explicit tuple(const T&...);  // constexpr in C++14
25    template <class... U>
26        explicit tuple(U&&...);  // constexpr in C++14
27    tuple(const tuple&) = default;
28    tuple(tuple&&) = default;
29    template <class... U>
30        tuple(const tuple<U...>&);  // constexpr in C++14
31    template <class... U>
32        tuple(tuple<U...>&&);  // constexpr in C++14
33    template <class U1, class U2>
34        tuple(const pair<U1, U2>&); // iff sizeof...(T) == 2 // constexpr in C++14
35    template <class U1, class U2>
36        tuple(pair<U1, U2>&&); // iff sizeof...(T) == 2  // constexpr in C++14
37
38    // allocator-extended constructors
39    template <class Alloc>
40        tuple(allocator_arg_t, const Alloc& a);
41    template <class Alloc>
42        tuple(allocator_arg_t, const Alloc& a, const T&...);
43    template <class Alloc, class... U>
44        tuple(allocator_arg_t, const Alloc& a, U&&...);
45    template <class Alloc>
46        tuple(allocator_arg_t, const Alloc& a, const tuple&);
47    template <class Alloc>
48        tuple(allocator_arg_t, const Alloc& a, tuple&&);
49    template <class Alloc, class... U>
50        tuple(allocator_arg_t, const Alloc& a, const tuple<U...>&);
51    template <class Alloc, class... U>
52        tuple(allocator_arg_t, const Alloc& a, tuple<U...>&&);
53    template <class Alloc, class U1, class U2>
54        tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&);
55    template <class Alloc, class U1, class U2>
56        tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&);
57
58    tuple& operator=(const tuple&);
59    tuple&
60        operator=(tuple&&) noexcept(AND(is_nothrow_move_assignable<T>::value ...));
61    template <class... U>
62        tuple& operator=(const tuple<U...>&);
63    template <class... U>
64        tuple& operator=(tuple<U...>&&);
65    template <class U1, class U2>
66        tuple& operator=(const pair<U1, U2>&); // iff sizeof...(T) == 2
67    template <class U1, class U2>
68        tuple& operator=(pair<U1, U2>&&); //iffsizeof...(T) == 2
69
70    void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...));
71};
72
73const unspecified ignore;
74
75template <class... T> tuple<V...>  make_tuple(T&&...); // constexpr in C++14
76template <class... T> tuple<ATypes...> forward_as_tuple(T&&...) noexcept;
77template <class... T> tuple<T&...> tie(T&...) noexcept;
78template <class... Tuples> tuple<CTypes...> tuple_cat(Tuples&&... tpls); // constexpr in C++14
79
80// 20.4.1.4, tuple helper classes:
81template <class T> class tuple_size; // undefined
82template <class... T> class tuple_size<tuple<T...>>;
83template <intsize_t I, class T> class tuple_element; // undefined
84template <intsize_t I, class... T> class tuple_element<I, tuple<T...>>;
85
86// 20.4.1.5, element access:
87template <intsize_t I, class... T>
88    typename tuple_element<I, tuple<T...>>::type&
89    get(tuple<T...>&) noexcept; // constexpr in C++14
90template <intsize_t I, class... T>
91    typename tuple_element<I, tuple<T...>>::type const&
92    get(const tuple<T...>&) noexcept; // constexpr in C++14
93template <intsize_t I, class... T>
94    typename tuple_element<I, tuple<T...>>::type&&
95    get(tuple<T...>&&) noexcept; // constexpr in C++14
96
97template <class T1, class... T>
98    constexpr T1& get(tuple<T...>&) noexcept;  // C++14
99template <class T1, class... T>
100    constexpr T1 const& get(const tuple<T...>&) noexcept;   // C++14
101template <class T1, class... T>
102    constexpr T1&& get(tuple<T...>&&) noexcept;   // C++14
103
104// 20.4.1.6, relational operators:
105template<class... T, class... U> bool operator==(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
106template<class... T, class... U> bool operator<(const tuple<T...>&, const tuple<U...>&);  // constexpr in C++14
107template<class... T, class... U> bool operator!=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
108template<class... T, class... U> bool operator>(const tuple<T...>&, const tuple<U...>&);  // constexpr in C++14
109template<class... T, class... U> bool operator<=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
110template<class... T, class... U> bool operator>=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
111
112template <class... Types, class Alloc>
113  struct uses_allocator<tuple<Types...>, Alloc>;
114
115template <class... Types>
116  void
117  swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(noexcept(x.swap(y)));
118
119}  // std
120
121*/
122
123#include <__config>
124#include <__tuple>
125#include <cstddef>
126#include <type_traits>
127#include <__functional_base>
128#include <utility>
129
130#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
131#pragma GCC system_header
132#endif
133
134_LIBCPP_BEGIN_NAMESPACE_STD
135
136// allocator_arg_t
137
138struct _LIBCPP_TYPE_VIS allocator_arg_t { };
139
140#if defined(_LIBCPP_HAS_NO_CONSTEXPR) || defined(_LIBCPP_BUILDING_MEMORY)
141extern const allocator_arg_t allocator_arg;
142#else
143constexpr allocator_arg_t allocator_arg = allocator_arg_t();
144#endif
145
146// uses_allocator
147
148template <class _Tp>
149struct __has_allocator_type
150{
151private:
152    struct __two {char __lx; char __lxx;};
153    template <class _Up> static __two __test(...);
154    template <class _Up> static char __test(typename _Up::allocator_type* = 0);
155public:
156    static const bool value = sizeof(__test<_Tp>(0)) == 1;
157};
158
159template <class _Tp, class _Alloc, bool = __has_allocator_type<_Tp>::value>
160struct __uses_allocator
161    : public integral_constant<bool,
162        is_convertible<_Alloc, typename _Tp::allocator_type>::value>
163{
164};
165
166template <class _Tp, class _Alloc>
167struct __uses_allocator<_Tp, _Alloc, false>
168    : public false_type
169{
170};
171
172template <class _Tp, class _Alloc>
173struct _LIBCPP_TYPE_VIS uses_allocator
174    : public __uses_allocator<_Tp, _Alloc>
175{
176};
177
178#ifndef _LIBCPP_HAS_NO_VARIADICS
179
180// uses-allocator construction
181
182template <class _Tp, class _Alloc, class ..._Args>
183struct __uses_alloc_ctor_imp
184{
185    static const bool __ua = uses_allocator<_Tp, _Alloc>::value;
186    static const bool __ic =
187        is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value;
188    static const int value = __ua ? 2 - __ic : 0;
189};
190
191template <class _Tp, class _Alloc, class ..._Args>
192struct __uses_alloc_ctor
193    : integral_constant<int, __uses_alloc_ctor_imp<_Tp, _Alloc, _Args...>::value>
194    {};
195
196#endif  // _LIBCPP_HAS_NO_VARIADICS
197
198#ifndef _LIBCPP_HAS_NO_VARIADICS
199
200// tuple_size
201
202template <class ..._Tp>
203class _LIBCPP_TYPE_VIS tuple_size<tuple<_Tp...> >
204    : public integral_constant<size_t, sizeof...(_Tp)>
205{
206};
207
208// tuple_element
209
210template <size_t _Ip, class ..._Tp>
211class _LIBCPP_TYPE_VIS tuple_element<_Ip, tuple<_Tp...> >
212{
213public:
214    typedef typename tuple_element<_Ip, __tuple_types<_Tp...> >::type type;
215};
216
217// __tuple_leaf
218
219template <size_t _Ip, class _Hp, bool=is_empty<_Hp>::value
220#if __has_feature(is_final)
221                                 && !__is_final(_Hp)
222#endif
223         >
224class __tuple_leaf;
225
226template <size_t _Ip, class _Hp, bool _Ep>
227inline _LIBCPP_INLINE_VISIBILITY
228void swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y)
229    _NOEXCEPT_(__is_nothrow_swappable<_Hp>::value)
230{
231    swap(__x.get(), __y.get());
232}
233
234template <size_t _Ip, class _Hp, bool>
235class __tuple_leaf
236{
237    _Hp value;
238
239    __tuple_leaf& operator=(const __tuple_leaf&);
240public:
241    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __tuple_leaf()
242             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) : value()
243       {static_assert(!is_reference<_Hp>::value,
244              "Attempted to default construct a reference element in a tuple");}
245
246    template <class _Alloc>
247        _LIBCPP_INLINE_VISIBILITY
248        __tuple_leaf(integral_constant<int, 0>, const _Alloc&)
249            : value()
250        {static_assert(!is_reference<_Hp>::value,
251              "Attempted to default construct a reference element in a tuple");}
252
253    template <class _Alloc>
254        _LIBCPP_INLINE_VISIBILITY
255        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
256            : value(allocator_arg_t(), __a)
257        {static_assert(!is_reference<_Hp>::value,
258              "Attempted to default construct a reference element in a tuple");}
259
260    template <class _Alloc>
261        _LIBCPP_INLINE_VISIBILITY
262        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
263            : value(__a)
264        {static_assert(!is_reference<_Hp>::value,
265              "Attempted to default construct a reference element in a tuple");}
266
267    template <class _Tp,
268              class = typename enable_if<is_constructible<_Hp, _Tp>::value>::type>
269        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
270        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
271            : value(_VSTD::forward<_Tp>(__t))
272        {static_assert(!is_reference<_Hp>::value ||
273                       (is_lvalue_reference<_Hp>::value &&
274                        (is_lvalue_reference<_Tp>::value ||
275                         is_same<typename remove_reference<_Tp>::type,
276                                 reference_wrapper<
277                                    typename remove_reference<_Hp>::type
278                                 >
279                                >::value)) ||
280                        (is_rvalue_reference<_Hp>::value &&
281                         !is_lvalue_reference<_Tp>::value),
282       "Attempted to construct a reference element in a tuple with an rvalue");}
283
284    template <class _Tp, class _Alloc>
285        _LIBCPP_INLINE_VISIBILITY
286        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
287            : value(_VSTD::forward<_Tp>(__t))
288        {static_assert(!is_lvalue_reference<_Hp>::value ||
289                       (is_lvalue_reference<_Hp>::value &&
290                        (is_lvalue_reference<_Tp>::value ||
291                         is_same<typename remove_reference<_Tp>::type,
292                                 reference_wrapper<
293                                    typename remove_reference<_Hp>::type
294                                 >
295                                >::value)),
296       "Attempted to construct a reference element in a tuple with an rvalue");}
297
298    template <class _Tp, class _Alloc>
299        _LIBCPP_INLINE_VISIBILITY
300        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
301            : value(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t))
302        {static_assert(!is_lvalue_reference<_Hp>::value ||
303                       (is_lvalue_reference<_Hp>::value &&
304                        (is_lvalue_reference<_Tp>::value ||
305                         is_same<typename remove_reference<_Tp>::type,
306                                 reference_wrapper<
307                                    typename remove_reference<_Hp>::type
308                                 >
309                                >::value)),
310       "Attempted to construct a reference element in a tuple with an rvalue");}
311
312    template <class _Tp, class _Alloc>
313        _LIBCPP_INLINE_VISIBILITY
314        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
315            : value(_VSTD::forward<_Tp>(__t), __a)
316        {static_assert(!is_lvalue_reference<_Hp>::value ||
317                       (is_lvalue_reference<_Hp>::value &&
318                        (is_lvalue_reference<_Tp>::value ||
319                         is_same<typename remove_reference<_Tp>::type,
320                                 reference_wrapper<
321                                    typename remove_reference<_Hp>::type
322                                 >
323                                >::value)),
324       "Attempted to construct a reference element in a tuple with an rvalue");}
325
326    _LIBCPP_INLINE_VISIBILITY
327    _LIBCPP_CONSTEXPR_AFTER_CXX11
328    __tuple_leaf(const __tuple_leaf& __t) _NOEXCEPT_(is_nothrow_copy_constructible<_Hp>::value)
329        : value(__t.get())
330        {static_assert(!is_rvalue_reference<_Hp>::value, "Can not copy a tuple with rvalue reference member");}
331
332    _LIBCPP_INLINE_VISIBILITY
333    _LIBCPP_CONSTEXPR_AFTER_CXX11
334    __tuple_leaf(__tuple_leaf&& __t) _NOEXCEPT_(is_nothrow_move_constructible<_Hp>::value)
335        : value(_VSTD::move(__t.get()))
336        {}
337
338    template <class _Tp>
339        _LIBCPP_INLINE_VISIBILITY
340        __tuple_leaf&
341        operator=(_Tp&& __t) _NOEXCEPT_((is_nothrow_assignable<_Hp&, _Tp>::value))
342        {
343            value = _VSTD::forward<_Tp>(__t);
344            return *this;
345        }
346
347    _LIBCPP_INLINE_VISIBILITY
348    int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
349    {
350        _VSTD::swap(*this, __t);
351        return 0;
352    }
353
354    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11       _Hp& get()       _NOEXCEPT {return value;}
355    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return value;}
356};
357
358template <size_t _Ip, class _Hp>
359class __tuple_leaf<_Ip, _Hp, true>
360    : private _Hp
361{
362
363    __tuple_leaf& operator=(const __tuple_leaf&);
364public:
365    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __tuple_leaf()
366             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) {}
367
368    template <class _Alloc>
369        _LIBCPP_INLINE_VISIBILITY
370        __tuple_leaf(integral_constant<int, 0>, const _Alloc&) {}
371
372    template <class _Alloc>
373        _LIBCPP_INLINE_VISIBILITY
374        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
375            : _Hp(allocator_arg_t(), __a) {}
376
377    template <class _Alloc>
378        _LIBCPP_INLINE_VISIBILITY
379        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
380            : _Hp(__a) {}
381
382    template <class _Tp,
383              class = typename enable_if<is_constructible<_Hp, _Tp>::value>::type>
384        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
385        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
386            : _Hp(_VSTD::forward<_Tp>(__t)) {}
387
388    template <class _Tp, class _Alloc>
389        _LIBCPP_INLINE_VISIBILITY
390        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
391            : _Hp(_VSTD::forward<_Tp>(__t)) {}
392
393    template <class _Tp, class _Alloc>
394        _LIBCPP_INLINE_VISIBILITY
395        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
396            : _Hp(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) {}
397
398    template <class _Tp, class _Alloc>
399        _LIBCPP_INLINE_VISIBILITY
400        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
401            : _Hp(_VSTD::forward<_Tp>(__t), __a) {}
402
403    template <class _Tp>
404        _LIBCPP_INLINE_VISIBILITY
405        __tuple_leaf&
406        operator=(_Tp&& __t) _NOEXCEPT_((is_nothrow_assignable<_Hp&, _Tp>::value))
407        {
408            _Hp::operator=(_VSTD::forward<_Tp>(__t));
409            return *this;
410        }
411
412    _LIBCPP_INLINE_VISIBILITY
413    int
414    swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
415    {
416        _VSTD::swap(*this, __t);
417        return 0;
418    }
419
420    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11       _Hp& get()       _NOEXCEPT {return static_cast<_Hp&>(*this);}
421    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return static_cast<const _Hp&>(*this);}
422};
423
424template <class ..._Tp>
425_LIBCPP_INLINE_VISIBILITY
426void __swallow(_Tp&&...) _NOEXCEPT {}
427
428template <bool ...> struct __all;
429
430template <>
431struct __all<>
432{
433    static const bool value = true;
434};
435
436template <bool _B0, bool ... _Bp>
437struct __all<_B0, _Bp...>
438{
439    static const bool value = _B0 && __all<_Bp...>::value;
440};
441
442// __tuple_impl
443
444template<class _Indx, class ..._Tp> struct __tuple_impl;
445
446template<size_t ..._Indx, class ..._Tp>
447struct __tuple_impl<__tuple_indices<_Indx...>, _Tp...>
448    : public __tuple_leaf<_Indx, _Tp>...
449{
450    _LIBCPP_INLINE_VISIBILITY
451    _LIBCPP_CONSTEXPR __tuple_impl()
452        _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
453
454    template <size_t ..._Uf, class ..._Tf,
455              size_t ..._Ul, class ..._Tl, class ..._Up>
456        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
457        explicit
458        __tuple_impl(__tuple_indices<_Uf...>, __tuple_types<_Tf...>,
459                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
460                     _Up&&... __u)
461                     _NOEXCEPT_((__all<is_nothrow_constructible<_Tf, _Up>::value...>::value &&
462                                 __all<is_nothrow_default_constructible<_Tl>::value...>::value)) :
463            __tuple_leaf<_Uf, _Tf>(_VSTD::forward<_Up>(__u))...,
464            __tuple_leaf<_Ul, _Tl>()...
465            {}
466
467    template <class _Alloc, size_t ..._Uf, class ..._Tf,
468              size_t ..._Ul, class ..._Tl, class ..._Up>
469        _LIBCPP_INLINE_VISIBILITY
470        explicit
471        __tuple_impl(allocator_arg_t, const _Alloc& __a,
472                     __tuple_indices<_Uf...>, __tuple_types<_Tf...>,
473                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
474                     _Up&&... __u) :
475            __tuple_leaf<_Uf, _Tf>(__uses_alloc_ctor<_Tf, _Alloc, _Up>(), __a,
476            _VSTD::forward<_Up>(__u))...,
477            __tuple_leaf<_Ul, _Tl>(__uses_alloc_ctor<_Tl, _Alloc>(), __a)...
478            {}
479
480    template <class _Tuple,
481              class = typename enable_if
482                      <
483                         __tuple_constructible<_Tuple, tuple<_Tp...> >::value
484                      >::type
485             >
486        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
487        __tuple_impl(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_constructible<_Tp, typename tuple_element<_Indx,
488                                       typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))
489            : __tuple_leaf<_Indx, _Tp>(_VSTD::forward<typename tuple_element<_Indx,
490                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
491            {}
492
493    template <class _Alloc, class _Tuple,
494              class = typename enable_if
495                      <
496                         __tuple_convertible<_Tuple, tuple<_Tp...> >::value
497                      >::type
498             >
499        _LIBCPP_INLINE_VISIBILITY
500        __tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
501            : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, typename tuple_element<_Indx,
502                                       typename __make_tuple_types<_Tuple>::type>::type>(), __a,
503                                       _VSTD::forward<typename tuple_element<_Indx,
504                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
505            {}
506
507    template <class _Tuple>
508        _LIBCPP_INLINE_VISIBILITY
509        typename enable_if
510        <
511            __tuple_assignable<_Tuple, tuple<_Tp...> >::value,
512            __tuple_impl&
513        >::type
514        operator=(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_assignable<_Tp&, typename tuple_element<_Indx,
515                                       typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))
516        {
517            __swallow(__tuple_leaf<_Indx, _Tp>::operator=(_VSTD::forward<typename tuple_element<_Indx,
518                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...);
519            return *this;
520        }
521
522        _LIBCPP_INLINE_VISIBILITY
523        __tuple_impl&
524        operator=(const __tuple_impl& __t) _NOEXCEPT_((__all<is_nothrow_copy_assignable<_Tp>::value...>::value))
525        {
526            __swallow(__tuple_leaf<_Indx, _Tp>::operator=(static_cast<const __tuple_leaf<_Indx, _Tp>&>(__t).get())...);
527            return *this;
528        }
529
530    _LIBCPP_INLINE_VISIBILITY
531    void swap(__tuple_impl& __t)
532        _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
533    {
534        __swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...);
535    }
536};
537
538template <class ..._Tp>
539class _LIBCPP_TYPE_VIS tuple
540{
541    typedef __tuple_impl<typename __make_tuple_indices<sizeof...(_Tp)>::type, _Tp...> base;
542
543    base base_;
544
545    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
546        typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT;
547    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
548        const typename tuple_element<_Jp, tuple<_Up...> >::type& get(const tuple<_Up...>&) _NOEXCEPT;
549    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
550        typename tuple_element<_Jp, tuple<_Up...> >::type&& get(tuple<_Up...>&&) _NOEXCEPT;
551public:
552
553    _LIBCPP_INLINE_VISIBILITY
554    _LIBCPP_CONSTEXPR tuple()
555        _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
556
557    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
558    explicit tuple(const _Tp& ... __t) _NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value))
559        : base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
560                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
561                typename __make_tuple_indices<0>::type(),
562                typename __make_tuple_types<tuple, 0>::type(),
563                __t...
564               ) {}
565
566    template <class _Alloc>
567      _LIBCPP_INLINE_VISIBILITY
568      tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
569        : base_(allocator_arg_t(), __a,
570                typename __make_tuple_indices<sizeof...(_Tp)>::type(),
571                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
572                typename __make_tuple_indices<0>::type(),
573                typename __make_tuple_types<tuple, 0>::type(),
574                __t...
575               ) {}
576
577    template <class ..._Up,
578              typename enable_if
579                      <
580                         sizeof...(_Up) <= sizeof...(_Tp) &&
581                         __tuple_convertible
582                         <
583                            tuple<_Up...>,
584                            typename __make_tuple_types<tuple,
585                                     sizeof...(_Up) < sizeof...(_Tp) ?
586                                        sizeof...(_Up) :
587                                        sizeof...(_Tp)>::type
588                         >::value,
589                         bool
590                      >::type = false
591             >
592        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
593        tuple(_Up&&... __u)
594            _NOEXCEPT_((
595                is_nothrow_constructible<
596                    typename __make_tuple_indices<sizeof...(_Up)>::type,
597                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type,
598                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type,
599                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type,
600                    _Up...
601                >::value
602            ))
603            : base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
604                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
605                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
606                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
607                    _VSTD::forward<_Up>(__u)...) {}
608
609    template <class ..._Up,
610              typename enable_if
611                      <
612                         sizeof...(_Up) <= sizeof...(_Tp) &&
613                         __tuple_constructible
614                         <
615                            tuple<_Up...>,
616                            typename __make_tuple_types<tuple,
617                                     sizeof...(_Up) < sizeof...(_Tp) ?
618                                        sizeof...(_Up) :
619                                        sizeof...(_Tp)>::type
620                         >::value &&
621                         !__tuple_convertible
622                         <
623                            tuple<_Up...>,
624                            typename __make_tuple_types<tuple,
625                                     sizeof...(_Up) < sizeof...(_Tp) ?
626                                        sizeof...(_Up) :
627                                        sizeof...(_Tp)>::type
628                         >::value,
629                         bool
630                      >::type =false
631             >
632        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
633        explicit
634        tuple(_Up&&... __u)
635            _NOEXCEPT_((
636                is_nothrow_constructible<
637                    typename __make_tuple_indices<sizeof...(_Up)>::type,
638                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type,
639                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type,
640                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type,
641                    _Up...
642                >::value
643            ))
644            : base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
645                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
646                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
647                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
648                    _VSTD::forward<_Up>(__u)...) {}
649
650    template <class _Alloc, class ..._Up,
651              class = typename enable_if
652                      <
653                         sizeof...(_Up) <= sizeof...(_Tp) &&
654                         __tuple_convertible
655                         <
656                            tuple<_Up...>,
657                            typename __make_tuple_types<tuple,
658                                     sizeof...(_Up) < sizeof...(_Tp) ?
659                                        sizeof...(_Up) :
660                                        sizeof...(_Tp)>::type
661                         >::value
662                      >::type
663             >
664        _LIBCPP_INLINE_VISIBILITY
665        tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
666            : base_(allocator_arg_t(), __a,
667                    typename __make_tuple_indices<sizeof...(_Up)>::type(),
668                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
669                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
670                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
671                    _VSTD::forward<_Up>(__u)...) {}
672
673    template <class _Tuple,
674              typename enable_if
675                      <
676                         __tuple_convertible<_Tuple, tuple>::value,
677                         bool
678                      >::type = false
679             >
680        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
681        tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<base, _Tuple>::value))
682            : base_(_VSTD::forward<_Tuple>(__t)) {}
683
684    template <class _Tuple,
685              typename enable_if
686                      <
687                         __tuple_constructible<_Tuple, tuple>::value &&
688                         !__tuple_convertible<_Tuple, tuple>::value,
689                         bool
690                      >::type = false
691             >
692        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
693        explicit
694        tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<base, _Tuple>::value))
695            : base_(_VSTD::forward<_Tuple>(__t)) {}
696
697    template <class _Alloc, class _Tuple,
698              class = typename enable_if
699                      <
700                         __tuple_convertible<_Tuple, tuple>::value
701                      >::type
702             >
703        _LIBCPP_INLINE_VISIBILITY
704        tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
705            : base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {}
706
707    template <class _Tuple,
708              class = typename enable_if
709                      <
710                         __tuple_assignable<_Tuple, tuple>::value
711                      >::type
712             >
713        _LIBCPP_INLINE_VISIBILITY
714        tuple&
715        operator=(_Tuple&& __t) _NOEXCEPT_((is_nothrow_assignable<base&, _Tuple>::value))
716        {
717            base_.operator=(_VSTD::forward<_Tuple>(__t));
718            return *this;
719        }
720
721    _LIBCPP_INLINE_VISIBILITY
722    void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
723        {base_.swap(__t.base_);}
724};
725
726template <>
727class _LIBCPP_TYPE_VIS tuple<>
728{
729public:
730    _LIBCPP_INLINE_VISIBILITY
731    _LIBCPP_CONSTEXPR tuple() _NOEXCEPT {}
732    template <class _Alloc>
733    _LIBCPP_INLINE_VISIBILITY
734        tuple(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
735    template <class _Alloc>
736    _LIBCPP_INLINE_VISIBILITY
737        tuple(allocator_arg_t, const _Alloc&, const tuple&) _NOEXCEPT {}
738    template <class _Up>
739    _LIBCPP_INLINE_VISIBILITY
740        tuple(array<_Up, 0>) _NOEXCEPT {}
741    template <class _Alloc, class _Up>
742    _LIBCPP_INLINE_VISIBILITY
743        tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) _NOEXCEPT {}
744    _LIBCPP_INLINE_VISIBILITY
745    void swap(tuple&) _NOEXCEPT {}
746};
747
748template <class ..._Tp>
749inline _LIBCPP_INLINE_VISIBILITY
750typename enable_if
751<
752    __all<__is_swappable<_Tp>::value...>::value,
753    void
754>::type
755swap(tuple<_Tp...>& __t, tuple<_Tp...>& __u)
756                 _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
757    {__t.swap(__u);}
758
759// get
760
761template <size_t _Ip, class ..._Tp>
762inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
763typename tuple_element<_Ip, tuple<_Tp...> >::type&
764get(tuple<_Tp...>& __t) _NOEXCEPT
765{
766    typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
767    return static_cast<__tuple_leaf<_Ip, type>&>(__t.base_).get();
768}
769
770template <size_t _Ip, class ..._Tp>
771inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
772const typename tuple_element<_Ip, tuple<_Tp...> >::type&
773get(const tuple<_Tp...>& __t) _NOEXCEPT
774{
775    typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
776    return static_cast<const __tuple_leaf<_Ip, type>&>(__t.base_).get();
777}
778
779template <size_t _Ip, class ..._Tp>
780inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
781typename tuple_element<_Ip, tuple<_Tp...> >::type&&
782get(tuple<_Tp...>&& __t) _NOEXCEPT
783{
784    typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
785    return static_cast<type&&>(
786             static_cast<__tuple_leaf<_Ip, type>&&>(__t.base_).get());
787}
788
789#if _LIBCPP_STD_VER > 11
790// get by type
791template <typename _T1, size_t _Idx, typename... _Args>
792struct __find_exactly_one_t_helper;
793
794// -- find exactly one
795template <typename _T1, size_t _Idx, typename... _Args>
796struct __find_exactly_one_t_checker {
797    static constexpr size_t value = _Idx;
798//  Check the rest of the list to make sure there's only one
799    static_assert ( __find_exactly_one_t_helper<_T1, 0, _Args...>::value == -1, "type can only occur once in type list" );
800    };
801
802
803template <typename _T1, size_t _Idx>
804struct __find_exactly_one_t_helper <_T1, _Idx> {
805    static constexpr size_t value = -1;
806    };
807
808template <typename _T1, size_t _Idx, typename _Head, typename... _Args>
809struct __find_exactly_one_t_helper <_T1, _Idx, _Head, _Args...> {
810    static constexpr size_t value =
811        std::conditional<
812            std::is_same<_T1, _Head>::value,
813            __find_exactly_one_t_checker<_T1, _Idx,   _Args...>,
814            __find_exactly_one_t_helper <_T1, _Idx+1, _Args...>
815        >::type::value;
816    };
817
818template <typename _T1, typename... _Args>
819struct __find_exactly_one_t {
820    static constexpr size_t value = __find_exactly_one_t_helper<_T1, 0, _Args...>::value;
821    static_assert ( value != -1, "type not found in type list" );
822    };
823
824template <class _T1, class... _Args>
825inline _LIBCPP_INLINE_VISIBILITY
826constexpr _T1& get(tuple<_Args...>& __tup) noexcept
827{
828    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
829}
830
831template <class _T1, class... _Args>
832inline _LIBCPP_INLINE_VISIBILITY
833constexpr _T1 const& get(tuple<_Args...> const& __tup) noexcept
834{
835    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
836}
837
838template <class _T1, class... _Args>
839inline _LIBCPP_INLINE_VISIBILITY
840constexpr _T1&& get(tuple<_Args...>&& __tup) noexcept
841{
842    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));
843}
844
845#endif
846
847// tie
848
849template <class ..._Tp>
850inline _LIBCPP_INLINE_VISIBILITY
851tuple<_Tp&...>
852tie(_Tp&... __t) _NOEXCEPT
853{
854    return tuple<_Tp&...>(__t...);
855}
856
857template <class _Up>
858struct __ignore_t
859{
860    template <class _Tp>
861        _LIBCPP_INLINE_VISIBILITY
862        const __ignore_t& operator=(_Tp&&) const {return *this;}
863};
864
865namespace { const __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>(); }
866
867template <class _Tp> class _LIBCPP_TYPE_VIS reference_wrapper;
868
869template <class _Tp>
870struct ___make_tuple_return
871{
872    typedef _Tp type;
873};
874
875template <class _Tp>
876struct ___make_tuple_return<reference_wrapper<_Tp> >
877{
878    typedef _Tp& type;
879};
880
881template <class _Tp>
882struct __make_tuple_return
883{
884    typedef typename ___make_tuple_return<typename decay<_Tp>::type>::type type;
885};
886
887template <class... _Tp>
888inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
889tuple<typename __make_tuple_return<_Tp>::type...>
890make_tuple(_Tp&&... __t)
891{
892    return tuple<typename __make_tuple_return<_Tp>::type...>(_VSTD::forward<_Tp>(__t)...);
893}
894
895template <class... _Tp>
896inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
897tuple<_Tp&&...>
898__forward_as_tuple(_Tp&&... __t) _NOEXCEPT
899{
900    return tuple<_Tp&&...>(_VSTD::forward<_Tp>(__t)...);
901}
902
903template <class... _Tp>
904inline _LIBCPP_INLINE_VISIBILITY
905tuple<_Tp&&...>
906forward_as_tuple(_Tp&&... __t) _NOEXCEPT
907{
908    return tuple<_Tp&&...>(_VSTD::forward<_Tp>(__t)...);
909}
910
911template <size_t _Ip>
912struct __tuple_equal
913{
914    template <class _Tp, class _Up>
915    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
916    bool operator()(const _Tp& __x, const _Up& __y)
917    {
918        return __tuple_equal<_Ip - 1>()(__x, __y) && get<_Ip-1>(__x) == get<_Ip-1>(__y);
919    }
920};
921
922template <>
923struct __tuple_equal<0>
924{
925    template <class _Tp, class _Up>
926    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
927    bool operator()(const _Tp&, const _Up&)
928    {
929        return true;
930    }
931};
932
933template <class ..._Tp, class ..._Up>
934inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
935bool
936operator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
937{
938    return __tuple_equal<sizeof...(_Tp)>()(__x, __y);
939}
940
941template <class ..._Tp, class ..._Up>
942inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
943bool
944operator!=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
945{
946    return !(__x == __y);
947}
948
949template <size_t _Ip>
950struct __tuple_less
951{
952    template <class _Tp, class _Up>
953    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
954    bool operator()(const _Tp& __x, const _Up& __y)
955    {
956        return __tuple_less<_Ip-1>()(__x, __y) ||
957             (!__tuple_less<_Ip-1>()(__y, __x) && get<_Ip-1>(__x) < get<_Ip-1>(__y));
958    }
959};
960
961template <>
962struct __tuple_less<0>
963{
964    template <class _Tp, class _Up>
965    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
966    bool operator()(const _Tp&, const _Up&)
967    {
968        return false;
969    }
970};
971
972template <class ..._Tp, class ..._Up>
973inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
974bool
975operator<(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
976{
977    return __tuple_less<sizeof...(_Tp)>()(__x, __y);
978}
979
980template <class ..._Tp, class ..._Up>
981inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
982bool
983operator>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
984{
985    return __y < __x;
986}
987
988template <class ..._Tp, class ..._Up>
989inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
990bool
991operator>=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
992{
993    return !(__x < __y);
994}
995
996template <class ..._Tp, class ..._Up>
997inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
998bool
999operator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1000{
1001    return !(__y < __x);
1002}
1003
1004// tuple_cat
1005
1006template <class _Tp, class _Up> struct __tuple_cat_type;
1007
1008template <class ..._Ttypes, class ..._Utypes>
1009struct __tuple_cat_type<tuple<_Ttypes...>, __tuple_types<_Utypes...> >
1010{
1011    typedef tuple<_Ttypes..., _Utypes...> type;
1012};
1013
1014template <class _ResultTuple, bool _Is_Tuple0TupleLike, class ..._Tuples>
1015struct __tuple_cat_return_1
1016{
1017};
1018
1019template <class ..._Types, class _Tuple0>
1020struct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0>
1021{
1022    typedef typename __tuple_cat_type<tuple<_Types...>,
1023            typename __make_tuple_types<typename remove_reference<_Tuple0>::type>::type>::type
1024                                                                           type;
1025};
1026
1027template <class ..._Types, class _Tuple0, class _Tuple1, class ..._Tuples>
1028struct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0, _Tuple1, _Tuples...>
1029    : public __tuple_cat_return_1<
1030                 typename __tuple_cat_type<
1031                     tuple<_Types...>,
1032                     typename __make_tuple_types<typename remove_reference<_Tuple0>::type>::type
1033                 >::type,
1034                 __tuple_like<typename remove_reference<_Tuple1>::type>::value,
1035                 _Tuple1, _Tuples...>
1036{
1037};
1038
1039template <class ..._Tuples> struct __tuple_cat_return;
1040
1041template <class _Tuple0, class ..._Tuples>
1042struct __tuple_cat_return<_Tuple0, _Tuples...>
1043    : public __tuple_cat_return_1<tuple<>,
1044         __tuple_like<typename remove_reference<_Tuple0>::type>::value, _Tuple0,
1045                                                                     _Tuples...>
1046{
1047};
1048
1049template <>
1050struct __tuple_cat_return<>
1051{
1052    typedef tuple<> type;
1053};
1054
1055inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1056tuple<>
1057tuple_cat()
1058{
1059    return tuple<>();
1060}
1061
1062template <class _Rp, class _Indices, class _Tuple0, class ..._Tuples>
1063struct __tuple_cat_return_ref_imp;
1064
1065template <class ..._Types, size_t ..._I0, class _Tuple0>
1066struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, _Tuple0>
1067{
1068    typedef typename remove_reference<_Tuple0>::type _T0;
1069    typedef tuple<_Types..., typename __apply_cv<_Tuple0,
1070                          typename tuple_element<_I0, _T0>::type>::type&&...> type;
1071};
1072
1073template <class ..._Types, size_t ..._I0, class _Tuple0, class _Tuple1, class ..._Tuples>
1074struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>,
1075                                  _Tuple0, _Tuple1, _Tuples...>
1076    : public __tuple_cat_return_ref_imp<
1077         tuple<_Types..., typename __apply_cv<_Tuple0,
1078               typename tuple_element<_I0,
1079                  typename remove_reference<_Tuple0>::type>::type>::type&&...>,
1080         typename __make_tuple_indices<tuple_size<typename
1081                                 remove_reference<_Tuple1>::type>::value>::type,
1082         _Tuple1, _Tuples...>
1083{
1084};
1085
1086template <class _Tuple0, class ..._Tuples>
1087struct __tuple_cat_return_ref
1088    : public __tuple_cat_return_ref_imp<tuple<>,
1089               typename __make_tuple_indices<
1090                        tuple_size<typename remove_reference<_Tuple0>::type>::value
1091               >::type, _Tuple0, _Tuples...>
1092{
1093};
1094
1095template <class _Types, class _I0, class _J0>
1096struct __tuple_cat;
1097
1098template <class ..._Types, size_t ..._I0, size_t ..._J0>
1099struct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J0...> >
1100{
1101    template <class _Tuple0>
1102    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1103    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&>::type
1104    operator()(tuple<_Types...> __t, _Tuple0&& __t0)
1105    {
1106        return __forward_as_tuple(_VSTD::forward<_Types>(get<_I0>(__t))...,
1107                                      get<_J0>(_VSTD::forward<_Tuple0>(__t0))...);
1108    }
1109
1110    template <class _Tuple0, class _Tuple1, class ..._Tuples>
1111    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1112    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&, _Tuple1&&, _Tuples&&...>::type
1113    operator()(tuple<_Types...> __t, _Tuple0&& __t0, _Tuple1&& __t1, _Tuples&& ...__tpls)
1114    {
1115        typedef typename remove_reference<_Tuple0>::type _T0;
1116        typedef typename remove_reference<_Tuple1>::type _T1;
1117        return __tuple_cat<
1118           tuple<_Types..., typename __apply_cv<_Tuple0, typename tuple_element<_J0, _T0>::type>::type&&...>,
1119           typename __make_tuple_indices<sizeof ...(_Types) + tuple_size<_T0>::value>::type,
1120           typename __make_tuple_indices<tuple_size<_T1>::value>::type>()
1121                           (__forward_as_tuple(
1122                              _VSTD::forward<_Types>(get<_I0>(__t))...,
1123                              get<_J0>(_VSTD::forward<_Tuple0>(__t0))...
1124                            ),
1125                            _VSTD::forward<_Tuple1>(__t1),
1126                            _VSTD::forward<_Tuples>(__tpls)...);
1127    }
1128};
1129
1130template <class _Tuple0, class... _Tuples>
1131inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1132typename __tuple_cat_return<_Tuple0, _Tuples...>::type
1133tuple_cat(_Tuple0&& __t0, _Tuples&&... __tpls)
1134{
1135    typedef typename remove_reference<_Tuple0>::type _T0;
1136    return __tuple_cat<tuple<>, __tuple_indices<>,
1137                  typename __make_tuple_indices<tuple_size<_T0>::value>::type>()
1138                  (tuple<>(), _VSTD::forward<_Tuple0>(__t0),
1139                                            _VSTD::forward<_Tuples>(__tpls)...);
1140}
1141
1142template <class ..._Tp, class _Alloc>
1143struct _LIBCPP_TYPE_VIS uses_allocator<tuple<_Tp...>, _Alloc>
1144    : true_type {};
1145
1146template <class _T1, class _T2>
1147template <class... _Args1, class... _Args2, size_t ..._I1, size_t ..._I2>
1148inline _LIBCPP_INLINE_VISIBILITY
1149pair<_T1, _T2>::pair(piecewise_construct_t,
1150                     tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,
1151                     __tuple_indices<_I1...>, __tuple_indices<_I2...>)
1152    :  first(_VSTD::forward<_Args1>(get<_I1>( __first_args))...),
1153      second(_VSTD::forward<_Args2>(get<_I2>(__second_args))...)
1154{
1155}
1156
1157#endif  // _LIBCPP_HAS_NO_VARIADICS
1158
1159_LIBCPP_END_NAMESPACE_STD
1160
1161#endif  // _LIBCPP_TUPLE
1162