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