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