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