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