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