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