xref: /llvm-project-15.0.7/libcxx/include/tuple (revision 498ee00a)
1// -*- C++ -*-
2//===--------------------------- tuple ------------------------------------===//
3//
4//                     The LLVM Compiler Infrastructure
5//
6// This file is distributed under the University of Illinois Open Source
7// License. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_TUPLE
12#define _LIBCPP_TUPLE
13
14/*
15    tuple synopsis
16
17namespace std
18{
19
20template <class... T>
21class tuple {
22public:
23    constexpr tuple();
24    explicit tuple(const T&...);  // constexpr in C++14
25    template <class... U>
26        explicit tuple(U&&...);  // constexpr in C++14
27    tuple(const tuple&) = default;
28    tuple(tuple&&) = default;
29    template <class... U>
30        tuple(const tuple<U...>&);  // constexpr in C++14
31    template <class... U>
32        tuple(tuple<U...>&&);  // constexpr in C++14
33    template <class U1, class U2>
34        tuple(const pair<U1, U2>&); // iff sizeof...(T) == 2 // constexpr in C++14
35    template <class U1, class U2>
36        tuple(pair<U1, U2>&&); // iff sizeof...(T) == 2  // constexpr in C++14
37
38    // allocator-extended constructors
39    template <class Alloc>
40        tuple(allocator_arg_t, const Alloc& a);
41    template <class Alloc>
42        tuple(allocator_arg_t, const Alloc& a, const T&...);
43    template <class Alloc, class... U>
44        tuple(allocator_arg_t, const Alloc& a, U&&...);
45    template <class Alloc>
46        tuple(allocator_arg_t, const Alloc& a, const tuple&);
47    template <class Alloc>
48        tuple(allocator_arg_t, const Alloc& a, tuple&&);
49    template <class Alloc, class... U>
50        tuple(allocator_arg_t, const Alloc& a, const tuple<U...>&);
51    template <class Alloc, class... U>
52        tuple(allocator_arg_t, const Alloc& a, tuple<U...>&&);
53    template <class Alloc, class U1, class U2>
54        tuple(allocator_arg_t, const Alloc& a, const pair<U1, U2>&);
55    template <class Alloc, class U1, class U2>
56        tuple(allocator_arg_t, const Alloc& a, pair<U1, U2>&&);
57
58    tuple& operator=(const tuple&);
59    tuple&
60        operator=(tuple&&) noexcept(AND(is_nothrow_move_assignable<T>::value ...));
61    template <class... U>
62        tuple& operator=(const tuple<U...>&);
63    template <class... U>
64        tuple& operator=(tuple<U...>&&);
65    template <class U1, class U2>
66        tuple& operator=(const pair<U1, U2>&); // iff sizeof...(T) == 2
67    template <class U1, class U2>
68        tuple& operator=(pair<U1, U2>&&); //iffsizeof...(T) == 2
69
70    void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...));
71};
72
73const unspecified ignore;
74
75template <class... T> tuple<V...>  make_tuple(T&&...); // constexpr in C++14
76template <class... T> tuple<ATypes...> forward_as_tuple(T&&...) noexcept; // constexpr in C++14
77template <class... T> tuple<T&...> tie(T&...) noexcept; // constexpr in C++14
78template <class... Tuples> tuple<CTypes...> tuple_cat(Tuples&&... tpls); // constexpr in C++14
79
80// [tuple.apply], calling a function with a tuple of arguments:
81template <class F, class Tuple>
82  constexpr decltype(auto) apply(F&& f, Tuple&& t); // C++17
83template <class T, class Tuple>
84  constexpr T make_from_tuple(Tuple&& t); // C++17
85
86// 20.4.1.4, tuple helper classes:
87template <class T> class tuple_size; // undefined
88template <class... T> class tuple_size<tuple<T...>>;
89template <class T>
90 constexpr size_t tuple_size_v = tuple_size<T>::value; // C++17
91template <size_t I, class T> class tuple_element; // undefined
92template <size_t I, class... T> class tuple_element<I, tuple<T...>>;
93template <size_t I, class T>
94  using tuple_element_t = typename tuple_element <I, T>::type; // C++14
95
96// 20.4.1.5, element access:
97template <size_t I, class... T>
98    typename tuple_element<I, tuple<T...>>::type&
99    get(tuple<T...>&) noexcept; // constexpr in C++14
100template <size_t I, class... T>
101    const typename tuple_element<I, tuple<T...>>::type&
102    get(const tuple<T...>&) noexcept; // constexpr in C++14
103template <size_t I, class... T>
104    typename tuple_element<I, tuple<T...>>::type&&
105    get(tuple<T...>&&) noexcept; // constexpr in C++14
106template <size_t I, class... T>
107    const typename tuple_element<I, tuple<T...>>::type&&
108    get(const tuple<T...>&&) noexcept; // constexpr in C++14
109
110template <class T1, class... T>
111    constexpr T1& get(tuple<T...>&) noexcept;  // C++14
112template <class T1, class... T>
113    constexpr const T1& get(const tuple<T...>&) noexcept;   // C++14
114template <class T1, class... T>
115    constexpr T1&& get(tuple<T...>&&) noexcept;   // C++14
116template <class T1, class... T>
117    constexpr const T1&& get(const tuple<T...>&&) noexcept;   // C++14
118
119// 20.4.1.6, relational operators:
120template<class... T, class... U> bool operator==(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
121template<class... T, class... U> bool operator<(const tuple<T...>&, const tuple<U...>&);  // constexpr in C++14
122template<class... T, class... U> bool operator!=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
123template<class... T, class... U> bool operator>(const tuple<T...>&, const tuple<U...>&);  // constexpr in C++14
124template<class... T, class... U> bool operator<=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
125template<class... T, class... U> bool operator>=(const tuple<T...>&, const tuple<U...>&); // constexpr in C++14
126
127template <class... Types, class Alloc>
128  struct uses_allocator<tuple<Types...>, Alloc>;
129
130template <class... Types>
131  void
132  swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(noexcept(x.swap(y)));
133
134}  // std
135
136*/
137
138#include <__config>
139#include <__tuple>
140#include <cstddef>
141#include <type_traits>
142#include <__functional_base>
143#include <utility>
144
145#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
146#pragma GCC system_header
147#endif
148
149_LIBCPP_BEGIN_NAMESPACE_STD
150
151#ifndef _LIBCPP_HAS_NO_VARIADICS
152
153
154// __tuple_leaf
155
156template <size_t _Ip, class _Hp,
157          bool=is_empty<_Hp>::value && !__libcpp_is_final<_Hp>::value
158         >
159class __tuple_leaf;
160
161template <size_t _Ip, class _Hp, bool _Ep>
162inline _LIBCPP_INLINE_VISIBILITY
163void swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y)
164    _NOEXCEPT_(__is_nothrow_swappable<_Hp>::value)
165{
166    swap(__x.get(), __y.get());
167}
168
169template <size_t _Ip, class _Hp, bool>
170class __tuple_leaf
171{
172    _Hp value;
173
174    template <class _Tp>
175    static constexpr bool __can_bind_reference() {
176        using _RawTp = typename remove_reference<_Tp>::type;
177        using _RawHp = typename remove_reference<_Hp>::type;
178        using _CheckLValueArg = integral_constant<bool,
179            is_lvalue_reference<_Tp>::value
180        ||  is_same<_RawTp, reference_wrapper<_RawHp>>::value
181        ||  is_same<_RawTp, reference_wrapper<typename remove_const<_RawHp>::type>>::value
182        >;
183        return  !is_reference<_Hp>::value
184            || (is_lvalue_reference<_Hp>::value && _CheckLValueArg::value)
185            || (is_rvalue_reference<_Hp>::value && !is_lvalue_reference<_Tp>::value);
186    }
187
188    __tuple_leaf& operator=(const __tuple_leaf&);
189public:
190    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __tuple_leaf()
191             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) : value()
192       {static_assert(!is_reference<_Hp>::value,
193              "Attempted to default construct a reference element in a tuple");}
194
195    template <class _Alloc>
196        _LIBCPP_INLINE_VISIBILITY
197        __tuple_leaf(integral_constant<int, 0>, const _Alloc&)
198            : value()
199        {static_assert(!is_reference<_Hp>::value,
200              "Attempted to default construct a reference element in a tuple");}
201
202    template <class _Alloc>
203        _LIBCPP_INLINE_VISIBILITY
204        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
205            : value(allocator_arg_t(), __a)
206        {static_assert(!is_reference<_Hp>::value,
207              "Attempted to default construct a reference element in a tuple");}
208
209    template <class _Alloc>
210        _LIBCPP_INLINE_VISIBILITY
211        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
212            : value(__a)
213        {static_assert(!is_reference<_Hp>::value,
214              "Attempted to default construct a reference element in a tuple");}
215
216    template <class _Tp,
217              class = typename enable_if<
218                  __lazy_and<
219                      __lazy_not<is_same<typename decay<_Tp>::type, __tuple_leaf>>
220                    , is_constructible<_Hp, _Tp>
221                    >::value
222                >::type
223            >
224        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
225        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
226            : value(_VSTD::forward<_Tp>(__t))
227        {static_assert(__can_bind_reference<_Tp>(),
228       "Attempted to construct a reference element in a tuple with an rvalue");}
229
230    template <class _Tp, class _Alloc>
231        _LIBCPP_INLINE_VISIBILITY
232        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
233            : value(_VSTD::forward<_Tp>(__t))
234        {static_assert(__can_bind_reference<_Tp>(),
235       "Attempted to construct a reference element in a tuple with an rvalue");}
236
237    template <class _Tp, class _Alloc>
238        _LIBCPP_INLINE_VISIBILITY
239        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
240            : value(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t))
241        {static_assert(!is_reference<_Hp>::value,
242            "Attempted to uses-allocator construct a reference element in a tuple");}
243
244    template <class _Tp, class _Alloc>
245        _LIBCPP_INLINE_VISIBILITY
246        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
247            : value(_VSTD::forward<_Tp>(__t), __a)
248        {static_assert(!is_reference<_Hp>::value,
249           "Attempted to uses-allocator construct a reference element in a tuple");}
250
251    __tuple_leaf(const __tuple_leaf& __t) = default;
252    __tuple_leaf(__tuple_leaf&& __t) = default;
253
254    template <class _Tp>
255        _LIBCPP_INLINE_VISIBILITY
256        __tuple_leaf&
257        operator=(_Tp&& __t) _NOEXCEPT_((is_nothrow_assignable<_Hp&, _Tp>::value))
258        {
259            value = _VSTD::forward<_Tp>(__t);
260            return *this;
261        }
262
263    _LIBCPP_INLINE_VISIBILITY
264    int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
265    {
266        _VSTD::swap(*this, __t);
267        return 0;
268    }
269
270    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11       _Hp& get()       _NOEXCEPT {return value;}
271    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return value;}
272};
273
274template <size_t _Ip, class _Hp>
275class __tuple_leaf<_Ip, _Hp, true>
276    : private _Hp
277{
278
279    __tuple_leaf& operator=(const __tuple_leaf&);
280public:
281    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __tuple_leaf()
282             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) {}
283
284    template <class _Alloc>
285        _LIBCPP_INLINE_VISIBILITY
286        __tuple_leaf(integral_constant<int, 0>, const _Alloc&) {}
287
288    template <class _Alloc>
289        _LIBCPP_INLINE_VISIBILITY
290        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
291            : _Hp(allocator_arg_t(), __a) {}
292
293    template <class _Alloc>
294        _LIBCPP_INLINE_VISIBILITY
295        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
296            : _Hp(__a) {}
297
298    template <class _Tp,
299              class = typename enable_if<
300                  __lazy_and<
301                        __lazy_not<is_same<typename decay<_Tp>::type, __tuple_leaf>>
302                      , is_constructible<_Hp, _Tp>
303                    >::value
304                >::type
305            >
306        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
307        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
308            : _Hp(_VSTD::forward<_Tp>(__t)) {}
309
310    template <class _Tp, class _Alloc>
311        _LIBCPP_INLINE_VISIBILITY
312        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
313            : _Hp(_VSTD::forward<_Tp>(__t)) {}
314
315    template <class _Tp, class _Alloc>
316        _LIBCPP_INLINE_VISIBILITY
317        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
318            : _Hp(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) {}
319
320    template <class _Tp, class _Alloc>
321        _LIBCPP_INLINE_VISIBILITY
322        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
323            : _Hp(_VSTD::forward<_Tp>(__t), __a) {}
324
325    __tuple_leaf(__tuple_leaf const &) = default;
326    __tuple_leaf(__tuple_leaf &&) = default;
327
328    template <class _Tp>
329        _LIBCPP_INLINE_VISIBILITY
330        __tuple_leaf&
331        operator=(_Tp&& __t) _NOEXCEPT_((is_nothrow_assignable<_Hp&, _Tp>::value))
332        {
333            _Hp::operator=(_VSTD::forward<_Tp>(__t));
334            return *this;
335        }
336
337    _LIBCPP_INLINE_VISIBILITY
338    int
339    swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
340    {
341        _VSTD::swap(*this, __t);
342        return 0;
343    }
344
345    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11       _Hp& get()       _NOEXCEPT {return static_cast<_Hp&>(*this);}
346    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Hp& get() const _NOEXCEPT {return static_cast<const _Hp&>(*this);}
347};
348
349template <class ..._Tp>
350_LIBCPP_INLINE_VISIBILITY
351void __swallow(_Tp&&...) _NOEXCEPT {}
352
353template <class ..._Tp>
354struct __lazy_all : __all<_Tp::value...> {};
355
356template <class _Tp>
357struct __all_default_constructible;
358
359template <class ..._Tp>
360struct __all_default_constructible<__tuple_types<_Tp...>>
361    : __all<is_default_constructible<_Tp>::value...>
362{ };
363
364// __tuple_impl
365
366template<class _Indx, class ..._Tp> struct __tuple_impl;
367
368template<size_t ..._Indx, class ..._Tp>
369struct __tuple_impl<__tuple_indices<_Indx...>, _Tp...>
370    : public __tuple_leaf<_Indx, _Tp>...
371{
372    _LIBCPP_INLINE_VISIBILITY
373    _LIBCPP_CONSTEXPR __tuple_impl()
374        _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
375
376    template <size_t ..._Uf, class ..._Tf,
377              size_t ..._Ul, class ..._Tl, class ..._Up>
378        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
379        explicit
380        __tuple_impl(__tuple_indices<_Uf...>, __tuple_types<_Tf...>,
381                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
382                     _Up&&... __u)
383                     _NOEXCEPT_((__all<is_nothrow_constructible<_Tf, _Up>::value...>::value &&
384                                 __all<is_nothrow_default_constructible<_Tl>::value...>::value)) :
385            __tuple_leaf<_Uf, _Tf>(_VSTD::forward<_Up>(__u))...,
386            __tuple_leaf<_Ul, _Tl>()...
387            {}
388
389    template <class _Alloc, size_t ..._Uf, class ..._Tf,
390              size_t ..._Ul, class ..._Tl, class ..._Up>
391        _LIBCPP_INLINE_VISIBILITY
392        explicit
393        __tuple_impl(allocator_arg_t, const _Alloc& __a,
394                     __tuple_indices<_Uf...>, __tuple_types<_Tf...>,
395                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
396                     _Up&&... __u) :
397            __tuple_leaf<_Uf, _Tf>(__uses_alloc_ctor<_Tf, _Alloc, _Up>(), __a,
398            _VSTD::forward<_Up>(__u))...,
399            __tuple_leaf<_Ul, _Tl>(__uses_alloc_ctor<_Tl, _Alloc>(), __a)...
400            {}
401
402    template <class _Tuple,
403              class = typename enable_if
404                      <
405                         __tuple_constructible<_Tuple, tuple<_Tp...> >::value
406                      >::type
407             >
408        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
409        __tuple_impl(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_constructible<_Tp, typename tuple_element<_Indx,
410                                       typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))
411            : __tuple_leaf<_Indx, _Tp>(_VSTD::forward<typename tuple_element<_Indx,
412                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
413            {}
414
415    template <class _Alloc, class _Tuple,
416              class = typename enable_if
417                      <
418                         __tuple_constructible<_Tuple, tuple<_Tp...> >::value
419                      >::type
420             >
421        _LIBCPP_INLINE_VISIBILITY
422        __tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
423            : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, typename tuple_element<_Indx,
424                                       typename __make_tuple_types<_Tuple>::type>::type>(), __a,
425                                       _VSTD::forward<typename tuple_element<_Indx,
426                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
427            {}
428
429    template <class _Tuple>
430        _LIBCPP_INLINE_VISIBILITY
431        typename enable_if
432        <
433            __tuple_assignable<_Tuple, tuple<_Tp...> >::value,
434            __tuple_impl&
435        >::type
436        operator=(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_assignable<_Tp&, typename tuple_element<_Indx,
437                                       typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))
438        {
439            __swallow(__tuple_leaf<_Indx, _Tp>::operator=(_VSTD::forward<typename tuple_element<_Indx,
440                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...);
441            return *this;
442        }
443
444    __tuple_impl(const __tuple_impl&) = default;
445    __tuple_impl(__tuple_impl&&) = default;
446
447    _LIBCPP_INLINE_VISIBILITY
448    __tuple_impl&
449    operator=(const __tuple_impl& __t) _NOEXCEPT_((__all<is_nothrow_copy_assignable<_Tp>::value...>::value))
450    {
451        __swallow(__tuple_leaf<_Indx, _Tp>::operator=(static_cast<const __tuple_leaf<_Indx, _Tp>&>(__t).get())...);
452        return *this;
453    }
454
455    _LIBCPP_INLINE_VISIBILITY
456    __tuple_impl&
457    operator=(__tuple_impl&& __t) _NOEXCEPT_((__all<is_nothrow_move_assignable<_Tp>::value...>::value))
458    {
459        __swallow(__tuple_leaf<_Indx, _Tp>::operator=(_VSTD::forward<_Tp>(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t).get()))...);
460        return *this;
461    }
462
463    _LIBCPP_INLINE_VISIBILITY
464    void swap(__tuple_impl& __t)
465        _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
466    {
467        __swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...);
468    }
469};
470
471
472
473template <class ..._Tp>
474class _LIBCPP_TYPE_VIS_ONLY tuple
475{
476    typedef __tuple_impl<typename __make_tuple_indices<sizeof...(_Tp)>::type, _Tp...> base;
477
478    base base_;
479
480    template <class ..._Args>
481    struct _PackExpandsToThisTuple : false_type {};
482
483    template <class _Arg>
484    struct _PackExpandsToThisTuple<_Arg>
485        : is_same<typename __uncvref<_Arg>::type, tuple> {};
486
487    template <bool _MaybeEnable, class _Dummy = void>
488    struct _CheckArgsConstructor : __check_tuple_constructor_fail {};
489
490    template <class _Dummy>
491    struct _CheckArgsConstructor<true, _Dummy>
492    {
493        template <class ..._Args>
494        static constexpr bool __enable_default() {
495            return __all<is_default_constructible<_Args>::value...>::value;
496        }
497
498        template <class ..._Args>
499        static constexpr bool __enable_explicit() {
500            return
501                __tuple_constructible<
502                    tuple<_Args...>,
503                    typename __make_tuple_types<tuple,
504                             sizeof...(_Args) < sizeof...(_Tp) ?
505                                 sizeof...(_Args) :
506                                 sizeof...(_Tp)>::type
507                >::value &&
508                !__tuple_convertible<
509                    tuple<_Args...>,
510                    typename __make_tuple_types<tuple,
511                             sizeof...(_Args) < sizeof...(_Tp) ?
512                                 sizeof...(_Args) :
513                                 sizeof...(_Tp)>::type
514                >::value &&
515                __all_default_constructible<
516                    typename __make_tuple_types<tuple, sizeof...(_Tp),
517                             sizeof...(_Args) < sizeof...(_Tp) ?
518                                 sizeof...(_Args) :
519                                 sizeof...(_Tp)>::type
520                >::value;
521        }
522
523        template <class ..._Args>
524        static constexpr bool __enable_implicit() {
525            return
526                __tuple_convertible<
527                    tuple<_Args...>,
528                    typename __make_tuple_types<tuple,
529                             sizeof...(_Args) < sizeof...(_Tp) ?
530                                 sizeof...(_Args) :
531                                 sizeof...(_Tp)>::type
532                >::value &&
533                __all_default_constructible<
534                    typename __make_tuple_types<tuple, sizeof...(_Tp),
535                             sizeof...(_Args) < sizeof...(_Tp) ?
536                                 sizeof...(_Args) :
537                                 sizeof...(_Tp)>::type
538                >::value;
539        }
540    };
541
542    template <bool _MaybeEnable,
543              bool = sizeof...(_Tp) == 1,
544              class _Dummy = void>
545    struct _CheckTupleLikeConstructor : __check_tuple_constructor_fail {};
546
547    template <class _Dummy>
548    struct _CheckTupleLikeConstructor<true, false, _Dummy>
549    {
550        template <class _Tuple>
551        static constexpr bool __enable_implicit() {
552            return __tuple_convertible<_Tuple, tuple>::value;
553        }
554
555        template <class _Tuple>
556        static constexpr bool __enable_explicit() {
557            return __tuple_constructible<_Tuple, tuple>::value
558               && !__tuple_convertible<_Tuple, tuple>::value;
559        }
560    };
561
562    template <class _Dummy>
563    struct _CheckTupleLikeConstructor<true, true, _Dummy>
564    {
565        // This trait is used to disable the tuple-like constructor when
566        // the UTypes... constructor should be selected instead.
567        // See LWG issue #2549.
568        template <class _Tuple>
569        using _PreferTupleLikeConstructor = __lazy_or<
570            // Don't attempt the two checks below if the tuple we are given
571            // has the same type as this tuple.
572            is_same<typename __uncvref<_Tuple>::type, tuple>,
573            __lazy_and<
574                __lazy_not<is_constructible<_Tp..., _Tuple>>,
575                __lazy_not<is_convertible<_Tuple, _Tp...>>
576            >
577        >;
578
579        template <class _Tuple>
580        static constexpr bool __enable_implicit() {
581            return __lazy_and<
582                __tuple_convertible<_Tuple, tuple>,
583                _PreferTupleLikeConstructor<_Tuple>
584            >::value;
585        }
586
587        template <class _Tuple>
588        static constexpr bool __enable_explicit() {
589            return __lazy_and<
590                __tuple_constructible<_Tuple, tuple>,
591                _PreferTupleLikeConstructor<_Tuple>,
592                __lazy_not<__tuple_convertible<_Tuple, tuple>>
593            >::value;
594        }
595    };
596
597    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
598        typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT;
599    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
600        const typename tuple_element<_Jp, tuple<_Up...> >::type& get(const tuple<_Up...>&) _NOEXCEPT;
601    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
602        typename tuple_element<_Jp, tuple<_Up...> >::type&& get(tuple<_Up...>&&) _NOEXCEPT;
603    template <size_t _Jp, class ..._Up> friend _LIBCPP_CONSTEXPR_AFTER_CXX11
604        const typename tuple_element<_Jp, tuple<_Up...> >::type&& get(const tuple<_Up...>&&) _NOEXCEPT;
605public:
606
607    template <bool _Dummy = true, class = typename enable_if<
608        _CheckArgsConstructor<_Dummy>::template __enable_default<_Tp...>()
609    >::type>
610    _LIBCPP_INLINE_VISIBILITY
611    _LIBCPP_CONSTEXPR tuple()
612        _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
613
614    tuple(tuple const&) = default;
615    tuple(tuple&&) = default;
616
617    template <class _AllocArgT, class _Alloc, bool _Dummy = true, class = typename enable_if<
618        __lazy_and<
619            is_same<allocator_arg_t, _AllocArgT>,
620            __lazy_all<__dependent_type<is_default_constructible<_Tp>, _Dummy>...>
621       >::value
622    >::type>
623    _LIBCPP_INLINE_VISIBILITY
624    tuple(_AllocArgT, _Alloc const& __a)
625      : base_(allocator_arg_t(), __a,
626                    __tuple_indices<>(), __tuple_types<>(),
627                    typename __make_tuple_indices<sizeof...(_Tp), 0>::type(),
628                    __tuple_types<_Tp...>()) {}
629
630    template <bool _Dummy = true,
631              typename enable_if
632                      <
633                         _CheckArgsConstructor<
634                            _Dummy
635                         >::template __enable_implicit<_Tp...>(),
636                         bool
637                      >::type = false
638        >
639    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
640    tuple(const _Tp& ... __t) _NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value))
641        : base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
642                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
643                typename __make_tuple_indices<0>::type(),
644                typename __make_tuple_types<tuple, 0>::type(),
645                __t...
646               ) {}
647
648    template <bool _Dummy = true,
649              typename enable_if
650                      <
651                         _CheckArgsConstructor<
652                            _Dummy
653                         >::template __enable_explicit<_Tp...>(),
654                         bool
655                      >::type = false
656        >
657    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
658    explicit tuple(const _Tp& ... __t) _NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value))
659        : base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
660                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
661                typename __make_tuple_indices<0>::type(),
662                typename __make_tuple_types<tuple, 0>::type(),
663                __t...
664               ) {}
665
666    template <class _Alloc, bool _Dummy = true,
667              typename enable_if
668                      <
669                         _CheckArgsConstructor<
670                            _Dummy
671                         >::template __enable_implicit<_Tp...>(),
672                         bool
673                      >::type = false
674        >
675      _LIBCPP_INLINE_VISIBILITY
676      tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
677        : base_(allocator_arg_t(), __a,
678                typename __make_tuple_indices<sizeof...(_Tp)>::type(),
679                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
680                typename __make_tuple_indices<0>::type(),
681                typename __make_tuple_types<tuple, 0>::type(),
682                __t...
683               ) {}
684
685    template <class _Alloc, bool _Dummy = true,
686              typename enable_if
687                      <
688                         _CheckArgsConstructor<
689                            _Dummy
690                         >::template __enable_explicit<_Tp...>(),
691                         bool
692                      >::type = false
693        >
694      _LIBCPP_INLINE_VISIBILITY
695      explicit
696      tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
697        : base_(allocator_arg_t(), __a,
698                typename __make_tuple_indices<sizeof...(_Tp)>::type(),
699                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
700                typename __make_tuple_indices<0>::type(),
701                typename __make_tuple_types<tuple, 0>::type(),
702                __t...
703               ) {}
704
705    template <class ..._Up,
706              typename enable_if
707                      <
708                         _CheckArgsConstructor<
709                             sizeof...(_Up) <= sizeof...(_Tp)
710                             && !_PackExpandsToThisTuple<_Up...>::value
711                         >::template __enable_implicit<_Up...>(),
712                         bool
713                      >::type = false
714             >
715        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
716        tuple(_Up&&... __u)
717            _NOEXCEPT_((
718                is_nothrow_constructible<base,
719                    typename __make_tuple_indices<sizeof...(_Up)>::type,
720                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type,
721                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type,
722                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type,
723                    _Up...
724                >::value
725            ))
726            : base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
727                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
728                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
729                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
730                    _VSTD::forward<_Up>(__u)...) {}
731
732    template <class ..._Up,
733              typename enable_if
734                      <
735                         _CheckArgsConstructor<
736                             sizeof...(_Up) <= sizeof...(_Tp)
737                             && !_PackExpandsToThisTuple<_Up...>::value
738                         >::template __enable_explicit<_Up...>(),
739                         bool
740                      >::type = false
741             >
742        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
743        explicit
744        tuple(_Up&&... __u)
745            _NOEXCEPT_((
746                is_nothrow_constructible<base,
747                    typename __make_tuple_indices<sizeof...(_Up)>::type,
748                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type,
749                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type,
750                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type,
751                    _Up...
752                >::value
753            ))
754            : base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
755                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
756                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
757                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
758                    _VSTD::forward<_Up>(__u)...) {}
759
760    template <class _Alloc, class ..._Up,
761              typename enable_if
762                      <
763                         _CheckArgsConstructor<
764                             sizeof...(_Up) == sizeof...(_Tp) &&
765                             !_PackExpandsToThisTuple<_Up...>::value
766                         >::template __enable_implicit<_Up...>(),
767                         bool
768                      >::type = false
769             >
770        _LIBCPP_INLINE_VISIBILITY
771        tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
772            : base_(allocator_arg_t(), __a,
773                    typename __make_tuple_indices<sizeof...(_Up)>::type(),
774                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
775                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
776                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
777                    _VSTD::forward<_Up>(__u)...) {}
778
779    template <class _Alloc, class ..._Up,
780              typename enable_if
781                      <
782                         _CheckArgsConstructor<
783                             sizeof...(_Up) == sizeof...(_Tp) &&
784                             !_PackExpandsToThisTuple<_Up...>::value
785                         >::template __enable_explicit<_Up...>(),
786                         bool
787                      >::type = false
788             >
789        _LIBCPP_INLINE_VISIBILITY
790        explicit
791        tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
792            : base_(allocator_arg_t(), __a,
793                    typename __make_tuple_indices<sizeof...(_Up)>::type(),
794                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
795                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
796                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
797                    _VSTD::forward<_Up>(__u)...) {}
798
799    template <class _Tuple,
800              typename enable_if
801                      <
802                         _CheckTupleLikeConstructor<
803                             __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value
804                             && !_PackExpandsToThisTuple<_Tuple>::value
805                         >::template __enable_implicit<_Tuple>(),
806                         bool
807                      >::type = false
808             >
809        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
810        tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<base, _Tuple>::value))
811            : base_(_VSTD::forward<_Tuple>(__t)) {}
812
813    template <class _Tuple,
814              typename enable_if
815                      <
816                         _CheckTupleLikeConstructor<
817                             __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value
818                             && !_PackExpandsToThisTuple<_Tuple>::value
819                         >::template __enable_explicit<_Tuple>(),
820                         bool
821                      >::type = false
822             >
823        _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
824        explicit
825        tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<base, _Tuple>::value))
826            : base_(_VSTD::forward<_Tuple>(__t)) {}
827
828    template <class _Alloc, class _Tuple,
829              typename enable_if
830                      <
831                         _CheckTupleLikeConstructor<
832                             __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value
833                         >::template __enable_implicit<_Tuple>(),
834                         bool
835                      >::type = false
836             >
837        _LIBCPP_INLINE_VISIBILITY
838        tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
839            : base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {}
840
841    template <class _Alloc, class _Tuple,
842              typename enable_if
843                      <
844                         _CheckTupleLikeConstructor<
845                             __tuple_like_with_size<_Tuple, sizeof...(_Tp)>::value
846                         >::template __enable_explicit<_Tuple>(),
847                         bool
848                      >::type = false
849             >
850        _LIBCPP_INLINE_VISIBILITY
851        explicit
852        tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
853            : base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {}
854
855    using _CanCopyAssign = __all<is_copy_assignable<_Tp>::value...>;
856    using _CanMoveAssign = __all<is_move_assignable<_Tp>::value...>;
857
858    _LIBCPP_INLINE_VISIBILITY
859    tuple& operator=(typename conditional<_CanCopyAssign::value, tuple, __nat>::type const& __t)
860        _NOEXCEPT_((__all<is_nothrow_copy_assignable<_Tp>::value...>::value))
861    {
862        base_.operator=(__t.base_);
863        return *this;
864    }
865
866    _LIBCPP_INLINE_VISIBILITY
867    tuple& operator=(typename conditional<_CanMoveAssign::value, tuple, __nat>::type&& __t)
868        _NOEXCEPT_((__all<is_nothrow_move_assignable<_Tp>::value...>::value))
869    {
870        base_.operator=(static_cast<base&&>(__t.base_));
871        return *this;
872    }
873
874    template <class _Tuple,
875              class = typename enable_if
876                      <
877                         __tuple_assignable<_Tuple, tuple>::value
878                      >::type
879             >
880        _LIBCPP_INLINE_VISIBILITY
881        tuple&
882        operator=(_Tuple&& __t) _NOEXCEPT_((is_nothrow_assignable<base&, _Tuple>::value))
883        {
884            base_.operator=(_VSTD::forward<_Tuple>(__t));
885            return *this;
886        }
887
888    _LIBCPP_INLINE_VISIBILITY
889    void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
890        {base_.swap(__t.base_);}
891};
892
893template <>
894class _LIBCPP_TYPE_VIS_ONLY tuple<>
895{
896public:
897    _LIBCPP_INLINE_VISIBILITY
898    _LIBCPP_CONSTEXPR tuple() _NOEXCEPT {}
899    template <class _Alloc>
900    _LIBCPP_INLINE_VISIBILITY
901        tuple(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
902    template <class _Alloc>
903    _LIBCPP_INLINE_VISIBILITY
904        tuple(allocator_arg_t, const _Alloc&, const tuple&) _NOEXCEPT {}
905    template <class _Up>
906    _LIBCPP_INLINE_VISIBILITY
907        tuple(array<_Up, 0>) _NOEXCEPT {}
908    template <class _Alloc, class _Up>
909    _LIBCPP_INLINE_VISIBILITY
910        tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) _NOEXCEPT {}
911    _LIBCPP_INLINE_VISIBILITY
912    void swap(tuple&) _NOEXCEPT {}
913};
914
915template <class ..._Tp>
916inline _LIBCPP_INLINE_VISIBILITY
917typename enable_if
918<
919    __all<__is_swappable<_Tp>::value...>::value,
920    void
921>::type
922swap(tuple<_Tp...>& __t, tuple<_Tp...>& __u)
923                 _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
924    {__t.swap(__u);}
925
926// get
927
928template <size_t _Ip, class ..._Tp>
929inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
930typename tuple_element<_Ip, tuple<_Tp...> >::type&
931get(tuple<_Tp...>& __t) _NOEXCEPT
932{
933    typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
934    return static_cast<__tuple_leaf<_Ip, type>&>(__t.base_).get();
935}
936
937template <size_t _Ip, class ..._Tp>
938inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
939const typename tuple_element<_Ip, tuple<_Tp...> >::type&
940get(const tuple<_Tp...>& __t) _NOEXCEPT
941{
942    typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
943    return static_cast<const __tuple_leaf<_Ip, type>&>(__t.base_).get();
944}
945
946template <size_t _Ip, class ..._Tp>
947inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
948typename tuple_element<_Ip, tuple<_Tp...> >::type&&
949get(tuple<_Tp...>&& __t) _NOEXCEPT
950{
951    typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
952    return static_cast<type&&>(
953             static_cast<__tuple_leaf<_Ip, type>&&>(__t.base_).get());
954}
955
956template <size_t _Ip, class ..._Tp>
957inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
958const typename tuple_element<_Ip, tuple<_Tp...> >::type&&
959get(const tuple<_Tp...>&& __t) _NOEXCEPT
960{
961    typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
962    return static_cast<const type&&>(
963             static_cast<const __tuple_leaf<_Ip, type>&&>(__t.base_).get());
964}
965
966#if _LIBCPP_STD_VER > 11
967
968namespace __find_detail {
969
970static constexpr size_t __not_found = -1;
971static constexpr size_t __ambiguous = __not_found - 1;
972
973inline _LIBCPP_INLINE_VISIBILITY
974constexpr size_t __find_idx_return(size_t __curr_i, size_t __res, bool __matches) {
975    return !__matches ? __res :
976        (__res == __not_found ? __curr_i : __ambiguous);
977}
978
979template <size_t _Nx>
980inline _LIBCPP_INLINE_VISIBILITY
981constexpr size_t __find_idx(size_t __i, const bool (&__matches)[_Nx]) {
982  return __i == _Nx ? __not_found :
983      __find_idx_return(__i, __find_idx(__i + 1, __matches), __matches[__i]);
984}
985
986template <class _T1, class ..._Args>
987struct __find_exactly_one_checked {
988  static constexpr bool __matches[] = {is_same<_T1, _Args>::value...};
989    static constexpr size_t value = __find_detail::__find_idx(0, __matches);
990    static_assert (value != __not_found, "type not found in type list" );
991    static_assert(value != __ambiguous,"type occurs more than once in type list");
992};
993
994template <class _T1>
995struct __find_exactly_one_checked<_T1> {
996    static_assert(!is_same<_T1, _T1>::value, "type not in empty type list");
997};
998
999} // namespace __find_detail;
1000
1001template <typename _T1, typename... _Args>
1002struct __find_exactly_one_t
1003    : public __find_detail::__find_exactly_one_checked<_T1, _Args...> {
1004};
1005
1006template <class _T1, class... _Args>
1007inline _LIBCPP_INLINE_VISIBILITY
1008constexpr _T1& get(tuple<_Args...>& __tup) noexcept
1009{
1010    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
1011}
1012
1013template <class _T1, class... _Args>
1014inline _LIBCPP_INLINE_VISIBILITY
1015constexpr _T1 const& get(tuple<_Args...> const& __tup) noexcept
1016{
1017    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
1018}
1019
1020template <class _T1, class... _Args>
1021inline _LIBCPP_INLINE_VISIBILITY
1022constexpr _T1&& get(tuple<_Args...>&& __tup) noexcept
1023{
1024    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));
1025}
1026
1027template <class _T1, class... _Args>
1028inline _LIBCPP_INLINE_VISIBILITY
1029constexpr _T1 const&& get(tuple<_Args...> const&& __tup) noexcept
1030{
1031    return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move(__tup));
1032}
1033
1034#endif
1035
1036// tie
1037
1038template <class ..._Tp>
1039inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1040tuple<_Tp&...>
1041tie(_Tp&... __t) _NOEXCEPT
1042{
1043    return tuple<_Tp&...>(__t...);
1044}
1045
1046template <class _Up>
1047struct __ignore_t
1048{
1049    template <class _Tp>
1050        _LIBCPP_INLINE_VISIBILITY
1051        const __ignore_t& operator=(_Tp&&) const {return *this;}
1052};
1053
1054namespace { const __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>(); }
1055
1056template <class _Tp>
1057struct __make_tuple_return_impl
1058{
1059    typedef _Tp type;
1060};
1061
1062template <class _Tp>
1063struct __make_tuple_return_impl<reference_wrapper<_Tp> >
1064{
1065    typedef _Tp& type;
1066};
1067
1068template <class _Tp>
1069struct __make_tuple_return
1070{
1071    typedef typename __make_tuple_return_impl<typename decay<_Tp>::type>::type type;
1072};
1073
1074template <class... _Tp>
1075inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1076tuple<typename __make_tuple_return<_Tp>::type...>
1077make_tuple(_Tp&&... __t)
1078{
1079    return tuple<typename __make_tuple_return<_Tp>::type...>(_VSTD::forward<_Tp>(__t)...);
1080}
1081
1082template <class... _Tp>
1083inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1084tuple<_Tp&&...>
1085forward_as_tuple(_Tp&&... __t) _NOEXCEPT
1086{
1087    return tuple<_Tp&&...>(_VSTD::forward<_Tp>(__t)...);
1088}
1089
1090template <size_t _Ip>
1091struct __tuple_equal
1092{
1093    template <class _Tp, class _Up>
1094    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1095    bool operator()(const _Tp& __x, const _Up& __y)
1096    {
1097        return __tuple_equal<_Ip - 1>()(__x, __y) && _VSTD::get<_Ip-1>(__x) == _VSTD::get<_Ip-1>(__y);
1098    }
1099};
1100
1101template <>
1102struct __tuple_equal<0>
1103{
1104    template <class _Tp, class _Up>
1105    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1106    bool operator()(const _Tp&, const _Up&)
1107    {
1108        return true;
1109    }
1110};
1111
1112template <class ..._Tp, class ..._Up>
1113inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1114bool
1115operator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1116{
1117    return __tuple_equal<sizeof...(_Tp)>()(__x, __y);
1118}
1119
1120template <class ..._Tp, class ..._Up>
1121inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1122bool
1123operator!=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1124{
1125    return !(__x == __y);
1126}
1127
1128template <size_t _Ip>
1129struct __tuple_less
1130{
1131    template <class _Tp, class _Up>
1132    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1133    bool operator()(const _Tp& __x, const _Up& __y)
1134    {
1135        const size_t __idx = tuple_size<_Tp>::value - _Ip;
1136        if (_VSTD::get<__idx>(__x) < _VSTD::get<__idx>(__y))
1137            return true;
1138        if (_VSTD::get<__idx>(__y) < _VSTD::get<__idx>(__x))
1139            return false;
1140        return __tuple_less<_Ip-1>()(__x, __y);
1141    }
1142};
1143
1144template <>
1145struct __tuple_less<0>
1146{
1147    template <class _Tp, class _Up>
1148    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1149    bool operator()(const _Tp&, const _Up&)
1150    {
1151        return false;
1152    }
1153};
1154
1155template <class ..._Tp, class ..._Up>
1156inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1157bool
1158operator<(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1159{
1160    return __tuple_less<sizeof...(_Tp)>()(__x, __y);
1161}
1162
1163template <class ..._Tp, class ..._Up>
1164inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1165bool
1166operator>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1167{
1168    return __y < __x;
1169}
1170
1171template <class ..._Tp, class ..._Up>
1172inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1173bool
1174operator>=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1175{
1176    return !(__x < __y);
1177}
1178
1179template <class ..._Tp, class ..._Up>
1180inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1181bool
1182operator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
1183{
1184    return !(__y < __x);
1185}
1186
1187// tuple_cat
1188
1189template <class _Tp, class _Up> struct __tuple_cat_type;
1190
1191template <class ..._Ttypes, class ..._Utypes>
1192struct __tuple_cat_type<tuple<_Ttypes...>, __tuple_types<_Utypes...> >
1193{
1194    typedef tuple<_Ttypes..., _Utypes...> type;
1195};
1196
1197template <class _ResultTuple, bool _Is_Tuple0TupleLike, class ..._Tuples>
1198struct __tuple_cat_return_1
1199{
1200};
1201
1202template <class ..._Types, class _Tuple0>
1203struct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0>
1204{
1205    typedef typename __tuple_cat_type<tuple<_Types...>,
1206            typename __make_tuple_types<typename remove_reference<_Tuple0>::type>::type>::type
1207                                                                           type;
1208};
1209
1210template <class ..._Types, class _Tuple0, class _Tuple1, class ..._Tuples>
1211struct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0, _Tuple1, _Tuples...>
1212    : public __tuple_cat_return_1<
1213                 typename __tuple_cat_type<
1214                     tuple<_Types...>,
1215                     typename __make_tuple_types<typename remove_reference<_Tuple0>::type>::type
1216                 >::type,
1217                 __tuple_like<typename remove_reference<_Tuple1>::type>::value,
1218                 _Tuple1, _Tuples...>
1219{
1220};
1221
1222template <class ..._Tuples> struct __tuple_cat_return;
1223
1224template <class _Tuple0, class ..._Tuples>
1225struct __tuple_cat_return<_Tuple0, _Tuples...>
1226    : public __tuple_cat_return_1<tuple<>,
1227         __tuple_like<typename remove_reference<_Tuple0>::type>::value, _Tuple0,
1228                                                                     _Tuples...>
1229{
1230};
1231
1232template <>
1233struct __tuple_cat_return<>
1234{
1235    typedef tuple<> type;
1236};
1237
1238inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1239tuple<>
1240tuple_cat()
1241{
1242    return tuple<>();
1243}
1244
1245template <class _Rp, class _Indices, class _Tuple0, class ..._Tuples>
1246struct __tuple_cat_return_ref_imp;
1247
1248template <class ..._Types, size_t ..._I0, class _Tuple0>
1249struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, _Tuple0>
1250{
1251    typedef typename remove_reference<_Tuple0>::type _T0;
1252    typedef tuple<_Types..., typename __apply_cv<_Tuple0,
1253                          typename tuple_element<_I0, _T0>::type>::type&&...> type;
1254};
1255
1256template <class ..._Types, size_t ..._I0, class _Tuple0, class _Tuple1, class ..._Tuples>
1257struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>,
1258                                  _Tuple0, _Tuple1, _Tuples...>
1259    : public __tuple_cat_return_ref_imp<
1260         tuple<_Types..., typename __apply_cv<_Tuple0,
1261               typename tuple_element<_I0,
1262                  typename remove_reference<_Tuple0>::type>::type>::type&&...>,
1263         typename __make_tuple_indices<tuple_size<typename
1264                                 remove_reference<_Tuple1>::type>::value>::type,
1265         _Tuple1, _Tuples...>
1266{
1267};
1268
1269template <class _Tuple0, class ..._Tuples>
1270struct __tuple_cat_return_ref
1271    : public __tuple_cat_return_ref_imp<tuple<>,
1272               typename __make_tuple_indices<
1273                        tuple_size<typename remove_reference<_Tuple0>::type>::value
1274               >::type, _Tuple0, _Tuples...>
1275{
1276};
1277
1278template <class _Types, class _I0, class _J0>
1279struct __tuple_cat;
1280
1281template <class ..._Types, size_t ..._I0, size_t ..._J0>
1282struct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J0...> >
1283{
1284    template <class _Tuple0>
1285    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1286    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&>::type
1287    operator()(tuple<_Types...> __t, _Tuple0&& __t0)
1288    {
1289        return forward_as_tuple(_VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
1290                                      _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...);
1291    }
1292
1293    template <class _Tuple0, class _Tuple1, class ..._Tuples>
1294    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1295    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&, _Tuple1&&, _Tuples&&...>::type
1296    operator()(tuple<_Types...> __t, _Tuple0&& __t0, _Tuple1&& __t1, _Tuples&& ...__tpls)
1297    {
1298        typedef typename remove_reference<_Tuple0>::type _T0;
1299        typedef typename remove_reference<_Tuple1>::type _T1;
1300        return __tuple_cat<
1301           tuple<_Types..., typename __apply_cv<_Tuple0, typename tuple_element<_J0, _T0>::type>::type&&...>,
1302           typename __make_tuple_indices<sizeof ...(_Types) + tuple_size<_T0>::value>::type,
1303           typename __make_tuple_indices<tuple_size<_T1>::value>::type>()
1304                           (forward_as_tuple(
1305                              _VSTD::forward<_Types>(_VSTD::get<_I0>(__t))...,
1306                              _VSTD::get<_J0>(_VSTD::forward<_Tuple0>(__t0))...
1307                            ),
1308                            _VSTD::forward<_Tuple1>(__t1),
1309                            _VSTD::forward<_Tuples>(__tpls)...);
1310    }
1311};
1312
1313template <class _Tuple0, class... _Tuples>
1314inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
1315typename __tuple_cat_return<_Tuple0, _Tuples...>::type
1316tuple_cat(_Tuple0&& __t0, _Tuples&&... __tpls)
1317{
1318    typedef typename remove_reference<_Tuple0>::type _T0;
1319    return __tuple_cat<tuple<>, __tuple_indices<>,
1320                  typename __make_tuple_indices<tuple_size<_T0>::value>::type>()
1321                  (tuple<>(), _VSTD::forward<_Tuple0>(__t0),
1322                                            _VSTD::forward<_Tuples>(__tpls)...);
1323}
1324
1325template <class ..._Tp, class _Alloc>
1326struct _LIBCPP_TYPE_VIS_ONLY uses_allocator<tuple<_Tp...>, _Alloc>
1327    : true_type {};
1328
1329#endif // _LIBCPP_HAS_NO_VARIADICS
1330
1331#ifndef _LIBCPP_CXX03_LANG
1332template <class _T1, class _T2>
1333template <class... _Args1, class... _Args2, size_t ..._I1, size_t ..._I2>
1334inline _LIBCPP_INLINE_VISIBILITY
1335pair<_T1, _T2>::pair(piecewise_construct_t,
1336                     tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,
1337                     __tuple_indices<_I1...>, __tuple_indices<_I2...>)
1338    :  first(_VSTD::forward<_Args1>(_VSTD::get<_I1>( __first_args))...),
1339      second(_VSTD::forward<_Args2>(_VSTD::get<_I2>(__second_args))...)
1340{
1341}
1342#endif // _LIBCPP_CXX03_LANG
1343
1344#if _LIBCPP_STD_VER > 14
1345template <class _Tp>
1346constexpr size_t tuple_size_v = tuple_size<_Tp>::value;
1347
1348#define _LIBCPP_NOEXCEPT_RETURN(...) noexcept(noexcept(__VA_ARGS__)) { return __VA_ARGS__; }
1349
1350template <class _Fn, class _Tuple, size_t ..._Id>
1351inline _LIBCPP_INLINE_VISIBILITY
1352constexpr decltype(auto) __apply_tuple_impl(_Fn && __f, _Tuple && __t,
1353                                            __tuple_indices<_Id...>)
1354_LIBCPP_NOEXCEPT_RETURN(
1355    _VSTD::__invoke_constexpr(
1356        _VSTD::forward<_Fn>(__f),
1357        _VSTD::get<_Id>(_VSTD::forward<_Tuple>(__t))...)
1358)
1359
1360template <class _Fn, class _Tuple>
1361inline _LIBCPP_INLINE_VISIBILITY
1362constexpr decltype(auto) apply(_Fn && __f, _Tuple && __t)
1363_LIBCPP_NOEXCEPT_RETURN(
1364    _VSTD::__apply_tuple_impl(
1365        _VSTD::forward<_Fn>(__f), _VSTD::forward<_Tuple>(__t),
1366        typename __make_tuple_indices<tuple_size_v<decay_t<_Tuple>>>::type{})
1367)
1368
1369template <class _Tp, class _Tuple, size_t... _Idx>
1370inline _LIBCPP_INLINE_VISIBILITY
1371constexpr _Tp __make_from_tuple_impl(_Tuple&& __t, __tuple_indices<_Idx...>)
1372_LIBCPP_NOEXCEPT_RETURN(
1373    _Tp(_VSTD::get<_Idx>(_VSTD::forward<_Tuple>(__t))...)
1374)
1375
1376template <class _Tp, class _Tuple>
1377inline _LIBCPP_INLINE_VISIBILITY
1378constexpr _Tp make_from_tuple(_Tuple&& __t)
1379_LIBCPP_NOEXCEPT_RETURN(
1380    _VSTD::__make_from_tuple_impl<_Tp>(_VSTD::forward<_Tuple>(__t),
1381        typename __make_tuple_indices<tuple_size_v<decay_t<_Tuple>>>::type{})
1382)
1383
1384#undef _LIBCPP_NOEXCEPT_RETURN
1385
1386#endif // _LIBCPP_STD_VER > 14
1387
1388_LIBCPP_END_NAMESPACE_STD
1389
1390#endif  // _LIBCPP_TUPLE
1391