1// -*- C++ -*-
2//===--------------------------- tuple ------------------------------------===//
3//
4// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5// See https://llvm.org/LICENSE.txt for license information.
6// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef _LIBCPP_TUPLE
11#define _LIBCPP_TUPLE
12
13/*
14    tuple synopsis
15
16namespace std
17{
18
19template <class... T>
20class tuple {
21public:
22    explicit(see-below) constexpr tuple();
23    explicit(see-below) tuple(const T&...);  // constexpr in C++14
24    template <class... U>
25        explicit(see-below) tuple(U&&...);  // constexpr in C++14
26    tuple(const tuple&) = default;
27    tuple(tuple&&) = default;
28    template <class... U>
29        explicit(see-below) tuple(const tuple<U...>&);  // constexpr in C++14
30    template <class... U>
31        explicit(see-below) tuple(tuple<U...>&&);  // constexpr in C++14
32    template <class U1, class U2>
33        explicit(see-below) tuple(const pair<U1, U2>&); // iff sizeof...(T) == 2 // constexpr in C++14
34    template <class U1, class U2>
35        explicit(see-below) tuple(pair<U1, U2>&&); // iff sizeof...(T) == 2  // constexpr in C++14
36
37    // allocator-extended constructors
38    template <class Alloc>
39        tuple(allocator_arg_t, const Alloc& a);
40    template <class Alloc>
41        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const T&...);          // constexpr in C++20
42    template <class Alloc, class... U>
43        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, U&&...);               // constexpr in C++20
44    template <class Alloc>
45        tuple(allocator_arg_t, const Alloc& a, const tuple&);                             // constexpr in C++20
46    template <class Alloc>
47        tuple(allocator_arg_t, const Alloc& a, tuple&&);                                  // constexpr in C++20
48    template <class Alloc, class... U>
49        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const tuple<U...>&);   // constexpr in C++20
50    template <class Alloc, class... U>
51        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, tuple<U...>&&);        // constexpr in C++20
52    template <class Alloc, class U1, class U2>
53        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&);  // constexpr in C++20
54    template <class Alloc, class U1, class U2>
55        explicit(see-below) tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&);       // constexpr in C++20
56
57    tuple& operator=(const tuple&);                                                       // constexpr in C++20
58    tuple& operator=(tuple&&) noexcept(is_nothrow_move_assignable_v<T> && ...);           // constexpr in C++20
59    template <class... U>
60        tuple& operator=(const tuple<U...>&);                                             // constexpr in C++20
61    template <class... U>
62        tuple& operator=(tuple<U...>&&);                                                  // constexpr in C++20
63    template <class U1, class U2>
64        tuple& operator=(const pair<U1, U2>&); // iff sizeof...(T) == 2                   // constexpr in C++20
65    template <class U1, class U2>
66        tuple& operator=(pair<U1, U2>&&); // iff sizeof...(T) == 2                        // constexpr in C++20
67
68    template<class U, size_t N>
69        tuple& operator=(array<U, N> const&) // iff sizeof...(T) == N, EXTENSION
70    template<class U, size_t N>
71        tuple& operator=(array<U, N>&&) // iff sizeof...(T) == N, EXTENSION
72
73    void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...));               // constexpr in C++20
74};
75
76template <class ...T>
77tuple(T...) -> tuple<T...>;                                         // since C++17
78template <class T1, class T2>
79tuple(pair<T1, T2>) -> tuple<T1, T2>;                               // since C++17
80template <class Alloc, class ...T>
81tuple(allocator_arg_t, Alloc, T...) -> tuple<T...>;                 // since C++17
82template <class Alloc, class T1, class T2>
83tuple(allocator_arg_t, Alloc, pair<T1, T2>) -> tuple<T1, T2>;       // since C++17
84template <class Alloc, class ...T>
85tuple(allocator_arg_t, Alloc, tuple<T...>) -> tuple<T...>;          // since C++17
86
87inline constexpr unspecified ignore;
88
89template <class... T> tuple<V...>  make_tuple(T&&...); // constexpr in C++14
90template <class... T> tuple<ATypes...> forward_as_tuple(T&&...) noexcept; // constexpr in C++14
91template <class... T> tuple<T&...> tie(T&...) noexcept; // constexpr in C++14
92template <class... Tuples> tuple<CTypes...> tuple_cat(Tuples&&... tpls); // constexpr in C++14
93
94// [tuple.apply], calling a function with a tuple of arguments:
95template <class F, class Tuple>
96  constexpr decltype(auto) apply(F&& f, Tuple&& t); // C++17
97template <class T, class Tuple>
98  constexpr T make_from_tuple(Tuple&& t); // C++17
99
100// 20.4.1.4, tuple helper classes:
101template <class T> struct tuple_size; // undefined
102template <class... T> struct tuple_size<tuple<T...>>;
103template <class T>
104 inline constexpr size_t tuple_size_v = tuple_size<T>::value; // C++17
105template <size_t I, class T> struct tuple_element; // undefined
106template <size_t I, class... T> struct tuple_element<I, tuple<T...>>;
107template <size_t I, class T>
108  using tuple_element_t = typename tuple_element <I, T>::type; // C++14
109
110// 20.4.1.5, element access:
111template <size_t I, class... T>
112    typename tuple_element<I, tuple<T...>>::type&
113    get(tuple<T...>&) noexcept; // constexpr in C++14
114template <size_t I, class... T>
115    const typename tuple_element<I, tuple<T...>>::type&
116    get(const tuple<T...>&) noexcept; // constexpr in C++14
117template <size_t I, class... T>
118    typename tuple_element<I, tuple<T...>>::type&&
119    get(tuple<T...>&&) noexcept; // constexpr in C++14
120template <size_t I, class... T>
121    const typename tuple_element<I, tuple<T...>>::type&&
122    get(const tuple<T...>&&) noexcept; // constexpr in C++14
123
124template <class T1, class... T>
125    constexpr T1& get(tuple<T...>&) noexcept;  // C++14
126template <class T1, class... T>
127    constexpr const T1& get(const tuple<T...>&) noexcept;   // C++14
128template <class T1, class... T>
129    constexpr T1&& get(tuple<T...>&&) noexcept;   // C++14
130template <class T1, class... T>
131    constexpr const T1&& get(const tuple<T...>&&) noexcept;   // C++14
132
133// 20.4.1.6, relational operators:
134template<class... T, class... U> bool operator==(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
135template<class... T, class... U> bool operator<(const tuple<T...>&, const tuple<U...>&);  // constexpr in C++14
136template<class... T, class... U> bool operator!=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
137template<class... T, class... U> bool operator>(const tuple<T...>&, const tuple<U...>&);  // constexpr in C++14
138template<class... T, class... U> bool operator<=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
139template<class... T, class... U> bool operator>=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
140
141template <class... Types, class Alloc>
142  struct uses_allocator<tuple<Types...>, Alloc>;
143
144template <class... Types>
145  void
146  swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(noexcept(x.swap(y)));
147
148}  // std
149
150*/
151
152#include <__config>
153#include <__functional/unwrap_ref.h>
154#include <__functional_base>
155#include <__memory/allocator_arg_t.h>
156#include <__memory/uses_allocator.h>
157#include <__tuple>
158#include <__utility/forward.h>
159#include <__utility/move.h>
160#include <compare>
161#include <cstddef>
162#include <type_traits>
163#include <utility>
164#include <version>
165
166#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
167#pragma GCC system_header
168#endif
169
170_LIBCPP_BEGIN_NAMESPACE_STD
171
172#ifndef _LIBCPP_CXX03_LANG
173
174
175// __tuple_leaf
176
177template <size_t _Ip, class _Hp,
178          bool=is_empty<_Hp>::value && !__libcpp_is_final<_Hp>::value
179         >
180class __tuple_leaf;
181
182template <size_t _Ip, class _Hp, bool _Ep>
183inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
184void swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y)
185    _NOEXCEPT_(__is_nothrow_swappable<_Hp>::value)
186{
187    swap(__x.get(), __y.get());
188}
189
190template <size_t _Ip, class _Hp, bool>
191class __tuple_leaf
192{
193    _Hp __value_;
194
195    template <class _Tp>
196    static constexpr bool __can_bind_reference() {
197#if __has_keyword(__reference_binds_to_temporary)
198      return !__reference_binds_to_temporary(_Hp, _Tp);
199#else
200      return true;
201#endif
202    }
203
204    _LIBCPP_CONSTEXPR_AFTER_CXX11
205    __tuple_leaf& operator=(const __tuple_leaf&);
206public:
207    _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf()
208             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) : __value_()
209       {static_assert(!is_reference<_Hp>::value,
210              "Attempted to default construct a reference element in a tuple");}
211
212    template <class _Alloc>
213        _LIBCPP_INLINE_VISIBILITY constexpr
214        __tuple_leaf(integral_constant<int, 0>, const _Alloc&)
215            : __value_()
216        {static_assert(!is_reference<_Hp>::value,
217              "Attempted to default construct a reference element in a tuple");}
218
219    template <class _Alloc>
220        _LIBCPP_INLINE_VISIBILITY constexpr
221        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
222            : __value_(allocator_arg_t(), __a)
223        {static_assert(!is_reference<_Hp>::value,
224              "Attempted to default construct a reference element in a tuple");}
225
226    template <class _Alloc>
227        _LIBCPP_INLINE_VISIBILITY constexpr
228        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
229            : __value_(__a)
230        {static_assert(!is_reference<_Hp>::value,
231              "Attempted to default construct a reference element in a tuple");}
232
233    template <class _Tp,
234              class = _EnableIf<
235                  _And<
236                      _IsNotSame<__uncvref_t<_Tp>, __tuple_leaf>,
237                      is_constructible<_Hp, _Tp>
238                    >::value
239                >
240            >
241        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
242        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
243            : __value_(_VSTD::forward<_Tp>(__t))
244        {static_assert(__can_bind_reference<_Tp&&>(),
245       "Attempted construction of reference element binds to a temporary whose lifetime has ended");}
246
247    template <class _Tp, class _Alloc>
248        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
249        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
250            : __value_(_VSTD::forward<_Tp>(__t))
251        {static_assert(__can_bind_reference<_Tp&&>(),
252       "Attempted construction of reference element binds to a temporary whose lifetime has ended");}
253
254    template <class _Tp, class _Alloc>
255        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
256        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
257            : __value_(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t))
258        {static_assert(!is_reference<_Hp>::value,
259            "Attempted to uses-allocator construct a reference element in a tuple");}
260
261    template <class _Tp, class _Alloc>
262        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
263        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
264            : __value_(_VSTD::forward<_Tp>(__t), __a)
265        {static_assert(!is_reference<_Hp>::value,
266           "Attempted to uses-allocator construct a reference element in a tuple");}
267
268    __tuple_leaf(const __tuple_leaf& __t) = default;
269    __tuple_leaf(__tuple_leaf&& __t) = default;
270
271    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
272    int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
273    {
274        _VSTD::swap(*this, __t);
275        return 0;
276    }
277
278    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11       _Hp& get()       _NOEXCEPT {return __value_;}
279    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return __value_;}
280};
281
282template <size_t _Ip, class _Hp>
283class __tuple_leaf<_Ip, _Hp, true>
284    : private _Hp
285{
286    _LIBCPP_CONSTEXPR_AFTER_CXX11
287    __tuple_leaf& operator=(const __tuple_leaf&);
288public:
289    _LIBCPP_INLINE_VISIBILITY constexpr __tuple_leaf()
290             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) {}
291
292    template <class _Alloc>
293        _LIBCPP_INLINE_VISIBILITY constexpr
294        __tuple_leaf(integral_constant<int, 0>, const _Alloc&) {}
295
296    template <class _Alloc>
297        _LIBCPP_INLINE_VISIBILITY constexpr
298        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
299            : _Hp(allocator_arg_t(), __a) {}
300
301    template <class _Alloc>
302        _LIBCPP_INLINE_VISIBILITY constexpr
303        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
304            : _Hp(__a) {}
305
306    template <class _Tp,
307              class = _EnableIf<
308                  _And<
309                    _IsNotSame<__uncvref_t<_Tp>, __tuple_leaf>,
310                    is_constructible<_Hp, _Tp>
311                  >::value
312                >
313            >
314        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
315        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
316            : _Hp(_VSTD::forward<_Tp>(__t)) {}
317
318    template <class _Tp, class _Alloc>
319        _LIBCPP_INLINE_VISIBILITY constexpr
320        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
321            : _Hp(_VSTD::forward<_Tp>(__t)) {}
322
323    template <class _Tp, class _Alloc>
324        _LIBCPP_INLINE_VISIBILITY constexpr
325        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
326            : _Hp(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) {}
327
328    template <class _Tp, class _Alloc>
329        _LIBCPP_INLINE_VISIBILITY constexpr
330        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
331            : _Hp(_VSTD::forward<_Tp>(__t), __a) {}
332
333    __tuple_leaf(__tuple_leaf const &) = default;
334    __tuple_leaf(__tuple_leaf &&) = default;
335
336    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
337    int
338    swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
339    {
340        _VSTD::swap(*this, __t);
341        return 0;
342    }
343
344    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11       _Hp& get()       _NOEXCEPT {return static_cast<_Hp&>(*this);}
345    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return static_cast<const _Hp&>(*this);}
346};
347
348template <class ..._Tp>
349_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
350void __swallow(_Tp&&...) _NOEXCEPT {}
351
352template <class _Tp>
353struct __all_default_constructible;
354
355template <class ..._Tp>
356struct __all_default_constructible<__tuple_types<_Tp...>>
357    : __all<is_default_constructible<_Tp>::value...>
358{ };
359
360// __tuple_impl
361
362template<class _Indx, class ..._Tp> struct __tuple_impl;
363
364template<size_t ..._Indx, class ..._Tp>
365struct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>, _Tp...>
366    : public __tuple_leaf<_Indx, _Tp>...
367{
368    _LIBCPP_INLINE_VISIBILITY
369    constexpr __tuple_impl()
370        _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
371
372    template <size_t ..._Uf, class ..._Tf,
373              size_t ..._Ul, class ..._Tl, class ..._Up>
374        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
375        explicit
376        __tuple_impl(__tuple_indices<_Uf...>, __tuple_types<_Tf...>,
377                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
378                     _Up&&... __u)
379                     _NOEXCEPT_((__all<is_nothrow_constructible<_Tf, _Up>::value...>::value &&
380                                 __all<is_nothrow_default_constructible<_Tl>::value...>::value)) :
381            __tuple_leaf<_Uf, _Tf>(_VSTD::forward<_Up>(__u))...,
382            __tuple_leaf<_Ul, _Tl>()...
383            {}
384
385    template <class _Alloc, size_t ..._Uf, class ..._Tf,
386              size_t ..._Ul, class ..._Tl, class ..._Up>
387        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
388        explicit
389        __tuple_impl(allocator_arg_t, const _Alloc& __a,
390                     __tuple_indices<_Uf...>, __tuple_types<_Tf...>,
391                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
392                     _Up&&... __u) :
393            __tuple_leaf<_Uf, _Tf>(__uses_alloc_ctor<_Tf, _Alloc, _Up>(), __a,
394            _VSTD::forward<_Up>(__u))...,
395            __tuple_leaf<_Ul, _Tl>(__uses_alloc_ctor<_Tl, _Alloc>(), __a)...
396            {}
397
398    template <class _Tuple,
399              class = typename enable_if
400                      <
401                         __tuple_constructible<_Tuple, tuple<_Tp...> >::value
402                      >::type
403             >
404        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
405        __tuple_impl(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_constructible<_Tp, typename tuple_element<_Indx,
406                                       typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))
407            : __tuple_leaf<_Indx, _Tp>(_VSTD::forward<typename tuple_element<_Indx,
408                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
409            {}
410
411    template <class _Alloc, class _Tuple,
412              class = typename enable_if
413                      <
414                         __tuple_constructible<_Tuple, tuple<_Tp...> >::value
415                      >::type
416             >
417        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
418        __tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
419            : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, typename tuple_element<_Indx,
420                                       typename __make_tuple_types<_Tuple>::type>::type>(), __a,
421                                       _VSTD::forward<typename tuple_element<_Indx,
422                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
423            {}
424
425    __tuple_impl(const __tuple_impl&) = default;
426    __tuple_impl(__tuple_impl&&) = default;
427
428    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
429    void swap(__tuple_impl& __t)
430        _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
431    {
432        _VSTD::__swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...);
433    }
434};
435
436template<class _Dest, class _Source, size_t ..._Np>
437_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
438void __memberwise_copy_assign(_Dest& __dest, _Source const& __source, __tuple_indices<_Np...>) {
439    _VSTD::__swallow(((_VSTD::get<_Np>(__dest) = _VSTD::get<_Np>(__source)), void(), 0)...);
440}
441
442template<class _Dest, class _Source, class ..._Up, size_t ..._Np>
443_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
444void __memberwise_forward_assign(_Dest& __dest, _Source&& __source, __tuple_types<_Up...>, __tuple_indices<_Np...>) {
445    _VSTD::__swallow(((
446        _VSTD::get<_Np>(__dest) = _VSTD::forward<_Up>(_VSTD::get<_Np>(__source))
447    ), void(), 0)...);
448}
449
450template <class ..._Tp>
451class _LIBCPP_TEMPLATE_VIS tuple
452{
453    typedef __tuple_impl<typename __make_tuple_indices<sizeof...(_Tp)>::type, _Tp...> _BaseT;
454
455    _BaseT __base_;
456
457    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
458        typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT;
459    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
460        const typename tuple_element<_Jp, tuple<_Up...> >::type& get(const tuple<_Up...>&) _NOEXCEPT;
461    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
462        typename tuple_element<_Jp, tuple<_Up...> >::type&& get(tuple<_Up...>&&) _NOEXCEPT;
463    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
464        const typename tuple_element<_Jp, tuple<_Up...> >::type&& get(const tuple<_Up...>&&) _NOEXCEPT;
465public:
466    // [tuple.cnstr]
467
468    // tuple() constructors (including allocator_arg_t variants)
469    template <template<class...> class _IsImpDefault = __is_implicitly_default_constructible, _EnableIf<
470        _And<
471            _IsImpDefault<_Tp>... // explicit check
472        >::value
473    , int> = 0>
474    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
475    tuple()
476        _NOEXCEPT_(_And<is_nothrow_default_constructible<_Tp>...>::value)
477    { }
478
479    template <template<class...> class _IsImpDefault = __is_implicitly_default_constructible,
480              template<class...> class _IsDefault = is_default_constructible, _EnableIf<
481        _And<
482            _IsDefault<_Tp>...,
483            _Not<_Lazy<_And, _IsImpDefault<_Tp>...> > // explicit check
484        >::value
485    , int> = 0>
486    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
487    explicit tuple()
488        _NOEXCEPT_(_And<is_nothrow_default_constructible<_Tp>...>::value)
489    { }
490
491    template <class _Alloc, template<class...> class _IsImpDefault = __is_implicitly_default_constructible, _EnableIf<
492        _And<
493            _IsImpDefault<_Tp>... // explicit check
494        >::value
495    , int> = 0>
496    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
497    tuple(allocator_arg_t, _Alloc const& __a)
498      : __base_(allocator_arg_t(), __a,
499                    __tuple_indices<>(), __tuple_types<>(),
500                    typename __make_tuple_indices<sizeof...(_Tp), 0>::type(),
501                    __tuple_types<_Tp...>()) {}
502
503    template <class _Alloc,
504              template<class...> class _IsImpDefault = __is_implicitly_default_constructible,
505              template<class...> class _IsDefault = is_default_constructible, _EnableIf<
506        _And<
507            _IsDefault<_Tp>...,
508            _Not<_Lazy<_And, _IsImpDefault<_Tp>...> > // explicit check
509        >::value
510    , int> = 0>
511    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
512    explicit tuple(allocator_arg_t, _Alloc const& __a)
513      : __base_(allocator_arg_t(), __a,
514                    __tuple_indices<>(), __tuple_types<>(),
515                    typename __make_tuple_indices<sizeof...(_Tp), 0>::type(),
516                    __tuple_types<_Tp...>()) {}
517
518    // tuple(const T&...) constructors (including allocator_arg_t variants)
519    template <template<class...> class _And = _And, _EnableIf<
520        _And<
521            _BoolConstant<sizeof...(_Tp) >= 1>,
522            is_copy_constructible<_Tp>...,
523            is_convertible<const _Tp&, _Tp>... // explicit check
524        >::value
525    , int> = 0>
526    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
527    tuple(const _Tp& ... __t)
528        _NOEXCEPT_(_And<is_nothrow_copy_constructible<_Tp>...>::value)
529        : __base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
530                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
531                typename __make_tuple_indices<0>::type(),
532                typename __make_tuple_types<tuple, 0>::type(),
533                __t...
534               ) {}
535
536    template <template<class...> class _And = _And, _EnableIf<
537        _And<
538            _BoolConstant<sizeof...(_Tp) >= 1>,
539            is_copy_constructible<_Tp>...,
540            _Not<_Lazy<_And, is_convertible<const _Tp&, _Tp>...> > // explicit check
541        >::value
542    , int> = 0>
543    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
544    explicit tuple(const _Tp& ... __t)
545        _NOEXCEPT_(_And<is_nothrow_copy_constructible<_Tp>...>::value)
546        : __base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
547                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
548                typename __make_tuple_indices<0>::type(),
549                typename __make_tuple_types<tuple, 0>::type(),
550                __t...
551               ) {}
552
553    template <class _Alloc, template<class...> class _And = _And, _EnableIf<
554        _And<
555            _BoolConstant<sizeof...(_Tp) >= 1>,
556            is_copy_constructible<_Tp>...,
557            is_convertible<const _Tp&, _Tp>... // explicit check
558        >::value
559    , int> = 0>
560    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
561    tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
562        : __base_(allocator_arg_t(), __a,
563                typename __make_tuple_indices<sizeof...(_Tp)>::type(),
564                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
565                typename __make_tuple_indices<0>::type(),
566                typename __make_tuple_types<tuple, 0>::type(),
567                __t...
568               ) {}
569
570    template <class _Alloc, template<class...> class _And = _And, _EnableIf<
571        _And<
572            _BoolConstant<sizeof...(_Tp) >= 1>,
573            is_copy_constructible<_Tp>...,
574            _Not<_Lazy<_And, is_convertible<const _Tp&, _Tp>...> > // explicit check
575        >::value
576    , int> = 0>
577    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
578    explicit tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
579        : __base_(allocator_arg_t(), __a,
580                typename __make_tuple_indices<sizeof...(_Tp)>::type(),
581                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
582                typename __make_tuple_indices<0>::type(),
583                typename __make_tuple_types<tuple, 0>::type(),
584                __t...
585               ) {}
586
587    // tuple(U&& ...) constructors (including allocator_arg_t variants)
588    template <class ..._Up> struct _IsThisTuple : false_type { };
589    template <class _Up> struct _IsThisTuple<_Up> : is_same<__uncvref_t<_Up>, tuple> { };
590
591    template <class ..._Up>
592    struct _EnableUTypesCtor : _And<
593        _BoolConstant<sizeof...(_Tp) >= 1>,
594        _Not<_IsThisTuple<_Up...> >, // extension to allow mis-behaved user constructors
595        is_constructible<_Tp, _Up>...
596    > { };
597
598    template <class ..._Up, _EnableIf<
599        _And<
600            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
601            _EnableUTypesCtor<_Up...>,
602            is_convertible<_Up, _Tp>... // explicit check
603        >::value
604    , int> = 0>
605    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
606    tuple(_Up&&... __u)
607        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
608        : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
609                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
610                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
611                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
612                    _VSTD::forward<_Up>(__u)...) {}
613
614    template <class ..._Up, _EnableIf<
615        _And<
616            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
617            _EnableUTypesCtor<_Up...>,
618            _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
619        >::value
620    , int> = 0>
621    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
622    explicit tuple(_Up&&... __u)
623        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
624        : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
625                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
626                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
627                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
628                    _VSTD::forward<_Up>(__u)...) {}
629
630    template <class _Alloc, class ..._Up, _EnableIf<
631        _And<
632            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
633            _EnableUTypesCtor<_Up...>,
634            is_convertible<_Up, _Tp>... // explicit check
635        >::value
636    , int> = 0>
637    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
638    tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
639        : __base_(allocator_arg_t(), __a,
640                    typename __make_tuple_indices<sizeof...(_Up)>::type(),
641                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
642                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
643                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
644                    _VSTD::forward<_Up>(__u)...) {}
645
646    template <class _Alloc, class ..._Up, _EnableIf<
647        _And<
648            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
649            _EnableUTypesCtor<_Up...>,
650            _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
651        >::value
652    , int> = 0>
653    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
654    explicit tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
655        : __base_(allocator_arg_t(), __a,
656                    typename __make_tuple_indices<sizeof...(_Up)>::type(),
657                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
658                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
659                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
660                    _VSTD::forward<_Up>(__u)...) {}
661
662    // Copy and move constructors (including the allocator_arg_t variants)
663    tuple(const tuple&) = default;
664    tuple(tuple&&) = default;
665
666    template <class _Alloc, template<class...> class _And = _And, _EnableIf<
667        _And<is_copy_constructible<_Tp>...>::value
668    , int> = 0>
669    tuple(allocator_arg_t, const _Alloc& __alloc, const tuple& __t)
670        : __base_(allocator_arg_t(), __alloc, __t)
671    { }
672
673    template <class _Alloc, template<class...> class _And = _And, _EnableIf<
674        _And<is_move_constructible<_Tp>...>::value
675    , int> = 0>
676    tuple(allocator_arg_t, const _Alloc& __alloc, tuple&& __t)
677        : __base_(allocator_arg_t(), __alloc, _VSTD::move(__t))
678    { }
679
680    // tuple(const tuple<U...>&) constructors (including allocator_arg_t variants)
681    template <class ..._Up>
682    struct _EnableCopyFromOtherTuple : _And<
683        _Not<is_same<tuple<_Tp...>, tuple<_Up...> > >,
684        _Lazy<_Or,
685            _BoolConstant<sizeof...(_Tp) != 1>,
686            // _Tp and _Up are 1-element packs - the pack expansions look
687            // weird to avoid tripping up the type traits in degenerate cases
688            _Lazy<_And,
689                _Not<is_convertible<const tuple<_Up>&, _Tp> >...,
690                _Not<is_constructible<_Tp, const tuple<_Up>&> >...
691            >
692        >,
693        is_constructible<_Tp, const _Up&>...
694    > { };
695
696    template <class ..._Up, _EnableIf<
697        _And<
698            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
699            _EnableCopyFromOtherTuple<_Up...>,
700            is_convertible<const _Up&, _Tp>... // explicit check
701        >::value
702    , int> = 0>
703    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
704    tuple(const tuple<_Up...>& __t)
705        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, const _Up&>...>::value))
706        : __base_(__t)
707    { }
708
709    template <class ..._Up, _EnableIf<
710        _And<
711            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
712            _EnableCopyFromOtherTuple<_Up...>,
713            _Not<_Lazy<_And, is_convertible<const _Up&, _Tp>...> > // explicit check
714        >::value
715    , int> = 0>
716    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
717    explicit tuple(const tuple<_Up...>& __t)
718        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, const _Up&>...>::value))
719        : __base_(__t)
720    { }
721
722    template <class ..._Up, class _Alloc, _EnableIf<
723        _And<
724            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
725            _EnableCopyFromOtherTuple<_Up...>,
726            is_convertible<const _Up&, _Tp>... // explicit check
727        >::value
728    , int> = 0>
729    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
730    tuple(allocator_arg_t, const _Alloc& __a, const tuple<_Up...>& __t)
731        : __base_(allocator_arg_t(), __a, __t)
732    { }
733
734    template <class ..._Up, class _Alloc, _EnableIf<
735        _And<
736            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
737            _EnableCopyFromOtherTuple<_Up...>,
738            _Not<_Lazy<_And, is_convertible<const _Up&, _Tp>...> > // explicit check
739        >::value
740    , int> = 0>
741    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
742    explicit tuple(allocator_arg_t, const _Alloc& __a, const tuple<_Up...>& __t)
743        : __base_(allocator_arg_t(), __a, __t)
744    { }
745
746    // tuple(tuple<U...>&&) constructors (including allocator_arg_t variants)
747    template <class ..._Up>
748    struct _EnableMoveFromOtherTuple : _And<
749        _Not<is_same<tuple<_Tp...>, tuple<_Up...> > >,
750        _Lazy<_Or,
751            _BoolConstant<sizeof...(_Tp) != 1>,
752            // _Tp and _Up are 1-element packs - the pack expansions look
753            // weird to avoid tripping up the type traits in degenerate cases
754            _Lazy<_And,
755                _Not<is_convertible<tuple<_Up>, _Tp> >...,
756                _Not<is_constructible<_Tp, tuple<_Up> > >...
757            >
758        >,
759        is_constructible<_Tp, _Up>...
760    > { };
761
762    template <class ..._Up, _EnableIf<
763        _And<
764            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
765            _EnableMoveFromOtherTuple<_Up...>,
766            is_convertible<_Up, _Tp>... // explicit check
767        >::value
768    , int> = 0>
769    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
770    tuple(tuple<_Up...>&& __t)
771        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
772        : __base_(_VSTD::move(__t))
773    { }
774
775    template <class ..._Up, _EnableIf<
776        _And<
777            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
778            _EnableMoveFromOtherTuple<_Up...>,
779            _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
780        >::value
781    , int> = 0>
782    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
783    explicit tuple(tuple<_Up...>&& __t)
784        _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
785        : __base_(_VSTD::move(__t))
786    { }
787
788    template <class _Alloc, class ..._Up, _EnableIf<
789        _And<
790            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
791            _EnableMoveFromOtherTuple<_Up...>,
792            is_convertible<_Up, _Tp>... // explicit check
793        >::value
794    , int> = 0>
795    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
796    tuple(allocator_arg_t, const _Alloc& __a, tuple<_Up...>&& __t)
797        : __base_(allocator_arg_t(), __a, _VSTD::move(__t))
798    { }
799
800    template <class _Alloc, class ..._Up, _EnableIf<
801        _And<
802            _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
803            _EnableMoveFromOtherTuple<_Up...>,
804            _Not<_Lazy<_And, is_convertible<_Up, _Tp>...> > // explicit check
805        >::value
806    , int> = 0>
807    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
808    explicit tuple(allocator_arg_t, const _Alloc& __a, tuple<_Up...>&& __t)
809        : __base_(allocator_arg_t(), __a, _VSTD::move(__t))
810    { }
811
812    // tuple(const pair<U1, U2>&) constructors (including allocator_arg_t variants)
813    template <class _Up1, class _Up2, class ..._DependentTp>
814    struct _EnableImplicitCopyFromPair : _And<
815        is_constructible<_FirstType<_DependentTp...>, const _Up1&>,
816        is_constructible<_SecondType<_DependentTp...>, const _Up2&>,
817        is_convertible<const _Up1&, _FirstType<_DependentTp...> >, // explicit check
818        is_convertible<const _Up2&, _SecondType<_DependentTp...> >
819    > { };
820
821    template <class _Up1, class _Up2, class ..._DependentTp>
822    struct _EnableExplicitCopyFromPair : _And<
823        is_constructible<_FirstType<_DependentTp...>, const _Up1&>,
824        is_constructible<_SecondType<_DependentTp...>, const _Up2&>,
825        _Not<is_convertible<const _Up1&, _FirstType<_DependentTp...> > >, // explicit check
826        _Not<is_convertible<const _Up2&, _SecondType<_DependentTp...> > >
827    > { };
828
829    template <class _Up1, class _Up2, template<class...> class _And = _And, _EnableIf<
830        _And<
831            _BoolConstant<sizeof...(_Tp) == 2>,
832            _EnableImplicitCopyFromPair<_Up1, _Up2, _Tp...>
833        >::value
834    , int> = 0>
835    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
836    tuple(const pair<_Up1, _Up2>& __p)
837        _NOEXCEPT_((_And<
838            is_nothrow_constructible<_FirstType<_Tp...>, const _Up1&>,
839            is_nothrow_constructible<_SecondType<_Tp...>, const _Up2&>
840        >::value))
841        : __base_(__p)
842    { }
843
844    template <class _Up1, class _Up2, template<class...> class _And = _And, _EnableIf<
845        _And<
846            _BoolConstant<sizeof...(_Tp) == 2>,
847            _EnableExplicitCopyFromPair<_Up1, _Up2, _Tp...>
848        >::value
849    , int> = 0>
850    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
851    explicit tuple(const pair<_Up1, _Up2>& __p)
852        _NOEXCEPT_((_And<
853            is_nothrow_constructible<_FirstType<_Tp...>, const _Up1&>,
854            is_nothrow_constructible<_SecondType<_Tp...>, const _Up2&>
855        >::value))
856        : __base_(__p)
857    { }
858
859    template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, _EnableIf<
860        _And<
861            _BoolConstant<sizeof...(_Tp) == 2>,
862            _EnableImplicitCopyFromPair<_Up1, _Up2, _Tp...>
863        >::value
864    , int> = 0>
865    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
866    tuple(allocator_arg_t, const _Alloc& __a, const pair<_Up1, _Up2>& __p)
867        : __base_(allocator_arg_t(), __a, __p)
868    { }
869
870    template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, _EnableIf<
871        _And<
872            _BoolConstant<sizeof...(_Tp) == 2>,
873            _EnableExplicitCopyFromPair<_Up1, _Up2, _Tp...>
874        >::value
875    , int> = 0>
876    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
877    explicit tuple(allocator_arg_t, const _Alloc& __a, const pair<_Up1, _Up2>& __p)
878        : __base_(allocator_arg_t(), __a, __p)
879    { }
880
881    // tuple(pair<U1, U2>&&) constructors (including allocator_arg_t variants)
882    template <class _Up1, class _Up2, class ..._DependentTp>
883    struct _EnableImplicitMoveFromPair : _And<
884        is_constructible<_FirstType<_DependentTp...>, _Up1>,
885        is_constructible<_SecondType<_DependentTp...>, _Up2>,
886        is_convertible<_Up1, _FirstType<_DependentTp...> >, // explicit check
887        is_convertible<_Up2, _SecondType<_DependentTp...> >
888    > { };
889
890    template <class _Up1, class _Up2, class ..._DependentTp>
891    struct _EnableExplicitMoveFromPair : _And<
892        is_constructible<_FirstType<_DependentTp...>, _Up1>,
893        is_constructible<_SecondType<_DependentTp...>, _Up2>,
894        _Not<is_convertible<_Up1, _FirstType<_DependentTp...> > >, // explicit check
895        _Not<is_convertible<_Up2, _SecondType<_DependentTp...> > >
896    > { };
897
898    template <class _Up1, class _Up2, template<class...> class _And = _And, _EnableIf<
899        _And<
900            _BoolConstant<sizeof...(_Tp) == 2>,
901            _EnableImplicitMoveFromPair<_Up1, _Up2, _Tp...>
902        >::value
903    , int> = 0>
904    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
905    tuple(pair<_Up1, _Up2>&& __p)
906        _NOEXCEPT_((_And<
907            is_nothrow_constructible<_FirstType<_Tp...>, _Up1>,
908            is_nothrow_constructible<_SecondType<_Tp...>, _Up2>
909        >::value))
910        : __base_(_VSTD::move(__p))
911    { }
912
913    template <class _Up1, class _Up2, template<class...> class _And = _And, _EnableIf<
914        _And<
915            _BoolConstant<sizeof...(_Tp) == 2>,
916            _EnableExplicitMoveFromPair<_Up1, _Up2, _Tp...>
917        >::value
918    , int> = 0>
919    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
920    explicit tuple(pair<_Up1, _Up2>&& __p)
921        _NOEXCEPT_((_And<
922            is_nothrow_constructible<_FirstType<_Tp...>, _Up1>,
923            is_nothrow_constructible<_SecondType<_Tp...>, _Up2>
924        >::value))
925        : __base_(_VSTD::move(__p))
926    { }
927
928    template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, _EnableIf<
929        _And<
930            _BoolConstant<sizeof...(_Tp) == 2>,
931            _EnableImplicitMoveFromPair<_Up1, _Up2, _Tp...>
932        >::value
933    , int> = 0>
934    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
935    tuple(allocator_arg_t, const _Alloc& __a, pair<_Up1, _Up2>&& __p)
936        : __base_(allocator_arg_t(), __a, _VSTD::move(__p))
937    { }
938
939    template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, _EnableIf<
940        _And<
941            _BoolConstant<sizeof...(_Tp) == 2>,
942            _EnableExplicitMoveFromPair<_Up1, _Up2, _Tp...>
943        >::value
944    , int> = 0>
945    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
946    explicit tuple(allocator_arg_t, const _Alloc& __a, pair<_Up1, _Up2>&& __p)
947        : __base_(allocator_arg_t(), __a, _VSTD::move(__p))
948    { }
949
950    // [tuple.assign]
951    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
952    tuple& operator=(_If<_And<is_copy_assignable<_Tp>...>::value, tuple, __nat> const& __tuple)
953        _NOEXCEPT_((_And<is_nothrow_copy_assignable<_Tp>...>::value))
954    {
955        _VSTD::__memberwise_copy_assign(*this, __tuple,
956            typename __make_tuple_indices<sizeof...(_Tp)>::type());
957        return *this;
958    }
959
960    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
961    tuple& operator=(_If<_And<is_move_assignable<_Tp>...>::value, tuple, __nat>&& __tuple)
962        _NOEXCEPT_((_And<is_nothrow_move_assignable<_Tp>...>::value))
963    {
964        _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__tuple),
965            __tuple_types<_Tp...>(),
966            typename __make_tuple_indices<sizeof...(_Tp)>::type());
967        return *this;
968    }
969
970    template<class... _Up, _EnableIf<
971        _And<
972            _BoolConstant<sizeof...(_Tp) == sizeof...(_Up)>,
973            is_assignable<_Tp&, _Up const&>...
974        >::value
975    ,int> = 0>
976    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
977    tuple& operator=(tuple<_Up...> const& __tuple)
978        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value))
979    {
980        _VSTD::__memberwise_copy_assign(*this, __tuple,
981            typename __make_tuple_indices<sizeof...(_Tp)>::type());
982        return *this;
983    }
984
985    template<class... _Up, _EnableIf<
986        _And<
987            _BoolConstant<sizeof...(_Tp) == sizeof...(_Up)>,
988            is_assignable<_Tp&, _Up>...
989        >::value
990    ,int> = 0>
991    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
992    tuple& operator=(tuple<_Up...>&& __tuple)
993        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up>...>::value))
994    {
995        _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__tuple),
996            __tuple_types<_Up...>(),
997            typename __make_tuple_indices<sizeof...(_Tp)>::type());
998        return *this;
999    }
1000
1001    template<class _Up1, class _Up2, class _Dep = true_type, _EnableIf<
1002        _And<_Dep,
1003            _BoolConstant<sizeof...(_Tp) == 2>,
1004            is_assignable<_FirstType<_Tp..., _Dep>&, _Up1 const&>,
1005            is_assignable<_SecondType<_Tp..., _Dep>&, _Up2 const&>
1006        >::value
1007    ,int> = 0>
1008    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1009    tuple& operator=(pair<_Up1, _Up2> const& __pair)
1010        _NOEXCEPT_((_And<
1011            is_nothrow_assignable<_FirstType<_Tp...>&, _Up1 const&>,
1012            is_nothrow_assignable<_SecondType<_Tp...>&, _Up2 const&>
1013        >::value))
1014    {
1015        _VSTD::get<0>(*this) = __pair.first;
1016        _VSTD::get<1>(*this) = __pair.second;
1017        return *this;
1018    }
1019
1020    template<class _Up1, class _Up2, class _Dep = true_type, _EnableIf<
1021        _And<_Dep,
1022            _BoolConstant<sizeof...(_Tp) == 2>,
1023            is_assignable<_FirstType<_Tp..., _Dep>&, _Up1>,
1024            is_assignable<_SecondType<_Tp..., _Dep>&, _Up2>
1025        >::value
1026    ,int> = 0>
1027    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1028    tuple& operator=(pair<_Up1, _Up2>&& __pair)
1029        _NOEXCEPT_((_And<
1030            is_nothrow_assignable<_FirstType<_Tp...>&, _Up1>,
1031            is_nothrow_assignable<_SecondType<_Tp...>&, _Up2>
1032        >::value))
1033    {
1034        _VSTD::get<0>(*this) = _VSTD::forward<_Up1>(__pair.first);
1035        _VSTD::get<1>(*this) = _VSTD::forward<_Up2>(__pair.second);
1036        return *this;
1037    }
1038
1039    // EXTENSION
1040    template<class _Up, size_t _Np, class = _EnableIf<
1041        _And<
1042            _BoolConstant<_Np == sizeof...(_Tp)>,
1043            is_assignable<_Tp&, _Up const&>...
1044        >::value
1045    > >
1046    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1047    tuple& operator=(array<_Up, _Np> const& __array)
1048        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value))
1049    {
1050        _VSTD::__memberwise_copy_assign(*this, __array,
1051            typename __make_tuple_indices<sizeof...(_Tp)>::type());
1052        return *this;
1053    }
1054
1055    // EXTENSION
1056    template<class _Up, size_t _Np, class = void, class = _EnableIf<
1057        _And<
1058            _BoolConstant<_Np == sizeof...(_Tp)>,
1059            is_assignable<_Tp&, _Up>...
1060        >::value
1061    > >
1062    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1063    tuple& operator=(array<_Up, _Np>&& __array)
1064        _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up>...>::value))
1065    {
1066        _VSTD::__memberwise_forward_assign(*this, _VSTD::move(__array),
1067            __tuple_types<_If<true, _Up, _Tp>...>(),
1068            typename __make_tuple_indices<sizeof...(_Tp)>::type());
1069        return *this;
1070    }
1071
1072    // [tuple.swap]
1073    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1074    void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
1075        {__base_.swap(__t.__base_);}
1076};
1077
1078template <>
1079class _LIBCPP_TEMPLATE_VIS tuple<>
1080{
1081public:
1082    _LIBCPP_INLINE_VISIBILITY constexpr
1083        tuple() _NOEXCEPT = default;
1084    template <class _Alloc>
1085    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1086        tuple(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
1087    template <class _Alloc>
1088    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1089        tuple(allocator_arg_t, const _Alloc&, const tuple&) _NOEXCEPT {}
1090    template <class _Up>
1091    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1092        tuple(array<_Up, 0>) _NOEXCEPT {}
1093    template <class _Alloc, class _Up>
1094    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1095        tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) _NOEXCEPT {}
1096    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1097    void swap(tuple&) _NOEXCEPT {}
1098};
1099
1100#ifndef _LIBCPP_HAS_NO_DEDUCTION_GUIDES
1101template <class ..._Tp>
1102tuple(_Tp...) -> tuple<_Tp...>;
1103template <class _Tp1, class _Tp2>
1104tuple(pair<_Tp1, _Tp2>) -> tuple<_Tp1, _Tp2>;
1105template <class _Alloc, class ..._Tp>
1106tuple(allocator_arg_t, _Alloc, _Tp...) -> tuple<_Tp...>;
1107template <class _Alloc, class _Tp1, class _Tp2>
1108tuple(allocator_arg_t, _Alloc, pair<_Tp1, _Tp2>) -> tuple<_Tp1, _Tp2>;
1109template <class _Alloc, class ..._Tp>
1110tuple(allocator_arg_t, _Alloc, tuple<_Tp...>) -> tuple<_Tp...>;
1111#endif
1112
1113template <class ..._Tp>
1114inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1115typename enable_if
1116<
1117    __all<__is_swappable<_Tp>::value...>::value,
1118    void
1119>::type
1120swap(tuple<_Tp...>& __t, tuple<_Tp...>& __u)
1121                 _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
1122    {__t.swap(__u);}
1123
1124// get
1125
1126template <size_t _Ip, class ..._Tp>
1127inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1128typename tuple_element<_Ip, tuple<_Tp...> >::type&
1129get(tuple<_Tp...>& __t) _NOEXCEPT
1130{
1131    typedef _LIBCPP_NODEBUG_TYPE typename tuple_element<_Ip, tuple<_Tp...> >::type type;
1132    return static_cast<__tuple_leaf<_Ip, type>&>(__t.__base_).get();
1133}
1134
1135template <size_t _Ip, class ..._Tp>
1136inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1137const typename tuple_element<_Ip, tuple<_Tp...> >::type&
1138get(const tuple<_Tp...>& __t) _NOEXCEPT
1139{
1140    typedef _LIBCPP_NODEBUG_TYPE typename tuple_element<_Ip, tuple<_Tp...> >::type type;
1141    return static_cast<const __tuple_leaf<_Ip, type>&>(__t.__base_).get();
1142}
1143
1144template <size_t _Ip, class ..._Tp>
1145inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1146typename tuple_element<_Ip, tuple<_Tp...> >::type&&
1147get(tuple<_Tp...>&& __t) _NOEXCEPT
1148{
1149    typedef _LIBCPP_NODEBUG_TYPE typename tuple_element<_Ip, tuple<_Tp...> >::type type;
1150    return static_cast<type&&>(
1151             static_cast<__tuple_leaf<_Ip, type>&&>(__t.__base_).get());
1152}
1153
1154template <size_t _Ip, class ..._Tp>
1155inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1156const typename tuple_element<_Ip, tuple<_Tp...> >::type&&
1157get(const tuple<_Tp...>&& __t) _NOEXCEPT
1158{
1159    typedef _LIBCPP_NODEBUG_TYPE typename tuple_element<_Ip, tuple<_Tp...> >::type type;
1160    return static_cast<const type&&>(
1161             static_cast<const __tuple_leaf<_Ip, type>&&>(__t.__base_).get());
1162}
1163
1164#if _LIBCPP_STD_VER > 11
1165
1166namespace __find_detail {
1167
1168static constexpr size_t __not_found = static_cast<size_t>(-1);
1169static constexpr size_t __ambiguous = __not_found - 1;
1170
1171inline _LIBCPP_INLINE_VISIBILITY
1172constexpr size_t __find_idx_return(size_t __curr_i, size_t __res, bool __matches) {
1173    return !__matches ? __res :
1174        (__res == __not_found ? __curr_i : __ambiguous);
1175}
1176
1177template <size_t _Nx>
1178inline _LIBCPP_INLINE_VISIBILITY
1179constexpr size_t __find_idx(size_t __i, const bool (&__matches)[_Nx]) {
1180  return __i == _Nx ? __not_found :
1181      __find_idx_return(__i, __find_idx(__i + 1, __matches), __matches[__i]);
1182}
1183
1184template <class _T1, class ..._Args>
1185struct __find_exactly_one_checked {
1186    static constexpr bool __matches[sizeof...(_Args)] = {is_same<_T1, _Args>::value...};
1187    static constexpr size_t value = __find_detail::__find_idx(0, __matches);
1188    static_assert(value != __not_found, "type not found in type list" );
1189    static_assert(value != __ambiguous, "type occurs more than once in type list");
1190};
1191
1192template <class _T1>
1193struct __find_exactly_one_checked<_T1> {
1194    static_assert(!is_same<_T1, _T1>::value, "type not in empty type list");
1195};
1196
1197} // namespace __find_detail;
1198
1199template <typename _T1, typename... _Args>
1200struct __find_exactly_one_t
1201    : public __find_detail::__find_exactly_one_checked<_T1, _Args...> {
1202};
1203
1204template <class _T1, class... _Args>
1205inline _LIBCPP_INLINE_VISIBILITY
1206constexpr _T1& get(tuple<_Args...>& __tup) noexcept
1207{
1208    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
1209}
1210
1211template <class _T1, class... _Args>
1212inline _LIBCPP_INLINE_VISIBILITY
1213constexpr _T1 const& get(tuple<_Args...> const& __tup) noexcept
1214{
1215    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
1216}
1217
1218template <class _T1, class... _Args>
1219inline _LIBCPP_INLINE_VISIBILITY
1220constexpr _T1&& get(tuple<_Args...>&& __tup) noexcept
1221{
1222    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));
1223}
1224
1225template <class _T1, class... _Args>
1226inline _LIBCPP_INLINE_VISIBILITY
1227constexpr _T1 const&& get(tuple<_Args...> const&& __tup) noexcept
1228{
1229    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));
1230}
1231
1232#endif
1233
1234// tie
1235
1236template <class ..._Tp>
1237inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1238tuple<_Tp&...>
1239tie(_Tp&... __t) _NOEXCEPT
1240{
1241    return tuple<_Tp&...>(__t...);
1242}
1243
1244template <class _Up>
1245struct __ignore_t
1246{
1247    template <class _Tp>
1248    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1249    const __ignore_t& operator=(_Tp&&) const {return *this;}
1250};
1251
1252namespace {
1253  _LIBCPP_INLINE_VAR constexpr __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>();
1254}
1255
1256template <class... _Tp>
1257inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1258tuple<typename __unwrap_ref_decay<_Tp>::type...>
1259make_tuple(_Tp&&... __t)
1260{
1261    return tuple<typename __unwrap_ref_decay<_Tp>::type...>(_VSTD::forward<_Tp>(__t)...);
1262}
1263
1264template <class... _Tp>
1265inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1266tuple<_Tp&&...>
1267forward_as_tuple(_Tp&&... __t) _NOEXCEPT
1268{
1269    return tuple<_Tp&&...>(_VSTD::forward<_Tp>(__t)...);
1270}
1271
1272template <size_t _Ip>
1273struct __tuple_equal
1274{
1275    template <class _Tp, class _Up>
1276    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1277    bool operator()(const _Tp& __x, const _Up& __y)
1278    {
1279        return __tuple_equal<_Ip - 1>()(__x, __y) && _VSTD::get<_Ip-1>(__x) == _VSTD::get<_Ip-1>(__y);
1280    }
1281};
1282
1283template <>
1284struct __tuple_equal<0>
1285{
1286    template <class _Tp, class _Up>
1287    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1288    bool operator()(const _Tp&, const _Up&)
1289    {
1290        return true;
1291    }
1292};
1293
1294template <class ..._Tp, class ..._Up>
1295inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1296bool
1297operator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1298{
1299    static_assert (sizeof...(_Tp) == sizeof...(_Up), "Can't compare tuples of different sizes");
1300    return __tuple_equal<sizeof...(_Tp)>()(__x, __y);
1301}
1302
1303template <class ..._Tp, class ..._Up>
1304inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1305bool
1306operator!=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1307{
1308    return !(__x == __y);
1309}
1310
1311template <size_t _Ip>
1312struct __tuple_less
1313{
1314    template <class _Tp, class _Up>
1315    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1316    bool operator()(const _Tp& __x, const _Up& __y)
1317    {
1318        const size_t __idx = tuple_size<_Tp>::value - _Ip;
1319        if (_VSTD::get<__idx>(__x) < _VSTD::get<__idx>(__y))
1320            return true;
1321        if (_VSTD::get<__idx>(__y) < _VSTD::get<__idx>(__x))
1322            return false;
1323        return __tuple_less<_Ip-1>()(__x, __y);
1324    }
1325};
1326
1327template <>
1328struct __tuple_less<0>
1329{
1330    template <class _Tp, class _Up>
1331    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1332    bool operator()(const _Tp&, const _Up&)
1333    {
1334        return false;
1335    }
1336};
1337
1338template <class ..._Tp, class ..._Up>
1339inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1340bool
1341operator<(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1342{
1343    static_assert (sizeof...(_Tp) == sizeof...(_Up), "Can't compare tuples of different sizes");
1344    return __tuple_less<sizeof...(_Tp)>()(__x, __y);
1345}
1346
1347template <class ..._Tp, class ..._Up>
1348inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1349bool
1350operator>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1351{
1352    return __y < __x;
1353}
1354
1355template <class ..._Tp, class ..._Up>
1356inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1357bool
1358operator>=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1359{
1360    return !(__x < __y);
1361}
1362
1363template <class ..._Tp, class ..._Up>
1364inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1365bool
1366operator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1367{
1368    return !(__y < __x);
1369}
1370
1371// tuple_cat
1372
1373template <class _Tp, class _Up> struct __tuple_cat_type;
1374
1375template <class ..._Ttypes, class ..._Utypes>
1376struct __tuple_cat_type<tuple<_Ttypes...>, __tuple_types<_Utypes...> >
1377{
1378    typedef _LIBCPP_NODEBUG_TYPE tuple<_Ttypes..., _Utypes...> type;
1379};
1380
1381template <class _ResultTuple, bool _Is_Tuple0TupleLike, class ..._Tuples>
1382struct __tuple_cat_return_1
1383{
1384};
1385
1386template <class ..._Types, class _Tuple0>
1387struct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0>
1388{
1389    typedef _LIBCPP_NODEBUG_TYPE typename __tuple_cat_type<tuple<_Types...>,
1390            typename __make_tuple_types<typename __uncvref<_Tuple0>::type>::type>::type
1391                                                                           type;
1392};
1393
1394template <class ..._Types, class _Tuple0, class _Tuple1, class ..._Tuples>
1395struct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0, _Tuple1, _Tuples...>
1396    : public __tuple_cat_return_1<
1397                 typename __tuple_cat_type<
1398                     tuple<_Types...>,
1399                     typename __make_tuple_types<typename __uncvref<_Tuple0>::type>::type
1400                 >::type,
1401                 __tuple_like<typename remove_reference<_Tuple1>::type>::value,
1402                 _Tuple1, _Tuples...>
1403{
1404};
1405
1406template <class ..._Tuples> struct __tuple_cat_return;
1407
1408template <class _Tuple0, class ..._Tuples>
1409struct __tuple_cat_return<_Tuple0, _Tuples...>
1410    : public __tuple_cat_return_1<tuple<>,
1411         __tuple_like<typename remove_reference<_Tuple0>::type>::value, _Tuple0,
1412                                                                     _Tuples...>
1413{
1414};
1415
1416template <>
1417struct __tuple_cat_return<>
1418{
1419    typedef _LIBCPP_NODEBUG_TYPE tuple<> type;
1420};
1421
1422inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1423tuple<>
1424tuple_cat()
1425{
1426    return tuple<>();
1427}
1428
1429template <class _Rp, class _Indices, class _Tuple0, class ..._Tuples>
1430struct __tuple_cat_return_ref_imp;
1431
1432template <class ..._Types, size_t ..._I0, class _Tuple0>
1433struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, _Tuple0>
1434{
1435    typedef _LIBCPP_NODEBUG_TYPE typename remove_reference<_Tuple0>::type _T0;
1436    typedef tuple<_Types..., typename __apply_cv<_Tuple0,
1437                          typename tuple_element<_I0, _T0>::type>::type&&...> type;
1438};
1439
1440template <class ..._Types, size_t ..._I0, class _Tuple0, class _Tuple1, class ..._Tuples>
1441struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>,
1442                                  _Tuple0, _Tuple1, _Tuples...>
1443    : public __tuple_cat_return_ref_imp<
1444         tuple<_Types..., typename __apply_cv<_Tuple0,
1445               typename tuple_element<_I0,
1446                  typename remove_reference<_Tuple0>::type>::type>::type&&...>,
1447         typename __make_tuple_indices<tuple_size<typename
1448                                 remove_reference<_Tuple1>::type>::value>::type,
1449         _Tuple1, _Tuples...>
1450{
1451};
1452
1453template <class _Tuple0, class ..._Tuples>
1454struct __tuple_cat_return_ref
1455    : public __tuple_cat_return_ref_imp<tuple<>,
1456               typename __make_tuple_indices<
1457                        tuple_size<typename remove_reference<_Tuple0>::type>::value
1458               >::type, _Tuple0, _Tuples...>
1459{
1460};
1461
1462template <class _Types, class _I0, class _J0>
1463struct __tuple_cat;
1464
1465template <class ..._Types, size_t ..._I0, size_t ..._J0>
1466struct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J0...> >
1467{
1468    template <class _Tuple0>
1469    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1470    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&>::type
1471    operator()(tuple<_Types...> __t, _Tuple0&& __t0)
1472    {
1473        return _VSTD::forward_as_tuple(
1474            _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
1475            _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...);
1476    }
1477
1478    template <class _Tuple0, class _Tuple1, class ..._Tuples>
1479    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1480    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&, _Tuple1&&, _Tuples&&...>::type
1481    operator()(tuple<_Types...> __t, _Tuple0&& __t0, _Tuple1&& __t1, _Tuples&& ...__tpls)
1482    {
1483        typedef _LIBCPP_NODEBUG_TYPE typename remove_reference<_Tuple0>::type _T0;
1484        typedef _LIBCPP_NODEBUG_TYPE typename remove_reference<_Tuple1>::type _T1;
1485        return __tuple_cat<
1486            tuple<_Types...,
1487                  typename __apply_cv<_Tuple0, typename tuple_element<
1488                                                   _J0, _T0>::type>::type&&...>,
1489            typename __make_tuple_indices<sizeof...(_Types) +
1490                                          tuple_size<_T0>::value>::type,
1491            typename __make_tuple_indices<tuple_size<_T1>::value>::type>()(
1492            _VSTD::forward_as_tuple(
1493                _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
1494                _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...),
1495            _VSTD::forward<_Tuple1>(__t1), _VSTD::forward<_Tuples>(__tpls)...);
1496    }
1497};
1498
1499template <class _Tuple0, class... _Tuples>
1500inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1501typename __tuple_cat_return<_Tuple0, _Tuples...>::type
1502tuple_cat(_Tuple0&& __t0, _Tuples&&... __tpls)
1503{
1504    typedef _LIBCPP_NODEBUG_TYPE typename remove_reference<_Tuple0>::type _T0;
1505    return __tuple_cat<tuple<>, __tuple_indices<>,
1506                  typename __make_tuple_indices<tuple_size<_T0>::value>::type>()
1507                  (tuple<>(), _VSTD::forward<_Tuple0>(__t0),
1508                                            _VSTD::forward<_Tuples>(__tpls)...);
1509}
1510
1511template <class ..._Tp, class _Alloc>
1512struct _LIBCPP_TEMPLATE_VIS uses_allocator<tuple<_Tp...>, _Alloc>
1513    : true_type {};
1514
1515template <class _T1, class _T2>
1516template <class... _Args1, class... _Args2, size_t ..._I1, size_t ..._I2>
1517inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX17
1518pair<_T1, _T2>::pair(piecewise_construct_t,
1519                     tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,
1520                     __tuple_indices<_I1...>, __tuple_indices<_I2...>)
1521    :  first(_VSTD::forward<_Args1>(_VSTD::get<_I1>( __first_args))...),
1522      second(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...)
1523{
1524}
1525
1526#if _LIBCPP_STD_VER > 14
1527template <class _Tp>
1528_LIBCPP_INLINE_VAR constexpr size_t tuple_size_v = tuple_size<_Tp>::value;
1529
1530#define _LIBCPP_NOEXCEPT_RETURN(...) noexcept(noexcept(__VA_ARGS__)) { return __VA_ARGS__; }
1531
1532template <class _Fn, class _Tuple, size_t ..._Id>
1533inline _LIBCPP_INLINE_VISIBILITY
1534constexpr decltype(auto) __apply_tuple_impl(_Fn && __f, _Tuple && __t,
1535                                            __tuple_indices<_Id...>)
1536_LIBCPP_NOEXCEPT_RETURN(
1537    _VSTD::__invoke_constexpr(
1538        _VSTD::forward<_Fn>(__f),
1539        _VSTD::get<_Id>(_VSTD::forward<_Tuple>(__t))...)
1540)
1541
1542template <class _Fn, class _Tuple>
1543inline _LIBCPP_INLINE_VISIBILITY
1544constexpr decltype(auto) apply(_Fn && __f, _Tuple && __t)
1545_LIBCPP_NOEXCEPT_RETURN(
1546    _VSTD::__apply_tuple_impl(
1547        _VSTD::forward<_Fn>(__f), _VSTD::forward<_Tuple>(__t),
1548        typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{})
1549)
1550
1551template <class _Tp, class _Tuple, size_t... _Idx>
1552inline _LIBCPP_INLINE_VISIBILITY
1553constexpr _Tp __make_from_tuple_impl(_Tuple&& __t, __tuple_indices<_Idx...>)
1554_LIBCPP_NOEXCEPT_RETURN(
1555    _Tp(_VSTD::get<_Idx>(_VSTD::forward<_Tuple>(__t))...)
1556)
1557
1558template <class _Tp, class _Tuple>
1559inline _LIBCPP_INLINE_VISIBILITY
1560constexpr _Tp make_from_tuple(_Tuple&& __t)
1561_LIBCPP_NOEXCEPT_RETURN(
1562    _VSTD::__make_from_tuple_impl<_Tp>(_VSTD::forward<_Tuple>(__t),
1563        typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{})
1564)
1565
1566#undef _LIBCPP_NOEXCEPT_RETURN
1567
1568#endif // _LIBCPP_STD_VER > 14
1569
1570#endif // !defined(_LIBCPP_CXX03_LANG)
1571
1572_LIBCPP_END_NAMESPACE_STD
1573
1574#endif // _LIBCPP_TUPLE
1575