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