[libc] Fix improper initialization of `StorageType` (#75610)
[llvm-project.git] / libcxx / include / tuple
blob194138f7076c1bf126be723a765a091cc0d28dbd
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 //===----------------------------------------------------------------------===//
10 #ifndef _LIBCPP_TUPLE
11 #define _LIBCPP_TUPLE
13 // clang-format off
16     tuple synopsis
18 namespace std
21 template <class... T>
22 class tuple {
23 public:
24     explicit(see-below) constexpr tuple();
25     explicit(see-below) tuple(const T&...);  // constexpr in C++14
26     template <class... U>
27         explicit(see-below) tuple(U&&...);  // constexpr in C++14
28     tuple(const tuple&) = default;
29     tuple(tuple&&) = default;
31     template<class... UTypes>
32         constexpr explicit(see-below) tuple(tuple<UTypes...>&);  // C++23
33     template <class... U>
34         explicit(see-below) tuple(const tuple<U...>&);  // constexpr in C++14
35     template <class... U>
36         explicit(see-below) tuple(tuple<U...>&&);  // constexpr in C++14
37     template<class... UTypes>
38         constexpr explicit(see-below) tuple(const tuple<UTypes...>&&); // C++23
40     template<class U1, class U2>
41         constexpr explicit(see-below) tuple(pair<U1, U2>&);  // iff sizeof...(Types) == 2 // C++23
42     template <class U1, class U2>
43         explicit(see-below) tuple(const pair<U1, U2>&); // iff sizeof...(T) == 2 // constexpr in C++14
44     template <class U1, class U2>
45         explicit(see-below) tuple(pair<U1, U2>&&); // iff sizeof...(T) == 2  // constexpr in C++14
46     template<class U1, class U2>
47         constexpr explicit(see-below) tuple(const pair<U1, U2>&&);  // iff sizeof...(Types) == 2 // C++23
49     // allocator-extended constructors
50     template <class Alloc>
51         tuple(allocator_arg_t, const Alloc& a);
52     template <class Alloc>
53         explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const T&...);          // constexpr in C++20
54     template <class Alloc, class... U>
55         explicit(see-below) tuple(allocator_arg_t, const Alloc& a, U&&...);               // constexpr in C++20
56     template <class Alloc>
57         tuple(allocator_arg_t, const Alloc& a, const tuple&);                             // constexpr in C++20
58     template <class Alloc>
59         tuple(allocator_arg_t, const Alloc& a, tuple&&);                                  // constexpr in C++20
60     template<class Alloc, class... UTypes>
61         constexpr explicit(see-below)
62           tuple(allocator_arg_t, const Alloc& a, tuple<UTypes...>&);                      // C++23
63     template <class Alloc, class... U>
64         explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const tuple<U...>&);   // constexpr in C++20
65     template <class Alloc, class... U>
66         explicit(see-below) tuple(allocator_arg_t, const Alloc& a, tuple<U...>&&);        // constexpr in C++20
67     template<class Alloc, class... UTypes>
68         constexpr explicit(see-below)
69           tuple(allocator_arg_t, const Alloc& a, const tuple<UTypes...>&&);               // C++23
70     template<class Alloc, class U1, class U2>
71         constexpr explicit(see-below)
72           tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&);                          // C++23
73     template <class Alloc, class U1, class U2>
74         explicit(see-below) tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&);  // constexpr in C++20
75     template <class Alloc, class U1, class U2>
76         explicit(see-below) tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&);       // constexpr in C++20
77     template<class Alloc, class U1, class U2>
78         constexpr explicit(see-below)
79           tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&&);                   // C++23
81     tuple& operator=(const tuple&);                                                       // constexpr in C++20
82     constexpr const tuple& operator=(const tuple&) const;                                 // C++23
83     tuple& operator=(tuple&&) noexcept(is_nothrow_move_assignable_v<T> && ...);           // constexpr in C++20
84     constexpr const tuple& operator=(tuple&&) const;                                      // C++23
85     template <class... U>
86         tuple& operator=(const tuple<U...>&);                                             // constexpr in C++20
87     template<class... UTypes>
88         constexpr const tuple& operator=(const tuple<UTypes...>&) const;                  // C++23
89     template <class... U>
90         tuple& operator=(tuple<U...>&&);                                                  // constexpr in C++20
91     template<class... UTypes>
92         constexpr const tuple& operator=(tuple<UTypes...>&&) const;                       // C++23
93     template <class U1, class U2>
94         tuple& operator=(const pair<U1, U2>&); // iff sizeof...(T) == 2                   // constexpr in C++20
95     template<class U1, class U2>
96         constexpr const tuple& operator=(const pair<U1, U2>&) const;   // iff sizeof...(Types) == 2 // C++23
97     template <class U1, class U2>
98         tuple& operator=(pair<U1, U2>&&); // iff sizeof...(T) == 2                        // constexpr in C++20
99     template<class U1, class U2>
100         constexpr const tuple& operator=(pair<U1, U2>&&) const;  // iff sizeof...(Types) == 2 // C++23
102     template<class U, size_t N>
103         tuple& operator=(array<U, N> const&) // iff sizeof...(T) == N, EXTENSION
104     template<class U, size_t N>
105         tuple& operator=(array<U, N>&&) // iff sizeof...(T) == N, EXTENSION
107     void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...));               // constexpr in C++20
108     constexpr void swap(const tuple&) const noexcept(see-below);                          // C++23
112 template<class... TTypes, class... UTypes, template<class> class TQual, template<class> class UQual> // since C++23
113   requires requires { typename tuple<common_reference_t<TQual<TTypes>, UQual<UTypes>>...>; }
114 struct basic_common_reference<tuple<TTypes...>, tuple<UTypes...>, TQual, UQual> {
115   using type = tuple<common_reference_t<TQual<TTypes>, UQual<UTypes>>...>;
118 template<class... TTypes, class... UTypes>                                // since C++23
119   requires requires { typename tuple<common_type_t<TTypes, UTypes>...>; }
120 struct common_type<tuple<TTypes...>, tuple<UTypes...>> {
121   using type = tuple<common_type_t<TTypes, UTypes>...>;
124 template <class ...T>
125 tuple(T...) -> tuple<T...>;                                         // since C++17
126 template <class T1, class T2>
127 tuple(pair<T1, T2>) -> tuple<T1, T2>;                               // since C++17
128 template <class Alloc, class ...T>
129 tuple(allocator_arg_t, Alloc, T...) -> tuple<T...>;                 // since C++17
130 template <class Alloc, class T1, class T2>
131 tuple(allocator_arg_t, Alloc, pair<T1, T2>) -> tuple<T1, T2>;       // since C++17
132 template <class Alloc, class ...T>
133 tuple(allocator_arg_t, Alloc, tuple<T...>) -> tuple<T...>;          // since C++17
135 inline constexpr unspecified ignore;
137 template <class... T> tuple<V...>  make_tuple(T&&...); // constexpr in C++14
138 template <class... T> tuple<ATypes...> forward_as_tuple(T&&...) noexcept; // constexpr in C++14
139 template <class... T> tuple<T&...> tie(T&...) noexcept; // constexpr in C++14
140 template <class... Tuples> tuple<CTypes...> tuple_cat(Tuples&&... tpls); // constexpr in C++14
142 // [tuple.apply], calling a function with a tuple of arguments:
143 template <class F, class Tuple>
144   constexpr decltype(auto) apply(F&& f, Tuple&& t); // C++17
145 template <class T, class Tuple>
146   constexpr T make_from_tuple(Tuple&& t); // C++17
148 // 20.4.1.4, tuple helper classes:
149 template <class T> struct tuple_size; // undefined
150 template <class... T> struct tuple_size<tuple<T...>>;
151 template <class T>
152  inline constexpr size_t tuple_size_v = tuple_size<T>::value; // C++17
153 template <size_t I, class T> struct tuple_element; // undefined
154 template <size_t I, class... T> struct tuple_element<I, tuple<T...>>;
155 template <size_t I, class T>
156   using tuple_element_t = typename tuple_element <I, T>::type; // C++14
158 // 20.4.1.5, element access:
159 template <size_t I, class... T>
160     typename tuple_element<I, tuple<T...>>::type&
161     get(tuple<T...>&) noexcept; // constexpr in C++14
162 template <size_t I, class... T>
163     const typename tuple_element<I, tuple<T...>>::type&
164     get(const tuple<T...>&) noexcept; // constexpr in C++14
165 template <size_t I, class... T>
166     typename tuple_element<I, tuple<T...>>::type&&
167     get(tuple<T...>&&) noexcept; // constexpr in C++14
168 template <size_t I, class... T>
169     const typename tuple_element<I, tuple<T...>>::type&&
170     get(const tuple<T...>&&) noexcept; // constexpr in C++14
172 template <class T1, class... T>
173     constexpr T1& get(tuple<T...>&) noexcept;  // C++14
174 template <class T1, class... T>
175     constexpr const T1& get(const tuple<T...>&) noexcept;   // C++14
176 template <class T1, class... T>
177     constexpr T1&& get(tuple<T...>&&) noexcept;   // C++14
178 template <class T1, class... T>
179     constexpr const T1&& get(const tuple<T...>&&) noexcept;   // C++14
181 // 20.4.1.6, relational operators:
182 template<class... T, class... U> bool operator==(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
183 template<class... T, class... U> bool operator<(const tuple<T...>&, const tuple<U...>&);  // constexpr in C++14, removed in C++20
184 template<class... T, class... U> bool operator!=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14, removed in C++20
185 template<class... T, class... U> bool operator>(const tuple<T...>&, const tuple<U...>&);  // constexpr in C++14, removed in C++20
186 template<class... T, class... U> bool operator<=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14, removed in C++20
187 template<class... T, class... U> bool operator>=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14, removed in C++20
188 template<class... T, class... U>
189   constexpr common_comparison_category_t<synth-three-way-result<T, U>...>
190     operator<=>(const tuple<T...>&, const tuple<U...>&);                                  // since C++20
192 template <class... Types, class Alloc>
193   struct uses_allocator<tuple<Types...>, Alloc>;
195 template <class... Types>
196   void
197   swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(noexcept(x.swap(y)));
199 template <class... Types>
200   constexpr void swap(const tuple<Types...>& x, const tuple<Types...>& y) noexcept(see-below);   // C++23
202 }  // std
206 // clang-format on
208 #include <__assert> // all public C++ headers provide the assertion handler
209 #include <__compare/common_comparison_category.h>
210 #include <__compare/synth_three_way.h>
211 #include <__config>
212 #include <__functional/invoke.h>
213 #include <__fwd/array.h>
214 #include <__fwd/get.h>
215 #include <__fwd/tuple.h>
216 #include <__memory/allocator_arg_t.h>
217 #include <__memory/uses_allocator.h>
218 #include <__tuple/make_tuple_types.h>
219 #include <__tuple/sfinae_helpers.h>
220 #include <__tuple/tuple_element.h>
221 #include <__tuple/tuple_indices.h>
222 #include <__tuple/tuple_like_ext.h>
223 #include <__tuple/tuple_size.h>
224 #include <__tuple/tuple_types.h>
225 #include <__type_traits/apply_cv.h>
226 #include <__type_traits/common_reference.h>
227 #include <__type_traits/common_type.h>
228 #include <__type_traits/conditional.h>
229 #include <__type_traits/conjunction.h>
230 #include <__type_traits/copy_cvref.h>
231 #include <__type_traits/disjunction.h>
232 #include <__type_traits/is_arithmetic.h>
233 #include <__type_traits/is_assignable.h>
234 #include <__type_traits/is_constructible.h>
235 #include <__type_traits/is_convertible.h>
236 #include <__type_traits/is_copy_assignable.h>
237 #include <__type_traits/is_copy_constructible.h>
238 #include <__type_traits/is_default_constructible.h>
239 #include <__type_traits/is_empty.h>
240 #include <__type_traits/is_final.h>
241 #include <__type_traits/is_implicitly_default_constructible.h>
242 #include <__type_traits/is_move_assignable.h>
243 #include <__type_traits/is_move_constructible.h>
244 #include <__type_traits/is_nothrow_assignable.h>
245 #include <__type_traits/is_nothrow_constructible.h>
246 #include <__type_traits/is_nothrow_copy_assignable.h>
247 #include <__type_traits/is_nothrow_copy_constructible.h>
248 #include <__type_traits/is_nothrow_default_constructible.h>
249 #include <__type_traits/is_nothrow_move_assignable.h>
250 #include <__type_traits/is_reference.h>
251 #include <__type_traits/is_same.h>
252 #include <__type_traits/is_swappable.h>
253 #include <__type_traits/lazy.h>
254 #include <__type_traits/maybe_const.h>
255 #include <__type_traits/nat.h>
256 #include <__type_traits/negation.h>
257 #include <__type_traits/remove_cvref.h>
258 #include <__type_traits/remove_reference.h>
259 #include <__type_traits/unwrap_ref.h>
260 #include <__utility/forward.h>
261 #include <__utility/integer_sequence.h>
262 #include <__utility/move.h>
263 #include <__utility/pair.h>
264 #include <__utility/piecewise_construct.h>
265 #include <__utility/swap.h>
266 #include <cstddef>
267 #include <version>
269 // standard-mandated includes
271 // [tuple.syn]
272 #include <compare>
274 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
275 #  pragma GCC system_header
276 #endif
278 _LIBCPP_PUSH_MACROS
279 #include <__undef_macros>
281 _LIBCPP_BEGIN_NAMESPACE_STD
283 #ifndef _LIBCPP_CXX03_LANG
286 // __tuple_leaf
288 template <size_t _Ip, class _Hp,
289           bool=is_empty<_Hp>::value && !__libcpp_is_final<_Hp>::value
290          >
291 class __tuple_leaf;
293 template <size_t _Ip, class _Hp, bool _Ep>
294 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
295 void swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y)
296     _NOEXCEPT_(__is_nothrow_swappable<_Hp>::value)
298     swap(__x.get(), __y.get());
301 template <size_t _Ip, class _Hp, bool _Ep>
302 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
303 void swap(const __tuple_leaf<_Ip, _Hp, _Ep>& __x, const __tuple_leaf<_Ip, _Hp, _Ep>& __y)
304      _NOEXCEPT_(__is_nothrow_swappable<const _Hp>::value) {
305   swap(__x.get(), __y.get());
308 template <size_t _Ip, class _Hp, bool>
309 class __tuple_leaf
311     _Hp __value_;
313     template <class _Tp>
314     static _LIBCPP_HIDE_FROM_ABI constexpr bool __can_bind_reference() {
315 #if __has_keyword(__reference_binds_to_temporary)
316       return !__reference_binds_to_temporary(_Hp, _Tp);
317 #else
318       return true;
319 #endif
320     }
322     _LIBCPP_CONSTEXPR_SINCE_CXX14
323     __tuple_leaf& operator=(const __tuple_leaf&);
324 public:
325     _LIBCPP_HIDE_FROM_ABI constexpr __tuple_leaf()
326              _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) : __value_()
327        {static_assert(!is_reference<_Hp>::value,
328               "Attempted to default construct a reference element in a tuple");}
330     template <class _Alloc>
331         _LIBCPP_HIDE_FROM_ABI constexpr
332         __tuple_leaf(integral_constant<int, 0>, const _Alloc&)
333             : __value_()
334         {static_assert(!is_reference<_Hp>::value,
335               "Attempted to default construct a reference element in a tuple");}
337     template <class _Alloc>
338         _LIBCPP_HIDE_FROM_ABI constexpr
339         __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
340             : __value_(allocator_arg_t(), __a)
341         {static_assert(!is_reference<_Hp>::value,
342               "Attempted to default construct a reference element in a tuple");}
344     template <class _Alloc>
345         _LIBCPP_HIDE_FROM_ABI constexpr
346         __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
347             : __value_(__a)
348         {static_assert(!is_reference<_Hp>::value,
349               "Attempted to default construct a reference element in a tuple");}
351     template <class _Tp,
352               class = __enable_if_t<
353                   _And<
354                       _IsNotSame<__remove_cvref_t<_Tp>, __tuple_leaf>,
355                       is_constructible<_Hp, _Tp>
356                     >::value
357                 >
358             >
359         _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
360         explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
361             : __value_(std::forward<_Tp>(__t))
362         {static_assert(__can_bind_reference<_Tp&&>(),
363        "Attempted construction of reference element binds to a temporary whose lifetime has ended");}
365     template <class _Tp, class _Alloc>
366         _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
367         explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
368             : __value_(std::forward<_Tp>(__t))
369         {static_assert(__can_bind_reference<_Tp&&>(),
370        "Attempted construction of reference element binds to a temporary whose lifetime has ended");}
372     template <class _Tp, class _Alloc>
373         _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
374         explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
375             : __value_(allocator_arg_t(), __a, std::forward<_Tp>(__t))
376         {static_assert(!is_reference<_Hp>::value,
377             "Attempted to uses-allocator construct a reference element in a tuple");}
379     template <class _Tp, class _Alloc>
380         _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
381         explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
382             : __value_(std::forward<_Tp>(__t), __a)
383         {static_assert(!is_reference<_Hp>::value,
384            "Attempted to uses-allocator construct a reference element in a tuple");}
386     _LIBCPP_HIDE_FROM_ABI __tuple_leaf(const __tuple_leaf& __t) = default;
387     _LIBCPP_HIDE_FROM_ABI __tuple_leaf(__tuple_leaf&& __t) = default;
389     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
390     int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
391     {
392         std::swap(*this, __t);
393         return 0;
394     }
396     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
397     int swap(const __tuple_leaf& __t) const _NOEXCEPT_(__is_nothrow_swappable<const __tuple_leaf>::value) {
398         std::swap(*this, __t);
399         return 0;
400     }
402     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14       _Hp& get()       _NOEXCEPT {return __value_;}
403     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Hp& get() const _NOEXCEPT {return __value_;}
406 template <size_t _Ip, class _Hp>
407 class __tuple_leaf<_Ip, _Hp, true>
408     : private _Hp
410     _LIBCPP_CONSTEXPR_SINCE_CXX14
411     __tuple_leaf& operator=(const __tuple_leaf&);
412 public:
413     _LIBCPP_HIDE_FROM_ABI constexpr __tuple_leaf()
414              _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) {}
416     template <class _Alloc>
417         _LIBCPP_HIDE_FROM_ABI constexpr
418         __tuple_leaf(integral_constant<int, 0>, const _Alloc&) {}
420     template <class _Alloc>
421         _LIBCPP_HIDE_FROM_ABI constexpr
422         __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
423             : _Hp(allocator_arg_t(), __a) {}
425     template <class _Alloc>
426         _LIBCPP_HIDE_FROM_ABI constexpr
427         __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
428             : _Hp(__a) {}
430     template <class _Tp,
431               class = __enable_if_t<
432                   _And<
433                     _IsNotSame<__remove_cvref_t<_Tp>, __tuple_leaf>,
434                     is_constructible<_Hp, _Tp>
435                   >::value
436                 >
437             >
438         _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
439         explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
440             : _Hp(std::forward<_Tp>(__t)) {}
442     template <class _Tp, class _Alloc>
443         _LIBCPP_HIDE_FROM_ABI constexpr
444         explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
445             : _Hp(std::forward<_Tp>(__t)) {}
447     template <class _Tp, class _Alloc>
448         _LIBCPP_HIDE_FROM_ABI constexpr
449         explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
450             : _Hp(allocator_arg_t(), __a, std::forward<_Tp>(__t)) {}
452     template <class _Tp, class _Alloc>
453         _LIBCPP_HIDE_FROM_ABI constexpr
454         explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
455             : _Hp(std::forward<_Tp>(__t), __a) {}
457     __tuple_leaf(__tuple_leaf const &) = default;
458     __tuple_leaf(__tuple_leaf &&) = default;
460     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
461     int
462     swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
463     {
464         std::swap(*this, __t);
465         return 0;
466     }
468     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
469     int swap(const __tuple_leaf& __rhs) const _NOEXCEPT_(__is_nothrow_swappable<const __tuple_leaf>::value) {
470         std::swap(*this, __rhs);
471         return 0;
472     }
474     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14       _Hp& get()       _NOEXCEPT {return static_cast<_Hp&>(*this);}
475     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 const _Hp& get() const _NOEXCEPT {return static_cast<const _Hp&>(*this);}
478 template <class ..._Tp>
479 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
480 void __swallow(_Tp&&...) _NOEXCEPT {}
482 template <class _Tp>
483 struct __all_default_constructible;
485 template <class ..._Tp>
486 struct __all_default_constructible<__tuple_types<_Tp...>>
487     : __all<is_default_constructible<_Tp>::value...>
488 { };
490 // __tuple_impl
492 template<class _Indx, class ..._Tp> struct __tuple_impl;
494 template<size_t ..._Indx, class ..._Tp>
495 struct _LIBCPP_DECLSPEC_EMPTY_BASES __tuple_impl<__tuple_indices<_Indx...>, _Tp...>
496     : public __tuple_leaf<_Indx, _Tp>...
498     _LIBCPP_HIDE_FROM_ABI
499     constexpr __tuple_impl()
500         _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
502     template <size_t ..._Uf, class ..._Tf,
503               size_t ..._Ul, class ..._Tl, class ..._Up>
504         _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
505         explicit
506         __tuple_impl(__tuple_indices<_Uf...>, __tuple_types<_Tf...>,
507                      __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
508                      _Up&&... __u)
509                      _NOEXCEPT_((__all<is_nothrow_constructible<_Tf, _Up>::value...>::value &&
510                                  __all<is_nothrow_default_constructible<_Tl>::value...>::value)) :
511             __tuple_leaf<_Uf, _Tf>(std::forward<_Up>(__u))...,
512             __tuple_leaf<_Ul, _Tl>()...
513             {}
515     template <class _Alloc, size_t ..._Uf, class ..._Tf,
516               size_t ..._Ul, class ..._Tl, class ..._Up>
517         _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
518         explicit
519         __tuple_impl(allocator_arg_t, const _Alloc& __a,
520                      __tuple_indices<_Uf...>, __tuple_types<_Tf...>,
521                      __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
522                      _Up&&... __u) :
523             __tuple_leaf<_Uf, _Tf>(__uses_alloc_ctor<_Tf, _Alloc, _Up>(), __a,
524             std::forward<_Up>(__u))...,
525             __tuple_leaf<_Ul, _Tl>(__uses_alloc_ctor<_Tl, _Alloc>(), __a)...
526             {}
528     template <class _Tuple,
529               class = __enable_if_t<__tuple_constructible<_Tuple, tuple<_Tp...> >::value>
530              >
531         _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
532         __tuple_impl(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_constructible<_Tp, typename tuple_element<_Indx,
533                                        typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))
534             : __tuple_leaf<_Indx, _Tp>(std::forward<typename tuple_element<_Indx,
535                                        typename __make_tuple_types<_Tuple>::type>::type>(std::get<_Indx>(__t)))...
536             {}
538     template <class _Alloc, class _Tuple,
539               class = __enable_if_t<__tuple_constructible<_Tuple, tuple<_Tp...> >::value>
540              >
541         _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
542         __tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
543             : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, typename tuple_element<_Indx,
544                                        typename __make_tuple_types<_Tuple>::type>::type>(), __a,
545                                        std::forward<typename tuple_element<_Indx,
546                                        typename __make_tuple_types<_Tuple>::type>::type>(std::get<_Indx>(__t)))...
547             {}
549     __tuple_impl(const __tuple_impl&) = default;
550     __tuple_impl(__tuple_impl&&) = default;
552     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
553     void swap(__tuple_impl& __t)
554         _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
555     {
556         std::__swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...);
557     }
559     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
560     void swap(const __tuple_impl& __t) const
561         _NOEXCEPT_(__all<__is_nothrow_swappable<const _Tp>::value...>::value)
562     {
563         std::__swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<const __tuple_leaf<_Indx, _Tp>&>(__t))...);
564     }
567 template<class _Dest, class _Source, size_t ..._Np>
568 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
569 void __memberwise_copy_assign(_Dest& __dest, _Source const& __source, __tuple_indices<_Np...>) {
570     std::__swallow(((std::get<_Np>(__dest) = std::get<_Np>(__source)), void(), 0)...);
573 template<class _Dest, class _Source, class ..._Up, size_t ..._Np>
574 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
575 void __memberwise_forward_assign(_Dest& __dest, _Source&& __source, __tuple_types<_Up...>, __tuple_indices<_Np...>) {
576     std::__swallow(((
577         std::get<_Np>(__dest) = std::forward<_Up>(std::get<_Np>(__source))
578     ), void(), 0)...);
581 template <class ..._Tp>
582 class _LIBCPP_TEMPLATE_VIS tuple
584     typedef __tuple_impl<typename __make_tuple_indices<sizeof...(_Tp)>::type, _Tp...> _BaseT;
586     _BaseT __base_;
588     template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_SINCE_CXX14
589         typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT;
590     template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_SINCE_CXX14
591         const typename tuple_element<_Jp, tuple<_Up...> >::type& get(const tuple<_Up...>&) _NOEXCEPT;
592     template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_SINCE_CXX14
593         typename tuple_element<_Jp, tuple<_Up...> >::type&& get(tuple<_Up...>&&) _NOEXCEPT;
594     template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_SINCE_CXX14
595         const typename tuple_element<_Jp, tuple<_Up...> >::type&& get(const tuple<_Up...>&&) _NOEXCEPT;
596 public:
597     // [tuple.cnstr]
599 _LIBCPP_DIAGNOSTIC_PUSH
600 _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wc++20-extensions")
601 _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wc++20-extensions")
603     // tuple() constructors (including allocator_arg_t variants)
604     template <template<class...> class _IsImpDefault = __is_implicitly_default_constructible,
605               template<class...> class _IsDefault = is_default_constructible, __enable_if_t<
606         _And<
607             _IsDefault<_Tp>...
608         >::value
609     , int> = 0>
610     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR
611     explicit(_Not<_Lazy<_And, _IsImpDefault<_Tp>...> >::value) tuple()
612         _NOEXCEPT_(_And<is_nothrow_default_constructible<_Tp>...>::value)
613     { }
615     template <class _Alloc,
616               template<class...> class _IsImpDefault = __is_implicitly_default_constructible,
617               template<class...> class _IsDefault = is_default_constructible, __enable_if_t<
618         _And<
619             _IsDefault<_Tp>...
620         >::value
621     , int> = 0>
622     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
623     explicit(_Not<_Lazy<_And, _IsImpDefault<_Tp>...> >::value) tuple(allocator_arg_t, _Alloc const& __a)
624       : __base_(allocator_arg_t(), __a,
625                     __tuple_indices<>(), __tuple_types<>(),
626                     typename __make_tuple_indices<sizeof...(_Tp), 0>::type(),
627                     __tuple_types<_Tp...>()) {}
629     // tuple(const T&...) constructors (including allocator_arg_t variants)
630     template <template<class...> class _And = _And, __enable_if_t<
631         _And<
632             _BoolConstant<sizeof...(_Tp) >= 1>,
633             is_copy_constructible<_Tp>...
634         >::value
635     , int> = 0>
636     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
637     explicit(_Not<_Lazy<_And, is_convertible<const _Tp&, _Tp>...> >::value) tuple(const _Tp& ... __t)
638         _NOEXCEPT_(_And<is_nothrow_copy_constructible<_Tp>...>::value)
639         : __base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
640                 typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
641                 typename __make_tuple_indices<0>::type(),
642                 typename __make_tuple_types<tuple, 0>::type(),
643                 __t...
644                ) {}
646     template <class _Alloc, template<class...> class _And = _And, __enable_if_t<
647         _And<
648             _BoolConstant<sizeof...(_Tp) >= 1>,
649             is_copy_constructible<_Tp>...
650         >::value
651     , int> = 0>
652     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
653     explicit(_Not<_Lazy<_And, is_convertible<const _Tp&, _Tp>...> >::value) tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
654         : __base_(allocator_arg_t(), __a,
655                 typename __make_tuple_indices<sizeof...(_Tp)>::type(),
656                 typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
657                 typename __make_tuple_indices<0>::type(),
658                 typename __make_tuple_types<tuple, 0>::type(),
659                 __t...
660                ) {}
662     // tuple(U&& ...) constructors (including allocator_arg_t variants)
663     template <class ..._Up> struct _IsThisTuple : false_type { };
664     template <class _Up> struct _IsThisTuple<_Up> : is_same<__remove_cvref_t<_Up>, tuple> { };
666     template <class ..._Up>
667     struct _EnableUTypesCtor : _And<
668         _BoolConstant<sizeof...(_Tp) >= 1>,
669         _Not<_IsThisTuple<_Up...> >, // extension to allow mis-behaved user constructors
670         is_constructible<_Tp, _Up>...
671     > { };
673     template <class ..._Up, __enable_if_t<
674         _And<
675             _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
676             _EnableUTypesCtor<_Up...>
677         >::value
678     , int> = 0>
679     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
680     explicit(_Not<_Lazy<_And, is_convertible<_Up, _Tp>...> >::value) tuple(_Up&&... __u)
681         _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
682         : __base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
683                     typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
684                     typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
685                     typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
686                     std::forward<_Up>(__u)...) {}
688     template <class _Alloc, class ..._Up, __enable_if_t<
689         _And<
690             _BoolConstant<sizeof...(_Up) == sizeof...(_Tp)>,
691             _EnableUTypesCtor<_Up...>
692         >::value
693     , int> = 0>
694     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
695     explicit(_Not<_Lazy<_And, is_convertible<_Up, _Tp>...> >::value) tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
696         : __base_(allocator_arg_t(), __a,
697                     typename __make_tuple_indices<sizeof...(_Up)>::type(),
698                     typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
699                     typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
700                     typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
701                     std::forward<_Up>(__u)...) {}
703     // Copy and move constructors (including the allocator_arg_t variants)
704     tuple(const tuple&) = default;
705     tuple(tuple&&) = default;
707     template <class _Alloc, template<class...> class _And = _And, __enable_if_t<
708         _And<is_copy_constructible<_Tp>...>::value
709     , int> = 0>
710     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
711     tuple(allocator_arg_t, const _Alloc& __alloc, const tuple& __t)
712         : __base_(allocator_arg_t(), __alloc, __t)
713     { }
715     template <class _Alloc, template<class...> class _And = _And, __enable_if_t<
716         _And<is_move_constructible<_Tp>...>::value
717     , int> = 0>
718     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
719     tuple(allocator_arg_t, const _Alloc& __alloc, tuple&& __t)
720         : __base_(allocator_arg_t(), __alloc, std::move(__t))
721     { }
723     // tuple(const tuple<U...>&) constructors (including allocator_arg_t variants)
725     template <class _OtherTuple, class _DecayedOtherTuple = __remove_cvref_t<_OtherTuple>, class = void>
726     struct _EnableCtorFromUTypesTuple : false_type {};
728     template <class _OtherTuple, class... _Up>
729     struct _EnableCtorFromUTypesTuple<_OtherTuple, tuple<_Up...>,
730               // the length of the packs needs to checked first otherwise the 2 packs cannot be expanded simultaneously below
731                __enable_if_t<sizeof...(_Up) == sizeof...(_Tp)>> : _And<
732         // the two conditions below are not in spec. The purpose is to disable the UTypes Ctor when copy/move Ctor can work.
733         // Otherwise, is_constructible can trigger hard error in those cases https://godbolt.org/z/M94cGdKcE
734         _Not<is_same<_OtherTuple, const tuple&> >,
735         _Not<is_same<_OtherTuple, tuple&&> >,
736         is_constructible<_Tp, __copy_cvref_t<_OtherTuple, _Up> >...,
737         _Lazy<_Or, _BoolConstant<sizeof...(_Tp) != 1>,
738             // _Tp and _Up are 1-element packs - the pack expansions look
739             // weird to avoid tripping up the type traits in degenerate cases
740             _Lazy<_And,
741                 _Not<is_same<_Tp, _Up> >...,
742                 _Not<is_convertible<_OtherTuple, _Tp> >...,
743                 _Not<is_constructible<_Tp, _OtherTuple> >...
744             >
745         >
746     > {};
748     template <class ..._Up, __enable_if_t<
749         _And<
750             _EnableCtorFromUTypesTuple<const tuple<_Up...>&>
751         >::value
752     , int> = 0>
753     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
754     explicit(_Not<_Lazy<_And, is_convertible<const _Up&, _Tp>...> >::value) tuple(const tuple<_Up...>& __t)
755         _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, const _Up&>...>::value))
756         : __base_(__t)
757     { }
759     template <class ..._Up, class _Alloc, __enable_if_t<
760         _And<
761             _EnableCtorFromUTypesTuple<const tuple<_Up...>&>
762         >::value
763     , int> = 0>
764     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
765     explicit(_Not<_Lazy<_And, is_convertible<const _Up&, _Tp>...> >::value) tuple(allocator_arg_t, const _Alloc& __a, const tuple<_Up...>& __t)
766         : __base_(allocator_arg_t(), __a, __t)
767     { }
769 #if _LIBCPP_STD_VER >= 23
770     // tuple(tuple<U...>&) constructors (including allocator_arg_t variants)
772     template <class... _Up, enable_if_t<
773         _EnableCtorFromUTypesTuple<tuple<_Up...>&>::value>* = nullptr>
774     _LIBCPP_HIDE_FROM_ABI constexpr
775         explicit(!_Lazy<_And, is_convertible<_Up&, _Tp>...>::value)
776     tuple(tuple<_Up...>& __t) : __base_(__t) {}
778     template <class _Alloc, class... _Up, enable_if_t<
779         _EnableCtorFromUTypesTuple<tuple<_Up...>&>::value>* = nullptr>
780     _LIBCPP_HIDE_FROM_ABI constexpr
781         explicit(!_Lazy<_And, is_convertible<_Up&, _Tp>...>::value)
782     tuple(allocator_arg_t, const _Alloc& __alloc, tuple<_Up...>& __t) : __base_(allocator_arg_t(), __alloc, __t) {}
783 #endif // _LIBCPP_STD_VER >= 23
785     // tuple(tuple<U...>&&) constructors (including allocator_arg_t variants)
786     template <class ..._Up, __enable_if_t<
787         _And<
788             _EnableCtorFromUTypesTuple<tuple<_Up...>&&>
789         >::value
790     , int> = 0>
791     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
792     explicit(_Not<_Lazy<_And, is_convertible<_Up, _Tp>...> >::value) tuple(tuple<_Up...>&& __t)
793         _NOEXCEPT_((_And<is_nothrow_constructible<_Tp, _Up>...>::value))
794         : __base_(std::move(__t))
795     { }
797     template <class _Alloc, class ..._Up, __enable_if_t<
798         _And<
799             _EnableCtorFromUTypesTuple<tuple<_Up...>&&>
800         >::value
801     , int> = 0>
802     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
803     explicit(_Not<_Lazy<_And, is_convertible<_Up, _Tp>...> >::value) tuple(allocator_arg_t, const _Alloc& __a, tuple<_Up...>&& __t)
804         : __base_(allocator_arg_t(), __a, std::move(__t))
805     { }
807 #if _LIBCPP_STD_VER >= 23
808     // tuple(const tuple<U...>&&) constructors (including allocator_arg_t variants)
810     template <class... _Up, enable_if_t<
811         _EnableCtorFromUTypesTuple<const tuple<_Up...>&&>::value>* = nullptr>
812     _LIBCPP_HIDE_FROM_ABI constexpr
813         explicit(!_Lazy<_And, is_convertible<const _Up&&, _Tp>...>::value)
814     tuple(const tuple<_Up...>&& __t) : __base_(std::move(__t)) {}
816     template <class _Alloc, class... _Up, enable_if_t<
817         _EnableCtorFromUTypesTuple<const tuple<_Up...>&&>::value>* = nullptr>
818     _LIBCPP_HIDE_FROM_ABI constexpr
819         explicit(!_Lazy<_And, is_convertible<const _Up&&, _Tp>...>::value)
820     tuple(allocator_arg_t, const _Alloc& __alloc, const tuple<_Up...>&& __t)
821         : __base_(allocator_arg_t(), __alloc, std::move(__t)) {}
822 #endif // _LIBCPP_STD_VER >= 23
824     // tuple(const pair<U1, U2>&) constructors (including allocator_arg_t variants)
826     template <template <class...> class _Pred, class _Pair, class _DecayedPair = __remove_cvref_t<_Pair>, class _Tuple = tuple>
827     struct _CtorPredicateFromPair : false_type{};
829     template <template <class...> class _Pred, class _Pair, class _Up1, class _Up2, class _Tp1, class _Tp2>
830     struct _CtorPredicateFromPair<_Pred, _Pair, pair<_Up1, _Up2>, tuple<_Tp1, _Tp2> > : _And<
831         _Pred<_Tp1, __copy_cvref_t<_Pair, _Up1> >,
832         _Pred<_Tp2, __copy_cvref_t<_Pair, _Up2> >
833     > {};
835     template <class _Pair>
836     struct _EnableCtorFromPair : _CtorPredicateFromPair<is_constructible, _Pair>{};
838     template <class _Pair>
839     struct _NothrowConstructibleFromPair : _CtorPredicateFromPair<is_nothrow_constructible, _Pair>{};
841     template <class _Pair, class _DecayedPair = __remove_cvref_t<_Pair>, class _Tuple = tuple>
842     struct _BothImplicitlyConvertible : false_type{};
844     template <class _Pair, class _Up1, class _Up2, class _Tp1, class _Tp2>
845     struct _BothImplicitlyConvertible<_Pair, pair<_Up1, _Up2>, tuple<_Tp1, _Tp2> > : _And<
846         is_convertible<__copy_cvref_t<_Pair, _Up1>, _Tp1>,
847         is_convertible<__copy_cvref_t<_Pair, _Up2>, _Tp2>
848     > {};
850     template <class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
851         _And<
852             _EnableCtorFromPair<const pair<_Up1, _Up2>&>
853         >::value
854     , int> = 0>
855     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
856     explicit(_Not<_BothImplicitlyConvertible<const pair<_Up1, _Up2>&> >::value) tuple(const pair<_Up1, _Up2>& __p)
857         _NOEXCEPT_((_NothrowConstructibleFromPair<const pair<_Up1, _Up2>&>::value))
858         : __base_(__p)
859     { }
861     template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
862         _And<
863             _EnableCtorFromPair<const pair<_Up1, _Up2>&>
864         >::value
865     , int> = 0>
866     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
867     explicit(_Not<_BothImplicitlyConvertible<const pair<_Up1, _Up2>&> >::value) tuple(allocator_arg_t, const _Alloc& __a, const pair<_Up1, _Up2>& __p)
868         : __base_(allocator_arg_t(), __a, __p)
869     { }
871 #if _LIBCPP_STD_VER >= 23
872     // tuple(pair<U1, U2>&) constructors (including allocator_arg_t variants)
874     template <class _U1, class _U2, enable_if_t<
875         _EnableCtorFromPair<pair<_U1, _U2>&>::value>* = nullptr>
876     _LIBCPP_HIDE_FROM_ABI constexpr
877         explicit(!_BothImplicitlyConvertible<pair<_U1, _U2>&>::value)
878     tuple(pair<_U1, _U2>& __p) : __base_(__p) {}
880     template <class _Alloc, class _U1, class _U2, enable_if_t<
881         _EnableCtorFromPair<std::pair<_U1, _U2>&>::value>* = nullptr>
882     _LIBCPP_HIDE_FROM_ABI constexpr
883         explicit(!_BothImplicitlyConvertible<pair<_U1, _U2>&>::value)
884     tuple(allocator_arg_t, const _Alloc& __alloc, pair<_U1, _U2>& __p) : __base_(allocator_arg_t(), __alloc, __p) {}
885 #endif
887     // tuple(pair<U1, U2>&&) constructors (including allocator_arg_t variants)
889     template <class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
890         _And<
891             _EnableCtorFromPair<pair<_Up1, _Up2>&&>
892         >::value
893     , int> = 0>
894     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
895     explicit(_Not<_BothImplicitlyConvertible<pair<_Up1, _Up2>&&> >::value) tuple(pair<_Up1, _Up2>&& __p)
896         _NOEXCEPT_((_NothrowConstructibleFromPair<pair<_Up1, _Up2>&&>::value))
897         : __base_(std::move(__p))
898     { }
900     template <class _Alloc, class _Up1, class _Up2, template<class...> class _And = _And, __enable_if_t<
901         _And<
902             _EnableCtorFromPair<pair<_Up1, _Up2>&&>
903         >::value
904     , int> = 0>
905     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
906     explicit(_Not<_BothImplicitlyConvertible<pair<_Up1, _Up2>&&> >::value) tuple(allocator_arg_t, const _Alloc& __a, pair<_Up1, _Up2>&& __p)
907         : __base_(allocator_arg_t(), __a, std::move(__p))
908     { }
910 #if _LIBCPP_STD_VER >= 23
911     // tuple(const pair<U1, U2>&&) constructors (including allocator_arg_t variants)
913     template <class _U1, class _U2, enable_if_t<
914         _EnableCtorFromPair<const pair<_U1, _U2>&&>::value>* = nullptr>
915     _LIBCPP_HIDE_FROM_ABI constexpr
916         explicit(!_BothImplicitlyConvertible<const pair<_U1, _U2>&&>::value)
917     tuple(const pair<_U1, _U2>&& __p) : __base_(std::move(__p)) {}
919     template <class _Alloc, class _U1, class _U2, enable_if_t<
920         _EnableCtorFromPair<const pair<_U1, _U2>&&>::value>* = nullptr>
921     _LIBCPP_HIDE_FROM_ABI constexpr
922         explicit(!_BothImplicitlyConvertible<const pair<_U1, _U2>&&>::value)
923     tuple(allocator_arg_t, const _Alloc& __alloc, const pair<_U1, _U2>&& __p)
924         : __base_(allocator_arg_t(), __alloc, std::move(__p)) {}
925 #endif // _LIBCPP_STD_VER >= 23
927 _LIBCPP_DIAGNOSTIC_POP
929     // [tuple.assign]
930     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
931     tuple& operator=(_If<_And<is_copy_assignable<_Tp>...>::value, tuple, __nat> const& __tuple)
932         _NOEXCEPT_((_And<is_nothrow_copy_assignable<_Tp>...>::value))
933     {
934         std::__memberwise_copy_assign(*this, __tuple,
935             typename __make_tuple_indices<sizeof...(_Tp)>::type());
936         return *this;
937     }
939 #if _LIBCPP_STD_VER >= 23
940     _LIBCPP_HIDE_FROM_ABI constexpr
941     const tuple& operator=(tuple const& __tuple) const
942       requires (_And<is_copy_assignable<const _Tp>...>::value) {
943         std::__memberwise_copy_assign(*this, __tuple, typename __make_tuple_indices<sizeof...(_Tp)>::type());
944         return *this;
945     }
947     _LIBCPP_HIDE_FROM_ABI constexpr
948     const tuple& operator=(tuple&& __tuple) const
949       requires (_And<is_assignable<const _Tp&, _Tp>...>::value) {
950         std::__memberwise_forward_assign(*this,
951                                          std::move(__tuple),
952                                          __tuple_types<_Tp...>(),
953                                          typename __make_tuple_indices<sizeof...(_Tp)>::type());
954         return *this;
955     }
956 #endif // _LIBCPP_STD_VER >= 23
958     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
959     tuple& operator=(_If<_And<is_move_assignable<_Tp>...>::value, tuple, __nat>&& __tuple)
960         _NOEXCEPT_((_And<is_nothrow_move_assignable<_Tp>...>::value))
961     {
962         std::__memberwise_forward_assign(*this, std::move(__tuple),
963             __tuple_types<_Tp...>(),
964             typename __make_tuple_indices<sizeof...(_Tp)>::type());
965         return *this;
966     }
968     template<class... _Up, __enable_if_t<
969         _And<
970             _BoolConstant<sizeof...(_Tp) == sizeof...(_Up)>,
971             is_assignable<_Tp&, _Up const&>...
972         >::value
973     ,int> = 0>
974     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
975     tuple& operator=(tuple<_Up...> const& __tuple)
976         _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value))
977     {
978         std::__memberwise_copy_assign(*this, __tuple,
979             typename __make_tuple_indices<sizeof...(_Tp)>::type());
980         return *this;
981     }
983     template<class... _Up, __enable_if_t<
984         _And<
985             _BoolConstant<sizeof...(_Tp) == sizeof...(_Up)>,
986             is_assignable<_Tp&, _Up>...
987         >::value
988     ,int> = 0>
989     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
990     tuple& operator=(tuple<_Up...>&& __tuple)
991         _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up>...>::value))
992     {
993         std::__memberwise_forward_assign(*this, std::move(__tuple),
994             __tuple_types<_Up...>(),
995             typename __make_tuple_indices<sizeof...(_Tp)>::type());
996         return *this;
997     }
1000 #if _LIBCPP_STD_VER >= 23
1001     template <class... _UTypes, enable_if_t<
1002         _And<_BoolConstant<sizeof...(_Tp) == sizeof...(_UTypes)>,
1003              is_assignable<const _Tp&, const _UTypes&>...>::value>* = nullptr>
1004     _LIBCPP_HIDE_FROM_ABI constexpr
1005     const tuple& operator=(const tuple<_UTypes...>& __u) const {
1006         std::__memberwise_copy_assign(*this,
1007                                       __u,
1008                                       typename __make_tuple_indices<sizeof...(_Tp)>::type());
1009         return *this;
1010     }
1012     template <class... _UTypes, enable_if_t<
1013         _And<_BoolConstant<sizeof...(_Tp) == sizeof...(_UTypes)>,
1014              is_assignable<const _Tp&, _UTypes>...>::value>* = nullptr>
1015     _LIBCPP_HIDE_FROM_ABI constexpr
1016     const tuple& operator=(tuple<_UTypes...>&& __u) const {
1017         std::__memberwise_forward_assign(*this,
1018                                          __u,
1019                                          __tuple_types<_UTypes...>(),
1020                                          typename __make_tuple_indices<sizeof...(_Tp)>::type());
1021         return *this;
1022     }
1023 #endif // _LIBCPP_STD_VER >= 23
1025     template <template<class...> class _Pred, bool _Const,
1026               class _Pair, class _DecayedPair = __remove_cvref_t<_Pair>, class _Tuple = tuple>
1027     struct _AssignPredicateFromPair : false_type {};
1029     template <template<class...> class _Pred, bool _Const,
1030               class _Pair, class _Up1, class _Up2, class _Tp1, class _Tp2>
1031     struct _AssignPredicateFromPair<_Pred, _Const, _Pair, pair<_Up1, _Up2>, tuple<_Tp1, _Tp2> > :
1032         _And<_Pred<__maybe_const<_Const, _Tp1>&, __copy_cvref_t<_Pair, _Up1> >,
1033              _Pred<__maybe_const<_Const, _Tp2>&, __copy_cvref_t<_Pair, _Up2> >
1034             > {};
1036     template <bool _Const, class _Pair>
1037     struct _EnableAssignFromPair : _AssignPredicateFromPair<is_assignable, _Const, _Pair> {};
1039     template <bool _Const, class _Pair>
1040     struct _NothrowAssignFromPair : _AssignPredicateFromPair<is_nothrow_assignable, _Const, _Pair> {};
1042 #if _LIBCPP_STD_VER >= 23
1043     template <class _U1, class _U2, enable_if_t<
1044         _EnableAssignFromPair<true, const pair<_U1, _U2>&>::value>* = nullptr>
1045     _LIBCPP_HIDE_FROM_ABI constexpr
1046     const tuple& operator=(const pair<_U1, _U2>& __pair) const
1047       noexcept(_NothrowAssignFromPair<true, const pair<_U1, _U2>&>::value) {
1048         std::get<0>(*this) = __pair.first;
1049         std::get<1>(*this) = __pair.second;
1050         return *this;
1051     }
1053     template <class _U1, class _U2, enable_if_t<
1054         _EnableAssignFromPair<true, pair<_U1, _U2>&&>::value>* = nullptr>
1055     _LIBCPP_HIDE_FROM_ABI constexpr
1056     const tuple& operator=(pair<_U1, _U2>&& __pair) const
1057       noexcept(_NothrowAssignFromPair<true, pair<_U1, _U2>&&>::value) {
1058         std::get<0>(*this) = std::move(__pair.first);
1059         std::get<1>(*this) = std::move(__pair.second);
1060         return *this;
1061     }
1062 #endif // _LIBCPP_STD_VER >= 23
1064     template<class _Up1, class _Up2, __enable_if_t<
1065         _EnableAssignFromPair<false, pair<_Up1, _Up2> const&>::value
1066     ,int> = 0>
1067     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1068     tuple& operator=(pair<_Up1, _Up2> const& __pair)
1069         _NOEXCEPT_((_NothrowAssignFromPair<false, pair<_Up1, _Up2> const&>::value))
1070     {
1071         std::get<0>(*this) = __pair.first;
1072         std::get<1>(*this) = __pair.second;
1073         return *this;
1074     }
1076     template<class _Up1, class _Up2, __enable_if_t<
1077         _EnableAssignFromPair<false, pair<_Up1, _Up2>&&>::value
1078     ,int> = 0>
1079     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1080     tuple& operator=(pair<_Up1, _Up2>&& __pair)
1081         _NOEXCEPT_((_NothrowAssignFromPair<false, pair<_Up1, _Up2>&&>::value))
1082     {
1083         std::get<0>(*this) = std::forward<_Up1>(__pair.first);
1084         std::get<1>(*this) = std::forward<_Up2>(__pair.second);
1085         return *this;
1086     }
1088     // EXTENSION
1089     template<class _Up, size_t _Np, class = __enable_if_t<
1090         _And<
1091             _BoolConstant<_Np == sizeof...(_Tp)>,
1092             is_assignable<_Tp&, _Up const&>...
1093         >::value
1094     > >
1095     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1096     tuple& operator=(array<_Up, _Np> const& __array)
1097         _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up const&>...>::value))
1098     {
1099         std::__memberwise_copy_assign(*this, __array,
1100             typename __make_tuple_indices<sizeof...(_Tp)>::type());
1101         return *this;
1102     }
1104     // EXTENSION
1105     template<class _Up, size_t _Np, class = void, class = __enable_if_t<
1106         _And<
1107             _BoolConstant<_Np == sizeof...(_Tp)>,
1108             is_assignable<_Tp&, _Up>...
1109         >::value
1110     > >
1111     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1112     tuple& operator=(array<_Up, _Np>&& __array)
1113         _NOEXCEPT_((_And<is_nothrow_assignable<_Tp&, _Up>...>::value))
1114     {
1115         std::__memberwise_forward_assign(*this, std::move(__array),
1116             __tuple_types<_If<true, _Up, _Tp>...>(),
1117             typename __make_tuple_indices<sizeof...(_Tp)>::type());
1118         return *this;
1119     }
1121     // [tuple.swap]
1122     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1123     void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
1124         {__base_.swap(__t.__base_);}
1126 #if _LIBCPP_STD_VER >= 23
1127     _LIBCPP_HIDE_FROM_ABI constexpr
1128     void swap(const tuple& __t) const noexcept(__all<is_nothrow_swappable_v<const _Tp&>...>::value) {
1129         __base_.swap(__t.__base_);
1130     }
1131 #endif // _LIBCPP_STD_VER >= 23
1134 template <>
1135 class _LIBCPP_TEMPLATE_VIS tuple<>
1137 public:
1138     constexpr tuple() _NOEXCEPT = default;
1139     template <class _Alloc>
1140     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1141         tuple(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
1142     template <class _Alloc>
1143     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1144         tuple(allocator_arg_t, const _Alloc&, const tuple&) _NOEXCEPT {}
1145     template <class _Up>
1146     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1147         tuple(array<_Up, 0>) _NOEXCEPT {}
1148     template <class _Alloc, class _Up>
1149     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1150         tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) _NOEXCEPT {}
1151     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1152     void swap(tuple&) _NOEXCEPT {}
1153 #if _LIBCPP_STD_VER >= 23
1154     _LIBCPP_HIDE_FROM_ABI constexpr void swap(const tuple&) const noexcept {}
1155 #endif
1158 #if _LIBCPP_STD_VER >= 23
1159 template <class... _TTypes, class... _UTypes, template<class> class _TQual, template<class> class _UQual>
1160     requires requires { typename tuple<common_reference_t<_TQual<_TTypes>, _UQual<_UTypes>>...>; }
1161 struct basic_common_reference<tuple<_TTypes...>, tuple<_UTypes...>, _TQual, _UQual> {
1162     using type = tuple<common_reference_t<_TQual<_TTypes>, _UQual<_UTypes>>...>;
1165 template <class... _TTypes, class... _UTypes>
1166     requires requires { typename tuple<common_type_t<_TTypes, _UTypes>...>; }
1167 struct common_type<tuple<_TTypes...>, tuple<_UTypes...>> {
1168     using type = tuple<common_type_t<_TTypes, _UTypes>...>;
1170 #endif // _LIBCPP_STD_VER >= 23
1172 #if _LIBCPP_STD_VER >= 17
1173 template <class ..._Tp>
1174 tuple(_Tp...) -> tuple<_Tp...>;
1175 template <class _Tp1, class _Tp2>
1176 tuple(pair<_Tp1, _Tp2>) -> tuple<_Tp1, _Tp2>;
1177 template <class _Alloc, class ..._Tp>
1178 tuple(allocator_arg_t, _Alloc, _Tp...) -> tuple<_Tp...>;
1179 template <class _Alloc, class _Tp1, class _Tp2>
1180 tuple(allocator_arg_t, _Alloc, pair<_Tp1, _Tp2>) -> tuple<_Tp1, _Tp2>;
1181 template <class _Alloc, class ..._Tp>
1182 tuple(allocator_arg_t, _Alloc, tuple<_Tp...>) -> tuple<_Tp...>;
1183 #endif
1185 template <class ..._Tp, __enable_if_t<__all<__is_swappable<_Tp>::value...>::value, int> = 0>
1186 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1187 void
1188 swap(tuple<_Tp...>& __t, tuple<_Tp...>& __u)
1189                  _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
1190     {__t.swap(__u);}
1192 #if _LIBCPP_STD_VER >= 23
1193 template <class... _Tp>
1194 _LIBCPP_HIDE_FROM_ABI constexpr
1195 enable_if_t<__all<is_swappable_v<const _Tp>...>::value, void>
1196 swap(const tuple<_Tp...>& __lhs, const tuple<_Tp...>& __rhs)
1197         noexcept(__all<is_nothrow_swappable_v<const _Tp>...>::value) {
1198     __lhs.swap(__rhs);
1200 #endif
1202 // get
1204 template <size_t _Ip, class ..._Tp>
1205 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
1206 typename tuple_element<_Ip, tuple<_Tp...> >::type&
1207 get(tuple<_Tp...>& __t) _NOEXCEPT
1209     typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type;
1210     return static_cast<__tuple_leaf<_Ip, type>&>(__t.__base_).get();
1213 template <size_t _Ip, class ..._Tp>
1214 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
1215 const typename tuple_element<_Ip, tuple<_Tp...> >::type&
1216 get(const tuple<_Tp...>& __t) _NOEXCEPT
1218     typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type;
1219     return static_cast<const __tuple_leaf<_Ip, type>&>(__t.__base_).get();
1222 template <size_t _Ip, class ..._Tp>
1223 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
1224 typename tuple_element<_Ip, tuple<_Tp...> >::type&&
1225 get(tuple<_Tp...>&& __t) _NOEXCEPT
1227     typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type;
1228     return static_cast<type&&>(
1229              static_cast<__tuple_leaf<_Ip, type>&&>(__t.__base_).get());
1232 template <size_t _Ip, class ..._Tp>
1233 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
1234 const typename tuple_element<_Ip, tuple<_Tp...> >::type&&
1235 get(const tuple<_Tp...>&& __t) _NOEXCEPT
1237     typedef _LIBCPP_NODEBUG typename tuple_element<_Ip, tuple<_Tp...> >::type type;
1238     return static_cast<const type&&>(
1239              static_cast<const __tuple_leaf<_Ip, type>&&>(__t.__base_).get());
1242 #if _LIBCPP_STD_VER >= 14
1244 namespace __find_detail {
1246 static constexpr size_t __not_found = static_cast<size_t>(-1);
1247 static constexpr size_t __ambiguous = __not_found - 1;
1249 inline _LIBCPP_HIDE_FROM_ABI
1250 constexpr size_t __find_idx_return(size_t __curr_i, size_t __res, bool __matches) {
1251     return !__matches ? __res :
1252         (__res == __not_found ? __curr_i : __ambiguous);
1255 template <size_t _Nx>
1256 inline _LIBCPP_HIDE_FROM_ABI
1257 constexpr size_t __find_idx(size_t __i, const bool (&__matches)[_Nx]) {
1258   return __i == _Nx ? __not_found :
1259       __find_detail::__find_idx_return(__i, __find_detail::__find_idx(__i + 1, __matches), __matches[__i]);
1262 template <class _T1, class ..._Args>
1263 struct __find_exactly_one_checked {
1264     static constexpr bool __matches[sizeof...(_Args)] = {is_same<_T1, _Args>::value...};
1265     static constexpr size_t value = __find_detail::__find_idx(0, __matches);
1266     static_assert(value != __not_found, "type not found in type list" );
1267     static_assert(value != __ambiguous, "type occurs more than once in type list");
1270 template <class _T1>
1271 struct __find_exactly_one_checked<_T1> {
1272     static_assert(!is_same<_T1, _T1>::value, "type not in empty type list");
1275 } // namespace __find_detail
1277 template <typename _T1, typename... _Args>
1278 struct __find_exactly_one_t
1279     : public __find_detail::__find_exactly_one_checked<_T1, _Args...> {
1282 template <class _T1, class... _Args>
1283 inline _LIBCPP_HIDE_FROM_ABI
1284 constexpr _T1& get(tuple<_Args...>& __tup) noexcept
1286     return std::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
1289 template <class _T1, class... _Args>
1290 inline _LIBCPP_HIDE_FROM_ABI
1291 constexpr _T1 const& get(tuple<_Args...> const& __tup) noexcept
1293     return std::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
1296 template <class _T1, class... _Args>
1297 inline _LIBCPP_HIDE_FROM_ABI
1298 constexpr _T1&& get(tuple<_Args...>&& __tup) noexcept
1300     return std::get<__find_exactly_one_t<_T1, _Args...>::value>(std::move(__tup));
1303 template <class _T1, class... _Args>
1304 inline _LIBCPP_HIDE_FROM_ABI
1305 constexpr _T1 const&& get(tuple<_Args...> const&& __tup) noexcept
1307     return std::get<__find_exactly_one_t<_T1, _Args...>::value>(std::move(__tup));
1310 #endif
1312 // tie
1314 template <class ..._Tp>
1315 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
1316 tuple<_Tp&...>
1317 tie(_Tp&... __t) _NOEXCEPT
1319     return tuple<_Tp&...>(__t...);
1322 template <class _Up>
1323 struct __ignore_t
1325     template <class _Tp>
1326     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
1327     const __ignore_t& operator=(_Tp&&) const {return *this;}
1330 #  if _LIBCPP_STD_VER >= 17
1331 inline constexpr __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>();
1332 #  else
1333 namespace {
1334   constexpr __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>();
1335 } // namespace
1336 #  endif
1338 template <class... _Tp>
1339 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
1340 tuple<typename __unwrap_ref_decay<_Tp>::type...>
1341 make_tuple(_Tp&&... __t)
1343     return tuple<typename __unwrap_ref_decay<_Tp>::type...>(std::forward<_Tp>(__t)...);
1346 template <class... _Tp>
1347 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
1348 tuple<_Tp&&...>
1349 forward_as_tuple(_Tp&&... __t) _NOEXCEPT
1351     return tuple<_Tp&&...>(std::forward<_Tp>(__t)...);
1354 template <size_t _Ip>
1355 struct __tuple_equal
1357     template <class _Tp, class _Up>
1358     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
1359     bool operator()(const _Tp& __x, const _Up& __y)
1360     {
1361         return __tuple_equal<_Ip - 1>()(__x, __y) && std::get<_Ip-1>(__x) == std::get<_Ip-1>(__y);
1362     }
1365 template <>
1366 struct __tuple_equal<0>
1368     template <class _Tp, class _Up>
1369     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
1370     bool operator()(const _Tp&, const _Up&)
1371     {
1372         return true;
1373     }
1376 template <class ..._Tp, class ..._Up>
1377 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
1378 bool
1379 operator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1381     static_assert (sizeof...(_Tp) == sizeof...(_Up), "Can't compare tuples of different sizes");
1382     return __tuple_equal<sizeof...(_Tp)>()(__x, __y);
1385 #if _LIBCPP_STD_VER >= 20
1387 // operator<=>
1389 template <class ..._Tp, class ..._Up, size_t ..._Is>
1390 _LIBCPP_HIDE_FROM_ABI constexpr
1391 auto
1392 __tuple_compare_three_way(const tuple<_Tp...>& __x, const tuple<_Up...>& __y, index_sequence<_Is...>) {
1393     common_comparison_category_t<__synth_three_way_result<_Tp, _Up>...> __result = strong_ordering::equal;
1394     static_cast<void>(((__result = std::__synth_three_way(std::get<_Is>(__x), std::get<_Is>(__y)), __result != 0) || ...));
1395     return __result;
1398 template <class ..._Tp, class ..._Up>
1399 requires (sizeof...(_Tp) == sizeof...(_Up))
1400 _LIBCPP_HIDE_FROM_ABI constexpr
1401 common_comparison_category_t<__synth_three_way_result<_Tp, _Up>...>
1402 operator<=>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1404     return std::__tuple_compare_three_way(__x, __y, index_sequence_for<_Tp...>{});
1407 #else // _LIBCPP_STD_VER >= 20
1409 template <class ..._Tp, class ..._Up>
1410 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
1411 bool
1412 operator!=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1414     return !(__x == __y);
1417 template <size_t _Ip>
1418 struct __tuple_less
1420     template <class _Tp, class _Up>
1421     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
1422     bool operator()(const _Tp& __x, const _Up& __y)
1423     {
1424         const size_t __idx = tuple_size<_Tp>::value - _Ip;
1425         if (std::get<__idx>(__x) < std::get<__idx>(__y))
1426             return true;
1427         if (std::get<__idx>(__y) < std::get<__idx>(__x))
1428             return false;
1429         return __tuple_less<_Ip-1>()(__x, __y);
1430     }
1433 template <>
1434 struct __tuple_less<0>
1436     template <class _Tp, class _Up>
1437     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
1438     bool operator()(const _Tp&, const _Up&)
1439     {
1440         return false;
1441     }
1444 template <class ..._Tp, class ..._Up>
1445 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
1446 bool
1447 operator<(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1449     static_assert (sizeof...(_Tp) == sizeof...(_Up), "Can't compare tuples of different sizes");
1450     return __tuple_less<sizeof...(_Tp)>()(__x, __y);
1453 template <class ..._Tp, class ..._Up>
1454 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
1455 bool
1456 operator>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1458     return __y < __x;
1461 template <class ..._Tp, class ..._Up>
1462 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
1463 bool
1464 operator>=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1466     return !(__x < __y);
1469 template <class ..._Tp, class ..._Up>
1470 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
1471 bool
1472 operator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1474     return !(__y < __x);
1477 #endif // _LIBCPP_STD_VER >= 20
1479 // tuple_cat
1481 template <class _Tp, class _Up> struct __tuple_cat_type;
1483 template <class ..._Ttypes, class ..._Utypes>
1484 struct __tuple_cat_type<tuple<_Ttypes...>, __tuple_types<_Utypes...> >
1486     typedef _LIBCPP_NODEBUG tuple<_Ttypes..., _Utypes...> type;
1489 template <class _ResultTuple, bool _Is_Tuple0TupleLike, class ..._Tuples>
1490 struct __tuple_cat_return_1
1494 template <class ..._Types, class _Tuple0>
1495 struct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0>
1497   using type _LIBCPP_NODEBUG = typename __tuple_cat_type<
1498       tuple<_Types...>,
1499       typename __make_tuple_types<__remove_cvref_t<_Tuple0> >::type
1500     >::type;
1503 template <class ..._Types, class _Tuple0, class _Tuple1, class ..._Tuples>
1504 struct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0, _Tuple1, _Tuples...>
1505     : public __tuple_cat_return_1<
1506                  typename __tuple_cat_type<
1507                      tuple<_Types...>,
1508                      typename __make_tuple_types<__remove_cvref_t<_Tuple0> >::type
1509                  >::type,
1510                  __tuple_like_ext<__libcpp_remove_reference_t<_Tuple1> >::value,
1511                  _Tuple1, _Tuples...>
1515 template <class ..._Tuples> struct __tuple_cat_return;
1517 template <class _Tuple0, class ..._Tuples>
1518 struct __tuple_cat_return<_Tuple0, _Tuples...>
1519     : public __tuple_cat_return_1<tuple<>,
1520          __tuple_like_ext<__libcpp_remove_reference_t<_Tuple0> >::value, _Tuple0,
1521                                                                      _Tuples...>
1525 template <>
1526 struct __tuple_cat_return<>
1528     typedef _LIBCPP_NODEBUG tuple<> type;
1531 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
1532 tuple<>
1533 tuple_cat()
1535     return tuple<>();
1538 template <class _Rp, class _Indices, class _Tuple0, class ..._Tuples>
1539 struct __tuple_cat_return_ref_imp;
1541 template <class ..._Types, size_t ..._I0, class _Tuple0>
1542 struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, _Tuple0>
1544     typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tuple0> _T0;
1545     typedef tuple<_Types..., __apply_cv_t<_Tuple0, typename tuple_element<_I0, _T0>::type>&&...> type;
1548 template <class ..._Types, size_t ..._I0, class _Tuple0, class _Tuple1, class ..._Tuples>
1549 struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>,
1550                                   _Tuple0, _Tuple1, _Tuples...>
1551     : public __tuple_cat_return_ref_imp<
1552          tuple<_Types..., __apply_cv_t<_Tuple0,
1553                                        typename tuple_element<_I0, __libcpp_remove_reference_t<_Tuple0>>::type>&&...>,
1554          typename __make_tuple_indices<tuple_size<__libcpp_remove_reference_t<_Tuple1> >::value>::type,
1555          _Tuple1, _Tuples...>
1559 template <class _Tuple0, class ..._Tuples>
1560 struct __tuple_cat_return_ref
1561     : public __tuple_cat_return_ref_imp<tuple<>,
1562                typename __make_tuple_indices<
1563                         tuple_size<__libcpp_remove_reference_t<_Tuple0> >::value
1564                >::type, _Tuple0, _Tuples...>
1568 template <class _Types, class _I0, class _J0>
1569 struct __tuple_cat;
1571 template <class ..._Types, size_t ..._I0, size_t ..._J0>
1572 struct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J0...> >
1574     template <class _Tuple0>
1575     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
1576     typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&>::type
1577     operator()(tuple<_Types...> __t, _Tuple0&& __t0)
1578     {
1579         (void)__t; // avoid unused parameter warning on GCC when _I0 is empty
1580         return std::forward_as_tuple(
1581             std::forward<_Types>(std::get<_I0>(__t))...,
1582             std::get<_J0>(std::forward<_Tuple0>(__t0))...);
1583     }
1585     template <class _Tuple0, class _Tuple1, class ..._Tuples>
1586     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
1587     typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&, _Tuple1&&, _Tuples&&...>::type
1588     operator()(tuple<_Types...> __t, _Tuple0&& __t0, _Tuple1&& __t1, _Tuples&& ...__tpls)
1589     {
1590         (void)__t; // avoid unused parameter warning on GCC when _I0 is empty
1591         typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tuple0> _T0;
1592         typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tuple1> _T1;
1593         return __tuple_cat<tuple<_Types..., __apply_cv_t<_Tuple0, typename tuple_element<_J0, _T0>::type>&&...>,
1594                            typename __make_tuple_indices<sizeof...(_Types) + tuple_size<_T0>::value>::type,
1595                            typename __make_tuple_indices<tuple_size<_T1>::value>::type>()(
1596             std::forward_as_tuple(
1597                 std::forward<_Types>(std::get<_I0>(__t))...,
1598                 std::get<_J0>(std::forward<_Tuple0>(__t0))...),
1599             std::forward<_Tuple1>(__t1), std::forward<_Tuples>(__tpls)...);
1600     }
1603 template <class _Tuple0, class... _Tuples>
1604 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14
1605 typename __tuple_cat_return<_Tuple0, _Tuples...>::type
1606 tuple_cat(_Tuple0&& __t0, _Tuples&&... __tpls)
1608     typedef _LIBCPP_NODEBUG __libcpp_remove_reference_t<_Tuple0> _T0;
1609     return __tuple_cat<tuple<>, __tuple_indices<>,
1610                   typename __make_tuple_indices<tuple_size<_T0>::value>::type>()
1611                   (tuple<>(), std::forward<_Tuple0>(__t0),
1612                                             std::forward<_Tuples>(__tpls)...);
1615 template <class ..._Tp, class _Alloc>
1616 struct _LIBCPP_TEMPLATE_VIS uses_allocator<tuple<_Tp...>, _Alloc>
1617     : true_type {};
1619 template <class _T1, class _T2>
1620 template <class... _Args1, class... _Args2, size_t ..._I1, size_t ..._I2>
1621 inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20
1622 pair<_T1, _T2>::pair(piecewise_construct_t,
1623                      tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,
1624                      __tuple_indices<_I1...>, __tuple_indices<_I2...>)
1625     :  first(std::forward<_Args1>(std::get<_I1>( __first_args))...),
1626       second(std::forward<_Args2>(std::get<_I2>(__second_args))...)
1630 #if _LIBCPP_STD_VER >= 17
1631 template <class _Tp>
1632 inline constexpr size_t tuple_size_v = tuple_size<_Tp>::value;
1634 #define _LIBCPP_NOEXCEPT_RETURN(...) noexcept(noexcept(__VA_ARGS__)) { return __VA_ARGS__; }
1636 template <class _Fn, class _Tuple, size_t ..._Id>
1637 inline _LIBCPP_HIDE_FROM_ABI
1638 constexpr decltype(auto) __apply_tuple_impl(_Fn && __f, _Tuple && __t,
1639                                             __tuple_indices<_Id...>)
1640 _LIBCPP_NOEXCEPT_RETURN(
1641     std::__invoke(
1642         std::forward<_Fn>(__f),
1643         std::get<_Id>(std::forward<_Tuple>(__t))...)
1646 template <class _Fn, class _Tuple>
1647 inline _LIBCPP_HIDE_FROM_ABI
1648 constexpr decltype(auto) apply(_Fn && __f, _Tuple && __t)
1649 _LIBCPP_NOEXCEPT_RETURN(
1650     std::__apply_tuple_impl(
1651         std::forward<_Fn>(__f), std::forward<_Tuple>(__t),
1652         typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{})
1655 template <class _Tp, class _Tuple, size_t... _Idx>
1656 inline _LIBCPP_HIDE_FROM_ABI
1657 constexpr _Tp __make_from_tuple_impl(_Tuple&& __t, __tuple_indices<_Idx...>)
1658 _LIBCPP_NOEXCEPT_RETURN(
1659     _Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...)
1662 template <class _Tp, class _Tuple>
1663 inline _LIBCPP_HIDE_FROM_ABI
1664 constexpr _Tp make_from_tuple(_Tuple&& __t)
1665 _LIBCPP_NOEXCEPT_RETURN(
1666     std::__make_from_tuple_impl<_Tp>(std::forward<_Tuple>(__t),
1667         typename __make_tuple_indices<tuple_size_v<remove_reference_t<_Tuple>>>::type{})
1670 #undef _LIBCPP_NOEXCEPT_RETURN
1672 #endif // _LIBCPP_STD_VER >= 17
1674 #endif // !defined(_LIBCPP_CXX03_LANG)
1676 _LIBCPP_END_NAMESPACE_STD
1678 _LIBCPP_POP_MACROS
1680 #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
1681 #  include <exception>
1682 #  include <iosfwd>
1683 #  include <new>
1684 #  include <type_traits>
1685 #  include <typeinfo>
1686 #  include <utility>
1687 #endif
1689 #endif // _LIBCPP_TUPLE