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