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