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