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