tuple revision 241903
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&...);
25    template <class... U>
26        explicit tuple(U&&...);
27    tuple(const tuple&) = default;
28    tuple(tuple&&) = default;
29    template <class... U>
30        tuple(const tuple<U...>&);
31    template <class... U>
32        tuple(tuple<U...>&&);
33    template <class U1, class U2>
34        tuple(const pair<U1, U2>&); // iff sizeof...(T) == 2
35    template <class U1, class U2>
36        tuple(pair<U1, U2>&&); // iff sizeof...(T) == 2
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&&...);
76template <class... T> tuple<ATypes...> forward_as_tuple(T&&...) noexcept;
77template <class... T> tuple<T&...> tie(T&...) noexcept;
78template <class... Tuples> tuple<CTypes...> tuple_cat(Tuples&&... tpls);
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 <intsize_t I, class T> class tuple_element; // undefined
84template <intsize_t I, class... T> class tuple_element<I, tuple<T...>>;
85
86// 20.4.1.5, element access:
87template <intsize_t I, class... T>
88    typename tuple_element<I, tuple<T...>>::type&
89    get(tuple<T...>&) noexcept;
90template <intsize_t I, class... T>
91    typename tuple_element<I, tuple<T...>>::type const&
92    get(const tuple<T...>&) noexcept;
93template <intsize_t I, class... T>
94    typename tuple_element<I, tuple<T...>>::type&&
95    get(tuple<T...>&&) noexcept;
96
97// 20.4.1.6, relational operators:
98template<class... T, class... U> bool operator==(const tuple<T...>&, const tuple<U...>&);
99template<class... T, class... U> bool operator<(const tuple<T...>&, const tuple<U...>&);
100template<class... T, class... U> bool operator!=(const tuple<T...>&, const tuple<U...>&);
101template<class... T, class... U> bool operator>(const tuple<T...>&, const tuple<U...>&);
102template<class... T, class... U> bool operator<=(const tuple<T...>&, const tuple<U...>&);
103template<class... T, class... U> bool operator>=(const tuple<T...>&, const tuple<U...>&);
104
105template <class... Types, class Alloc>
106  struct uses_allocator<tuple<Types...>, Alloc>;
107
108template <class... Types>
109  void
110  swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(noexcept(x.swap(y)));
111
112}  // std
113
114*/
115
116#include <__config>
117#include <__tuple>
118#include <cstddef>
119#include <type_traits>
120#include <__functional_base>
121#include <utility>
122
123#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
124#pragma GCC system_header
125#endif
126
127_LIBCPP_BEGIN_NAMESPACE_STD
128
129// allocator_arg_t
130
131struct _LIBCPP_VISIBLE allocator_arg_t { };
132
133#if defined(_LIBCPP_HAS_NO_CONSTEXPR) || defined(_LIBCPP_BUILDING_MEMORY)
134extern const allocator_arg_t allocator_arg;
135#else
136constexpr allocator_arg_t allocator_arg = allocator_arg_t();
137#endif
138
139// uses_allocator
140
141template <class _Tp>
142struct __has_allocator_type
143{
144private:
145    struct __two {char _; char __;};
146    template <class _Up> static __two __test(...);
147    template <class _Up> static char __test(typename _Up::allocator_type* = 0);
148public:
149    static const bool value = sizeof(__test<_Tp>(0)) == 1;
150};
151
152template <class _Tp, class _Alloc, bool = __has_allocator_type<_Tp>::value>
153struct __uses_allocator
154    : public integral_constant<bool,
155        is_convertible<_Alloc, typename _Tp::allocator_type>::value>
156{
157};
158
159template <class _Tp, class _Alloc>
160struct __uses_allocator<_Tp, _Alloc, false>
161    : public false_type
162{
163};
164
165template <class _Tp, class _Alloc>
166struct _LIBCPP_VISIBLE uses_allocator
167    : public __uses_allocator<_Tp, _Alloc>
168{
169};
170
171#ifndef _LIBCPP_HAS_NO_VARIADICS
172
173// uses-allocator construction
174
175template <class _Tp, class _Alloc, class ..._Args>
176struct __uses_alloc_ctor_imp
177{
178    static const bool __ua = uses_allocator<_Tp, _Alloc>::value;
179    static const bool __ic =
180        is_constructible<_Tp, allocator_arg_t, _Alloc, _Args...>::value;
181    static const int value = __ua ? 2 - __ic : 0;
182};
183
184template <class _Tp, class _Alloc, class ..._Args>
185struct __uses_alloc_ctor
186    : integral_constant<int, __uses_alloc_ctor_imp<_Tp, _Alloc, _Args...>::value>
187    {};
188
189#endif  // _LIBCPP_HAS_NO_VARIADICS
190
191#ifndef _LIBCPP_HAS_NO_VARIADICS
192
193// tuple_size
194
195template <class ..._Tp>
196class _LIBCPP_VISIBLE tuple_size<tuple<_Tp...> >
197    : public integral_constant<size_t, sizeof...(_Tp)>
198{
199};
200
201// tuple_element
202
203template <size_t _Ip, class ..._Tp>
204class _LIBCPP_VISIBLE tuple_element<_Ip, tuple<_Tp...> >
205{
206public:
207    typedef typename tuple_element<_Ip, __tuple_types<_Tp...> >::type type;
208};
209
210// __tuple_leaf
211
212template <size_t _Ip, class _Hp, bool=is_empty<_Hp>::value
213#if __has_feature(is_final)
214                                 && !__is_final(_Hp)
215#endif
216         >
217class __tuple_leaf;
218
219template <size_t _Ip, class _Hp, bool _Ep>
220inline _LIBCPP_INLINE_VISIBILITY
221void swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y)
222    _NOEXCEPT_(__is_nothrow_swappable<_Hp>::value)
223{
224    swap(__x.get(), __y.get());
225}
226
227template <size_t _Ip, class _Hp, bool>
228class __tuple_leaf
229{
230    _Hp value;
231
232    __tuple_leaf& operator=(const __tuple_leaf&);
233public:
234    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __tuple_leaf()
235             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) : value()
236       {static_assert(!is_reference<_Hp>::value,
237              "Attempted to default construct a reference element in a tuple");}
238
239    template <class _Alloc>
240        _LIBCPP_INLINE_VISIBILITY
241        __tuple_leaf(integral_constant<int, 0>, const _Alloc&)
242            : value()
243        {static_assert(!is_reference<_Hp>::value,
244              "Attempted to default construct a reference element in a tuple");}
245
246    template <class _Alloc>
247        _LIBCPP_INLINE_VISIBILITY
248        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
249            : value(allocator_arg_t(), __a)
250        {static_assert(!is_reference<_Hp>::value,
251              "Attempted to default construct a reference element in a tuple");}
252
253    template <class _Alloc>
254        _LIBCPP_INLINE_VISIBILITY
255        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
256            : value(__a)
257        {static_assert(!is_reference<_Hp>::value,
258              "Attempted to default construct a reference element in a tuple");}
259
260    template <class _Tp,
261              class = typename enable_if<is_constructible<_Hp, _Tp>::value>::type>
262        _LIBCPP_INLINE_VISIBILITY
263        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
264            : value(_VSTD::forward<_Tp>(__t))
265        {static_assert(!is_reference<_Hp>::value ||
266                       (is_lvalue_reference<_Hp>::value &&
267                        (is_lvalue_reference<_Tp>::value ||
268                         is_same<typename remove_reference<_Tp>::type,
269                                 reference_wrapper<
270                                    typename remove_reference<_Hp>::type
271                                 >
272                                >::value)) ||
273                        (is_rvalue_reference<_Hp>::value &&
274                         !is_lvalue_reference<_Tp>::value),
275       "Attempted to construct a reference element in a tuple with an rvalue");}
276
277    template <class _Tp, class _Alloc>
278        _LIBCPP_INLINE_VISIBILITY
279        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
280            : value(_VSTD::forward<_Tp>(__t))
281        {static_assert(!is_lvalue_reference<_Hp>::value ||
282                       (is_lvalue_reference<_Hp>::value &&
283                        (is_lvalue_reference<_Tp>::value ||
284                         is_same<typename remove_reference<_Tp>::type,
285                                 reference_wrapper<
286                                    typename remove_reference<_Hp>::type
287                                 >
288                                >::value)),
289       "Attempted to construct a reference element in a tuple with an rvalue");}
290
291    template <class _Tp, class _Alloc>
292        _LIBCPP_INLINE_VISIBILITY
293        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
294            : value(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t))
295        {static_assert(!is_lvalue_reference<_Hp>::value ||
296                       (is_lvalue_reference<_Hp>::value &&
297                        (is_lvalue_reference<_Tp>::value ||
298                         is_same<typename remove_reference<_Tp>::type,
299                                 reference_wrapper<
300                                    typename remove_reference<_Hp>::type
301                                 >
302                                >::value)),
303       "Attempted to construct a reference element in a tuple with an rvalue");}
304
305    template <class _Tp, class _Alloc>
306        _LIBCPP_INLINE_VISIBILITY
307        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
308            : value(_VSTD::forward<_Tp>(__t), __a)
309        {static_assert(!is_lvalue_reference<_Hp>::value ||
310                       (is_lvalue_reference<_Hp>::value &&
311                        (is_lvalue_reference<_Tp>::value ||
312                         is_same<typename remove_reference<_Tp>::type,
313                                 reference_wrapper<
314                                    typename remove_reference<_Hp>::type
315                                 >
316                                >::value)),
317       "Attempted to construct a reference element in a tuple with an rvalue");}
318
319    __tuple_leaf(const __tuple_leaf& __t) _NOEXCEPT_(is_nothrow_copy_constructible<_Hp>::value)
320        : value(__t.get())
321        {static_assert(!is_rvalue_reference<_Hp>::value, "Can not copy a tuple with rvalue reference member");}
322
323    template <class _Tp>
324        _LIBCPP_INLINE_VISIBILITY
325        explicit __tuple_leaf(const __tuple_leaf<_Ip, _Tp>& __t)
326                           _NOEXCEPT_((is_nothrow_constructible<_Hp, const _Tp&>::value))
327            : value(__t.get()) {}
328
329    template <class _Tp>
330        _LIBCPP_INLINE_VISIBILITY
331        __tuple_leaf&
332        operator=(_Tp&& __t) _NOEXCEPT_((is_nothrow_assignable<_Hp&, _Tp>::value))
333        {
334            value = _VSTD::forward<_Tp>(__t);
335            return *this;
336        }
337
338    _LIBCPP_INLINE_VISIBILITY
339    int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
340    {
341        _VSTD::swap(*this, __t);
342        return 0;
343    }
344
345    _LIBCPP_INLINE_VISIBILITY       _Hp& get()       _NOEXCEPT {return value;}
346    _LIBCPP_INLINE_VISIBILITY const _Hp& get() const _NOEXCEPT {return value;}
347};
348
349template <size_t _Ip, class _Hp>
350class __tuple_leaf<_Ip, _Hp, true>
351    : private _Hp
352{
353
354    __tuple_leaf& operator=(const __tuple_leaf&);
355public:
356    _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR __tuple_leaf()
357             _NOEXCEPT_(is_nothrow_default_constructible<_Hp>::value) {}
358
359    template <class _Alloc>
360        _LIBCPP_INLINE_VISIBILITY
361        __tuple_leaf(integral_constant<int, 0>, const _Alloc&) {}
362
363    template <class _Alloc>
364        _LIBCPP_INLINE_VISIBILITY
365        __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
366            : _Hp(allocator_arg_t(), __a) {}
367
368    template <class _Alloc>
369        _LIBCPP_INLINE_VISIBILITY
370        __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
371            : _Hp(__a) {}
372
373    template <class _Tp,
374              class = typename enable_if<is_constructible<_Hp, _Tp>::value>::type>
375        _LIBCPP_INLINE_VISIBILITY
376        explicit __tuple_leaf(_Tp&& __t) _NOEXCEPT_((is_nothrow_constructible<_Hp, _Tp>::value))
377            : _Hp(_VSTD::forward<_Tp>(__t)) {}
378
379    template <class _Tp, class _Alloc>
380        _LIBCPP_INLINE_VISIBILITY
381        explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
382            : _Hp(_VSTD::forward<_Tp>(__t)) {}
383
384    template <class _Tp, class _Alloc>
385        _LIBCPP_INLINE_VISIBILITY
386        explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
387            : _Hp(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) {}
388
389    template <class _Tp, class _Alloc>
390        _LIBCPP_INLINE_VISIBILITY
391        explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
392            : _Hp(_VSTD::forward<_Tp>(__t), __a) {}
393
394    template <class _Tp>
395        _LIBCPP_INLINE_VISIBILITY
396        explicit __tuple_leaf(const __tuple_leaf<_Ip, _Tp>& __t)
397            _NOEXCEPT_((is_nothrow_constructible<_Hp, const _Tp&>::value))
398            : _Hp(__t.get()) {}
399
400    template <class _Tp>
401        _LIBCPP_INLINE_VISIBILITY
402        __tuple_leaf&
403        operator=(_Tp&& __t) _NOEXCEPT_((is_nothrow_assignable<_Hp&, _Tp>::value))
404        {
405            _Hp::operator=(_VSTD::forward<_Tp>(__t));
406            return *this;
407        }
408
409    _LIBCPP_INLINE_VISIBILITY
410    int
411    swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
412    {
413        _VSTD::swap(*this, __t);
414        return 0;
415    }
416
417    _LIBCPP_INLINE_VISIBILITY       _Hp& get()       _NOEXCEPT {return static_cast<_Hp&>(*this);}
418    _LIBCPP_INLINE_VISIBILITY const _Hp& get() const _NOEXCEPT {return static_cast<const _Hp&>(*this);}
419};
420
421template <class ..._Tp>
422_LIBCPP_INLINE_VISIBILITY
423void __swallow(_Tp&&...) _NOEXCEPT {}
424
425template <bool ...> struct __all;
426
427template <>
428struct __all<>
429{
430    static const bool value = true;
431};
432
433template <bool _B0, bool ... _Bp>
434struct __all<_B0, _Bp...>
435{
436    static const bool value = _B0 && __all<_Bp...>::value;
437};
438
439// __tuple_impl
440
441template<class _Indx, class ..._Tp> struct __tuple_impl;
442
443template<size_t ..._Indx, class ..._Tp>
444struct __tuple_impl<__tuple_indices<_Indx...>, _Tp...>
445    : public __tuple_leaf<_Indx, _Tp>...
446{
447    _LIBCPP_INLINE_VISIBILITY
448    _LIBCPP_CONSTEXPR __tuple_impl()
449        _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
450
451    template <size_t ..._Uf, class ..._Tf,
452              size_t ..._Ul, class ..._Tl, class ..._Up>
453        _LIBCPP_INLINE_VISIBILITY
454        explicit
455        __tuple_impl(__tuple_indices<_Uf...>, __tuple_types<_Tf...>,
456                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
457                     _Up&&... __u)
458                     _NOEXCEPT_((__all<is_nothrow_constructible<_Tf, _Up>::value...>::value &&
459                                 __all<is_nothrow_default_constructible<_Tl>::value...>::value)) :
460            __tuple_leaf<_Uf, _Tf>(_VSTD::forward<_Up>(__u))...,
461            __tuple_leaf<_Ul, _Tl>()...
462            {}
463
464    template <class _Alloc, size_t ..._Uf, class ..._Tf,
465              size_t ..._Ul, class ..._Tl, class ..._Up>
466        _LIBCPP_INLINE_VISIBILITY
467        explicit
468        __tuple_impl(allocator_arg_t, const _Alloc& __a,
469                     __tuple_indices<_Uf...>, __tuple_types<_Tf...>,
470                     __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
471                     _Up&&... __u) :
472            __tuple_leaf<_Uf, _Tf>(__uses_alloc_ctor<_Tf, _Alloc, _Up>(), __a,
473            _VSTD::forward<_Up>(__u))...,
474            __tuple_leaf<_Ul, _Tl>(__uses_alloc_ctor<_Tl, _Alloc>(), __a)...
475            {}
476
477    template <class _Tuple,
478              class = typename enable_if
479                      <
480                         __tuple_convertible<_Tuple, tuple<_Tp...> >::value
481                      >::type
482             >
483        _LIBCPP_INLINE_VISIBILITY
484        __tuple_impl(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_constructible<_Tp, typename tuple_element<_Indx,
485                                       typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))
486            : __tuple_leaf<_Indx, _Tp>(_VSTD::forward<typename tuple_element<_Indx,
487                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
488            {}
489
490    template <class _Alloc, class _Tuple,
491              class = typename enable_if
492                      <
493                         __tuple_convertible<_Tuple, tuple<_Tp...> >::value
494                      >::type
495             >
496        _LIBCPP_INLINE_VISIBILITY
497        __tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
498            : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, typename tuple_element<_Indx,
499                                       typename __make_tuple_types<_Tuple>::type>::type>(), __a,
500                                       _VSTD::forward<typename tuple_element<_Indx,
501                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
502            {}
503
504    template <class _Tuple>
505        _LIBCPP_INLINE_VISIBILITY
506        typename enable_if
507        <
508            __tuple_assignable<_Tuple, tuple<_Tp...> >::value,
509            __tuple_impl&
510        >::type
511        operator=(_Tuple&& __t) _NOEXCEPT_((__all<is_nothrow_assignable<_Tp&, typename tuple_element<_Indx,
512                                       typename __make_tuple_types<_Tuple>::type>::type>::value...>::value))
513        {
514            __swallow(__tuple_leaf<_Indx, _Tp>::operator=(_VSTD::forward<typename tuple_element<_Indx,
515                                       typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...);
516            return *this;
517        }
518
519        _LIBCPP_INLINE_VISIBILITY
520        __tuple_impl&
521        operator=(const __tuple_impl& __t) _NOEXCEPT_((__all<is_nothrow_copy_assignable<_Tp>::value...>::value))
522        {
523            __swallow(__tuple_leaf<_Indx, _Tp>::operator=(static_cast<const __tuple_leaf<_Indx, _Tp>&>(__t).get())...);
524            return *this;
525        }
526
527    _LIBCPP_INLINE_VISIBILITY
528    void swap(__tuple_impl& __t)
529        _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
530    {
531        __swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...);
532    }
533};
534
535template <class ..._Tp>
536class _LIBCPP_VISIBLE tuple
537{
538    typedef __tuple_impl<typename __make_tuple_indices<sizeof...(_Tp)>::type, _Tp...> base;
539
540    base base_;
541
542    template <size_t _Jp, class ..._Up> friend
543        typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT;
544    template <size_t _Jp, class ..._Up> friend
545        const typename tuple_element<_Jp, tuple<_Up...> >::type& get(const tuple<_Up...>&) _NOEXCEPT;
546    template <size_t _Jp, class ..._Up> friend
547        typename tuple_element<_Jp, tuple<_Up...> >::type&& get(tuple<_Up...>&&) _NOEXCEPT;
548public:
549
550    _LIBCPP_INLINE_VISIBILITY
551    _LIBCPP_CONSTEXPR tuple()
552        _NOEXCEPT_(__all<is_nothrow_default_constructible<_Tp>::value...>::value) {}
553
554    _LIBCPP_INLINE_VISIBILITY
555    explicit tuple(const _Tp& ... __t) _NOEXCEPT_((__all<is_nothrow_copy_constructible<_Tp>::value...>::value)) 
556        : base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
557                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
558                typename __make_tuple_indices<0>::type(),
559                typename __make_tuple_types<tuple, 0>::type(),
560                __t...
561               ) {}
562
563    template <class _Alloc>
564      _LIBCPP_INLINE_VISIBILITY
565      tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
566        : base_(allocator_arg_t(), __a,
567                typename __make_tuple_indices<sizeof...(_Tp)>::type(),
568                typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
569                typename __make_tuple_indices<0>::type(),
570                typename __make_tuple_types<tuple, 0>::type(),
571                __t...
572               ) {}
573
574    template <class ..._Up,
575              typename enable_if
576                      <
577                         sizeof...(_Up) <= sizeof...(_Tp) &&
578                         __tuple_convertible
579                         <
580                            tuple<_Up...>,
581                            typename __make_tuple_types<tuple,
582                                     sizeof...(_Up) < sizeof...(_Tp) ?
583                                        sizeof...(_Up) :
584                                        sizeof...(_Tp)>::type
585                         >::value,
586                         bool
587                      >::type = false
588             >
589        _LIBCPP_INLINE_VISIBILITY
590        tuple(_Up&&... __u)
591            _NOEXCEPT_((
592                is_nothrow_constructible<
593                    typename __make_tuple_indices<sizeof...(_Up)>::type,
594                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type,
595                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type,
596                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type,
597                    _Up...
598                >::value
599            ))
600            : base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
601                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
602                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
603                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
604                    _VSTD::forward<_Up>(__u)...) {}
605
606    template <class ..._Up,
607              typename enable_if
608                      <
609                         sizeof...(_Up) <= sizeof...(_Tp) &&
610                         __tuple_constructible
611                         <
612                            tuple<_Up...>,
613                            typename __make_tuple_types<tuple,
614                                     sizeof...(_Up) < sizeof...(_Tp) ?
615                                        sizeof...(_Up) :
616                                        sizeof...(_Tp)>::type
617                         >::value &&
618                         !__tuple_convertible
619                         <
620                            tuple<_Up...>,
621                            typename __make_tuple_types<tuple,
622                                     sizeof...(_Up) < sizeof...(_Tp) ?
623                                        sizeof...(_Up) :
624                                        sizeof...(_Tp)>::type
625                         >::value,
626                         bool
627                      >::type =false
628             >
629        _LIBCPP_INLINE_VISIBILITY
630        explicit
631        tuple(_Up&&... __u)
632            _NOEXCEPT_((
633                is_nothrow_constructible<
634                    typename __make_tuple_indices<sizeof...(_Up)>::type,
635                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type,
636                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type,
637                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type,
638                    _Up...
639                >::value
640            ))
641            : base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
642                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
643                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
644                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
645                    _VSTD::forward<_Up>(__u)...) {}
646
647    template <class _Alloc, class ..._Up,
648              class = typename enable_if
649                      <
650                         sizeof...(_Up) <= sizeof...(_Tp) &&
651                         __tuple_convertible
652                         <
653                            tuple<_Up...>,
654                            typename __make_tuple_types<tuple,
655                                     sizeof...(_Up) < sizeof...(_Tp) ?
656                                        sizeof...(_Up) :
657                                        sizeof...(_Tp)>::type
658                         >::value
659                      >::type
660             >
661        _LIBCPP_INLINE_VISIBILITY
662        tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
663            : base_(allocator_arg_t(), __a,
664                    typename __make_tuple_indices<sizeof...(_Up)>::type(),
665                    typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
666                    typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
667                    typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
668                    _VSTD::forward<_Up>(__u)...) {}
669
670    template <class _Tuple,
671              typename enable_if
672                      <
673                         __tuple_convertible<_Tuple, tuple>::value,
674                         bool
675                      >::type = false
676             >
677        _LIBCPP_INLINE_VISIBILITY
678        tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<base, _Tuple>::value))
679            : base_(_VSTD::forward<_Tuple>(__t)) {}
680
681    template <class _Tuple,
682              typename enable_if
683                      <
684                         __tuple_constructible<_Tuple, tuple>::value &&
685                         !__tuple_convertible<_Tuple, tuple>::value,
686                         bool
687                      >::type = false
688             >
689        _LIBCPP_INLINE_VISIBILITY
690        explicit
691        tuple(_Tuple&& __t) _NOEXCEPT_((is_nothrow_constructible<base, _Tuple>::value))
692            : base_(_VSTD::forward<_Tuple>(__t)) {}
693
694    template <class _Alloc, class _Tuple,
695              class = typename enable_if
696                      <
697                         __tuple_convertible<_Tuple, tuple>::value
698                      >::type
699             >
700        _LIBCPP_INLINE_VISIBILITY
701        tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
702            : base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {}
703
704    template <class _Tuple,
705              class = typename enable_if
706                      <
707                         __tuple_assignable<_Tuple, tuple>::value
708                      >::type
709             >
710        _LIBCPP_INLINE_VISIBILITY
711        tuple&
712        operator=(_Tuple&& __t) _NOEXCEPT_((is_nothrow_assignable<base&, _Tuple>::value))
713        {
714            base_.operator=(_VSTD::forward<_Tuple>(__t));
715            return *this;
716        }
717
718    _LIBCPP_INLINE_VISIBILITY
719    void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
720        {base_.swap(__t.base_);}
721};
722
723template <>
724class _LIBCPP_VISIBLE tuple<>
725{
726public:
727    _LIBCPP_INLINE_VISIBILITY
728    _LIBCPP_CONSTEXPR tuple() _NOEXCEPT {}
729    template <class _Alloc>
730    _LIBCPP_INLINE_VISIBILITY
731        tuple(allocator_arg_t, const _Alloc&) _NOEXCEPT {}
732    template <class _Alloc>
733    _LIBCPP_INLINE_VISIBILITY
734        tuple(allocator_arg_t, const _Alloc&, const tuple&) _NOEXCEPT {}
735    template <class _Up>
736    _LIBCPP_INLINE_VISIBILITY
737        tuple(array<_Up, 0>) _NOEXCEPT {}
738    template <class _Alloc, class _Up>
739    _LIBCPP_INLINE_VISIBILITY
740        tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) _NOEXCEPT {}
741    _LIBCPP_INLINE_VISIBILITY
742    void swap(tuple&) _NOEXCEPT {}
743};
744
745template <class ..._Tp>
746inline _LIBCPP_INLINE_VISIBILITY
747typename enable_if
748<
749    __all<__is_swappable<_Tp>::value...>::value,
750    void
751>::type
752swap(tuple<_Tp...>& __t, tuple<_Tp...>& __u)
753                 _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
754    {__t.swap(__u);}
755
756// get
757
758template <size_t _Ip, class ..._Tp>
759inline _LIBCPP_INLINE_VISIBILITY
760typename tuple_element<_Ip, tuple<_Tp...> >::type&
761get(tuple<_Tp...>& __t) _NOEXCEPT
762{
763    typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
764    return static_cast<__tuple_leaf<_Ip, type>&>(__t.base_).get();
765}
766
767template <size_t _Ip, class ..._Tp>
768inline _LIBCPP_INLINE_VISIBILITY
769const typename tuple_element<_Ip, tuple<_Tp...> >::type&
770get(const tuple<_Tp...>& __t) _NOEXCEPT
771{
772    typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
773    return static_cast<const __tuple_leaf<_Ip, type>&>(__t.base_).get();
774}
775
776template <size_t _Ip, class ..._Tp>
777inline _LIBCPP_INLINE_VISIBILITY
778typename tuple_element<_Ip, tuple<_Tp...> >::type&&
779get(tuple<_Tp...>&& __t) _NOEXCEPT
780{
781    typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
782    return static_cast<type&&>(
783             static_cast<__tuple_leaf<_Ip, type>&&>(__t.base_).get());
784}
785
786// tie
787
788template <class ..._Tp>
789inline _LIBCPP_INLINE_VISIBILITY
790tuple<_Tp&...>
791tie(_Tp&... __t) _NOEXCEPT
792{
793    return tuple<_Tp&...>(__t...);
794}
795
796template <class _Up>
797struct __ignore_t
798{
799    template <class _Tp>
800        _LIBCPP_INLINE_VISIBILITY
801        const __ignore_t& operator=(_Tp&&) const {return *this;}
802};
803
804namespace { const __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>(); }
805
806template <class _Tp> class _LIBCPP_VISIBLE reference_wrapper;
807
808template <class _Tp>
809struct ___make_tuple_return
810{
811    typedef _Tp type;
812};
813
814template <class _Tp>
815struct ___make_tuple_return<reference_wrapper<_Tp> >
816{
817    typedef _Tp& type;
818};
819
820template <class _Tp>
821struct __make_tuple_return
822{
823    typedef typename ___make_tuple_return<typename decay<_Tp>::type>::type type;
824};
825
826template <class... _Tp>
827inline _LIBCPP_INLINE_VISIBILITY
828tuple<typename __make_tuple_return<_Tp>::type...>
829make_tuple(_Tp&&... __t)
830{
831    return tuple<typename __make_tuple_return<_Tp>::type...>(_VSTD::forward<_Tp>(__t)...);
832}
833
834template <class... _Tp>
835inline _LIBCPP_INLINE_VISIBILITY
836tuple<_Tp&&...>
837forward_as_tuple(_Tp&&... __t) _NOEXCEPT
838{
839    return tuple<_Tp&&...>(_VSTD::forward<_Tp>(__t)...);
840}
841
842template <size_t _Ip>
843struct __tuple_equal
844{
845    template <class _Tp, class _Up>
846    _LIBCPP_INLINE_VISIBILITY
847    bool operator()(const _Tp& __x, const _Up& __y)
848    {
849        return __tuple_equal<_Ip - 1>()(__x, __y) && get<_Ip-1>(__x) == get<_Ip-1>(__y);
850    }
851};
852
853template <>
854struct __tuple_equal<0>
855{
856    template <class _Tp, class _Up>
857    _LIBCPP_INLINE_VISIBILITY
858    bool operator()(const _Tp&, const _Up&)
859    {
860        return true;
861    }
862};
863
864template <class ..._Tp, class ..._Up>
865inline _LIBCPP_INLINE_VISIBILITY
866bool
867operator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
868{
869    return __tuple_equal<sizeof...(_Tp)>()(__x, __y);
870}
871
872template <class ..._Tp, class ..._Up>
873inline _LIBCPP_INLINE_VISIBILITY
874bool
875operator!=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
876{
877    return !(__x == __y);
878}
879
880template <size_t _Ip>
881struct __tuple_less
882{
883    template <class _Tp, class _Up>
884    _LIBCPP_INLINE_VISIBILITY
885    bool operator()(const _Tp& __x, const _Up& __y)
886    {
887        return __tuple_less<_Ip-1>()(__x, __y) ||
888             (!__tuple_less<_Ip-1>()(__y, __x) && get<_Ip-1>(__x) < get<_Ip-1>(__y));
889    }
890};
891
892template <>
893struct __tuple_less<0>
894{
895    template <class _Tp, class _Up>
896    _LIBCPP_INLINE_VISIBILITY
897    bool operator()(const _Tp&, const _Up&)
898    {
899        return false;
900    }
901};
902
903template <class ..._Tp, class ..._Up>
904inline _LIBCPP_INLINE_VISIBILITY
905bool
906operator<(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
907{
908    return __tuple_less<sizeof...(_Tp)>()(__x, __y);
909}
910
911template <class ..._Tp, class ..._Up>
912inline _LIBCPP_INLINE_VISIBILITY
913bool
914operator>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
915{
916    return __y < __x;
917}
918
919template <class ..._Tp, class ..._Up>
920inline _LIBCPP_INLINE_VISIBILITY
921bool
922operator>=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
923{
924    return !(__x < __y);
925}
926
927template <class ..._Tp, class ..._Up>
928inline _LIBCPP_INLINE_VISIBILITY
929bool
930operator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
931{
932    return !(__y < __x);
933}
934
935// tuple_cat
936
937template <class _Tp, class _Up> struct __tuple_cat_type;
938
939template <class ..._Ttypes, class ..._Utypes>
940struct __tuple_cat_type<tuple<_Ttypes...>, __tuple_types<_Utypes...> >
941{
942    typedef tuple<_Ttypes..., _Utypes...> type;
943};
944
945template <class _ResultTuple, bool _Is_Tuple0TupleLike, class ..._Tuples>
946struct __tuple_cat_return_1
947{
948};
949
950template <class ..._Types, class _Tuple0>
951struct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0>
952{
953    typedef typename __tuple_cat_type<tuple<_Types...>,
954            typename __make_tuple_types<typename remove_reference<_Tuple0>::type>::type>::type
955                                                                           type;
956};
957
958template <class ..._Types, class _Tuple0, class _Tuple1, class ..._Tuples>
959struct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0, _Tuple1, _Tuples...>
960    : public __tuple_cat_return_1<
961                 typename __tuple_cat_type<
962                     tuple<_Types...>,
963                     typename __make_tuple_types<typename remove_reference<_Tuple0>::type>::type
964                 >::type,
965                 __tuple_like<typename remove_reference<_Tuple1>::type>::value,
966                 _Tuple1, _Tuples...>
967{
968};
969
970template <class ..._Tuples> struct __tuple_cat_return;
971
972template <class _Tuple0, class ..._Tuples>
973struct __tuple_cat_return<_Tuple0, _Tuples...>
974    : public __tuple_cat_return_1<tuple<>,
975         __tuple_like<typename remove_reference<_Tuple0>::type>::value, _Tuple0,
976                                                                     _Tuples...>
977{
978};
979
980template <>
981struct __tuple_cat_return<>
982{
983    typedef tuple<> type;
984};
985
986inline _LIBCPP_INLINE_VISIBILITY
987tuple<>
988tuple_cat()
989{
990    return tuple<>();
991}
992
993template <class _Rp, class _Indices, class _Tuple0, class ..._Tuples>
994struct __tuple_cat_return_ref_imp;
995
996template <class ..._Types, size_t ..._I0, class _Tuple0>
997struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, _Tuple0>
998{
999    typedef typename remove_reference<_Tuple0>::type _T0;
1000    typedef tuple<_Types..., typename __apply_cv<_Tuple0,
1001                          typename tuple_element<_I0, _T0>::type>::type&&...> type;
1002};
1003
1004template <class ..._Types, size_t ..._I0, class _Tuple0, class _Tuple1, class ..._Tuples>
1005struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>,
1006                                  _Tuple0, _Tuple1, _Tuples...>
1007    : public __tuple_cat_return_ref_imp<
1008         tuple<_Types..., typename __apply_cv<_Tuple0,
1009               typename tuple_element<_I0,
1010                  typename remove_reference<_Tuple0>::type>::type>::type&&...>,
1011         typename __make_tuple_indices<tuple_size<typename
1012                                 remove_reference<_Tuple1>::type>::value>::type,
1013         _Tuple1, _Tuples...>
1014{
1015};
1016
1017template <class _Tuple0, class ..._Tuples>
1018struct __tuple_cat_return_ref
1019    : public __tuple_cat_return_ref_imp<tuple<>,
1020               typename __make_tuple_indices<
1021                        tuple_size<typename remove_reference<_Tuple0>::type>::value
1022               >::type, _Tuple0, _Tuples...>
1023{
1024};
1025
1026template <class _Types, class _I0, class _J0>
1027struct __tuple_cat;
1028
1029template <class ..._Types, size_t ..._I0, size_t ..._J0>
1030struct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J0...> >
1031{
1032    template <class _Tuple0>
1033    _LIBCPP_INLINE_VISIBILITY
1034    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&>::type
1035    operator()(tuple<_Types...> __t, _Tuple0&& __t0)
1036    {
1037        return _VSTD::forward_as_tuple(_VSTD::forward<_Types>(get<_I0>(__t))...,
1038                                      get<_J0>(_VSTD::forward<_Tuple0>(__t0))...);
1039    }
1040
1041    template <class _Tuple0, class _Tuple1, class ..._Tuples>
1042    _LIBCPP_INLINE_VISIBILITY
1043    typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&, _Tuple1&&, _Tuples&&...>::type
1044    operator()(tuple<_Types...> __t, _Tuple0&& __t0, _Tuple1&& __t1, _Tuples&& ...__tpls)
1045    {
1046        typedef typename remove_reference<_Tuple0>::type _T0;
1047        typedef typename remove_reference<_Tuple1>::type _T1;
1048        return __tuple_cat<
1049           tuple<_Types..., typename __apply_cv<_Tuple0, typename tuple_element<_J0, _T0>::type>::type&&...>,
1050           typename __make_tuple_indices<sizeof ...(_Types) + tuple_size<_T0>::value>::type,
1051           typename __make_tuple_indices<tuple_size<_T1>::value>::type>()
1052                           (_VSTD::forward_as_tuple(
1053                              _VSTD::forward<_Types>(get<_I0>(__t))...,
1054                              get<_J0>(_VSTD::forward<_Tuple0>(__t0))...
1055                            ),
1056                            _VSTD::forward<_Tuple1>(__t1),
1057                            _VSTD::forward<_Tuples>(__tpls)...);
1058    }
1059};
1060
1061template <class _Tuple0, class... _Tuples>
1062inline _LIBCPP_INLINE_VISIBILITY
1063typename __tuple_cat_return<_Tuple0, _Tuples...>::type
1064tuple_cat(_Tuple0&& __t0, _Tuples&&... __tpls)
1065{
1066    typedef typename remove_reference<_Tuple0>::type _T0;
1067    return __tuple_cat<tuple<>, __tuple_indices<>,
1068                  typename __make_tuple_indices<tuple_size<_T0>::value>::type>()
1069                  (tuple<>(), _VSTD::forward<_Tuple0>(__t0),
1070                                            _VSTD::forward<_Tuples>(__tpls)...);
1071}
1072
1073template <class ..._Tp, class _Alloc>
1074struct _LIBCPP_VISIBLE uses_allocator<tuple<_Tp...>, _Alloc>
1075    : true_type {};
1076
1077template <class _T1, class _T2>
1078template <class... _Args1, class... _Args2, size_t ..._I1, size_t ..._I2>
1079inline _LIBCPP_INLINE_VISIBILITY
1080pair<_T1, _T2>::pair(piecewise_construct_t,
1081                     tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,
1082                     __tuple_indices<_I1...>, __tuple_indices<_I2...>)
1083    :  first(_VSTD::forward<_Args1>(get<_I1>( __first_args))...),
1084      second(_VSTD::forward<_Args2>(get<_I2>(__second_args))...)
1085{
1086}
1087
1088#endif  // _LIBCPP_HAS_NO_VARIADICS
1089
1090_LIBCPP_END_NAMESPACE_STD
1091
1092#endif  // _LIBCPP_TUPLE
1093