]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/libc++/include/tuple
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / libc++ / include / tuple
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
17 namespace std
18 {
19
20 template <class... T>
21 class tuple {
22 public:
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
73 const unspecified ignore;
74
75 template <class... T> tuple<V...>  make_tuple(T&&...);
76 template <class... T> tuple<ATypes...> forward_as_tuple(T&&...) noexcept;
77 template <class... T> tuple<T&...> tie(T&...) noexcept;
78 template <class... Tuples> tuple<CTypes...> tuple_cat(Tuples&&... tpls);
79   
80 // 20.4.1.4, tuple helper classes:
81 template <class T> class tuple_size; // undefined
82 template <class... T> class tuple_size<tuple<T...>>;
83 template <intsize_t I, class T> class tuple_element; // undefined
84 template <intsize_t I, class... T> class tuple_element<I, tuple<T...>>;
85
86 // 20.4.1.5, element access:
87 template <intsize_t I, class... T>
88     typename tuple_element<I, tuple<T...>>::type&
89     get(tuple<T...>&) noexcept;
90 template <intsize_t I, class... T>
91     typename tuple_element<I, tuple<T...>>::type const&
92     get(const tuple<T...>&) noexcept;
93 template <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:
98 template<class... T, class... U> bool operator==(const tuple<T...>&, const tuple<U...>&);
99 template<class... T, class... U> bool operator<(const tuple<T...>&, const tuple<U...>&);
100 template<class... T, class... U> bool operator!=(const tuple<T...>&, const tuple<U...>&);
101 template<class... T, class... U> bool operator>(const tuple<T...>&, const tuple<U...>&);
102 template<class... T, class... U> bool operator<=(const tuple<T...>&, const tuple<U...>&);
103 template<class... T, class... U> bool operator>=(const tuple<T...>&, const tuple<U...>&);
104
105 template <class... Types, class Alloc>
106   struct uses_allocator<tuple<Types...>, Alloc>;
107
108 template <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
131 struct _LIBCPP_TYPE_VIS allocator_arg_t { };
132
133 #if defined(_LIBCPP_HAS_NO_CONSTEXPR) || defined(_LIBCPP_BUILDING_MEMORY)
134 extern const allocator_arg_t allocator_arg;
135 #else
136 constexpr allocator_arg_t allocator_arg = allocator_arg_t();
137 #endif
138
139 // uses_allocator
140
141 template <class _Tp>
142 struct __has_allocator_type
143 {
144 private:
145     struct __two {char __lx; char __lxx;};
146     template <class _Up> static __two __test(...);
147     template <class _Up> static char __test(typename _Up::allocator_type* = 0);
148 public:
149     static const bool value = sizeof(__test<_Tp>(0)) == 1;
150 };
151
152 template <class _Tp, class _Alloc, bool = __has_allocator_type<_Tp>::value>
153 struct __uses_allocator
154     : public integral_constant<bool,
155         is_convertible<_Alloc, typename _Tp::allocator_type>::value>
156 {
157 };
158
159 template <class _Tp, class _Alloc>
160 struct __uses_allocator<_Tp, _Alloc, false>
161     : public false_type
162 {
163 };
164
165 template <class _Tp, class _Alloc>
166 struct _LIBCPP_TYPE_VIS uses_allocator
167     : public __uses_allocator<_Tp, _Alloc>
168 {
169 };
170
171 #ifndef _LIBCPP_HAS_NO_VARIADICS
172
173 // uses-allocator construction
174
175 template <class _Tp, class _Alloc, class ..._Args>
176 struct __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
184 template <class _Tp, class _Alloc, class ..._Args>
185 struct __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
195 template <class ..._Tp>
196 class _LIBCPP_TYPE_VIS tuple_size<tuple<_Tp...> >
197     : public integral_constant<size_t, sizeof...(_Tp)>
198 {
199 };
200
201 // tuple_element
202
203 template <size_t _Ip, class ..._Tp>
204 class _LIBCPP_TYPE_VIS tuple_element<_Ip, tuple<_Tp...> >
205 {
206 public:
207     typedef typename tuple_element<_Ip, __tuple_types<_Tp...> >::type type;
208 };
209
210 // __tuple_leaf
211
212 template <size_t _Ip, class _Hp, bool=is_empty<_Hp>::value
213 #if __has_feature(is_final)
214                                  && !__is_final(_Hp)
215 #endif
216          >
217 class __tuple_leaf;
218
219 template <size_t _Ip, class _Hp, bool _Ep>
220 inline _LIBCPP_INLINE_VISIBILITY
221 void 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
227 template <size_t _Ip, class _Hp, bool>
228 class __tuple_leaf
229 {
230     _Hp value;
231
232     __tuple_leaf& operator=(const __tuple_leaf&);
233 public:
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
349 template <size_t _Ip, class _Hp>
350 class __tuple_leaf<_Ip, _Hp, true>
351     : private _Hp
352 {
353
354     __tuple_leaf& operator=(const __tuple_leaf&);
355 public:
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
421 template <class ..._Tp>
422 _LIBCPP_INLINE_VISIBILITY
423 void __swallow(_Tp&&...) _NOEXCEPT {}
424
425 template <bool ...> struct __all;
426
427 template <>
428 struct __all<>
429 {
430     static const bool value = true;
431 };
432
433 template <bool _B0, bool ... _Bp>
434 struct __all<_B0, _Bp...>
435 {
436     static const bool value = _B0 && __all<_Bp...>::value;
437 };
438
439 // __tuple_impl
440
441 template<class _Indx, class ..._Tp> struct __tuple_impl;
442
443 template<size_t ..._Indx, class ..._Tp>
444 struct __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_constructible<_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
535 template <class ..._Tp>
536 class _LIBCPP_TYPE_VIS 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;
548 public:
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
723 template <>
724 class _LIBCPP_TYPE_VIS tuple<>
725 {
726 public:
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
745 template <class ..._Tp>
746 inline _LIBCPP_INLINE_VISIBILITY
747 typename enable_if
748 <
749     __all<__is_swappable<_Tp>::value...>::value,
750     void
751 >::type
752 swap(tuple<_Tp...>& __t, tuple<_Tp...>& __u)
753                  _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
754     {__t.swap(__u);}
755
756 // get
757
758 template <size_t _Ip, class ..._Tp>
759 inline _LIBCPP_INLINE_VISIBILITY
760 typename tuple_element<_Ip, tuple<_Tp...> >::type&
761 get(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
767 template <size_t _Ip, class ..._Tp>
768 inline _LIBCPP_INLINE_VISIBILITY
769 const typename tuple_element<_Ip, tuple<_Tp...> >::type&
770 get(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
776 template <size_t _Ip, class ..._Tp>
777 inline _LIBCPP_INLINE_VISIBILITY
778 typename tuple_element<_Ip, tuple<_Tp...> >::type&&
779 get(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
788 template <class ..._Tp>
789 inline _LIBCPP_INLINE_VISIBILITY
790 tuple<_Tp&...>
791 tie(_Tp&... __t) _NOEXCEPT
792 {
793     return tuple<_Tp&...>(__t...);
794 }
795
796 template <class _Up>
797 struct __ignore_t
798 {
799     template <class _Tp>
800         _LIBCPP_INLINE_VISIBILITY
801         const __ignore_t& operator=(_Tp&&) const {return *this;}
802 };
803
804 namespace { const __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>(); }
805
806 template <class _Tp> class _LIBCPP_TYPE_VIS reference_wrapper;
807
808 template <class _Tp>
809 struct ___make_tuple_return
810 {
811     typedef _Tp type;
812 };
813
814 template <class _Tp>
815 struct ___make_tuple_return<reference_wrapper<_Tp> >
816 {
817     typedef _Tp& type;
818 };
819
820 template <class _Tp>
821 struct __make_tuple_return
822 {
823     typedef typename ___make_tuple_return<typename decay<_Tp>::type>::type type;
824 };
825
826 template <class... _Tp>
827 inline _LIBCPP_INLINE_VISIBILITY
828 tuple<typename __make_tuple_return<_Tp>::type...>
829 make_tuple(_Tp&&... __t)
830 {
831     return tuple<typename __make_tuple_return<_Tp>::type...>(_VSTD::forward<_Tp>(__t)...);
832 }
833
834 template <class... _Tp>
835 inline _LIBCPP_INLINE_VISIBILITY
836 tuple<_Tp&&...>
837 forward_as_tuple(_Tp&&... __t) _NOEXCEPT
838 {
839     return tuple<_Tp&&...>(_VSTD::forward<_Tp>(__t)...);
840 }
841
842 template <size_t _Ip>
843 struct __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
853 template <>
854 struct __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
864 template <class ..._Tp, class ..._Up>
865 inline _LIBCPP_INLINE_VISIBILITY
866 bool
867 operator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
868 {
869     return __tuple_equal<sizeof...(_Tp)>()(__x, __y);
870 }
871
872 template <class ..._Tp, class ..._Up>
873 inline _LIBCPP_INLINE_VISIBILITY
874 bool
875 operator!=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
876 {
877     return !(__x == __y);
878 }
879
880 template <size_t _Ip>
881 struct __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
892 template <>
893 struct __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
903 template <class ..._Tp, class ..._Up>
904 inline _LIBCPP_INLINE_VISIBILITY
905 bool
906 operator<(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
907 {
908     return __tuple_less<sizeof...(_Tp)>()(__x, __y);
909 }
910
911 template <class ..._Tp, class ..._Up>
912 inline _LIBCPP_INLINE_VISIBILITY
913 bool
914 operator>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
915 {
916     return __y < __x;
917 }
918
919 template <class ..._Tp, class ..._Up>
920 inline _LIBCPP_INLINE_VISIBILITY
921 bool
922 operator>=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
923 {
924     return !(__x < __y);
925 }
926
927 template <class ..._Tp, class ..._Up>
928 inline _LIBCPP_INLINE_VISIBILITY
929 bool
930 operator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
931 {
932     return !(__y < __x);
933 }
934
935 // tuple_cat
936
937 template <class _Tp, class _Up> struct __tuple_cat_type;
938
939 template <class ..._Ttypes, class ..._Utypes>
940 struct __tuple_cat_type<tuple<_Ttypes...>, __tuple_types<_Utypes...> >
941 {
942     typedef tuple<_Ttypes..., _Utypes...> type;
943 };
944
945 template <class _ResultTuple, bool _Is_Tuple0TupleLike, class ..._Tuples>
946 struct __tuple_cat_return_1
947 {
948 };
949
950 template <class ..._Types, class _Tuple0>
951 struct __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
958 template <class ..._Types, class _Tuple0, class _Tuple1, class ..._Tuples>
959 struct __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
970 template <class ..._Tuples> struct __tuple_cat_return;
971
972 template <class _Tuple0, class ..._Tuples>
973 struct __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
980 template <>
981 struct __tuple_cat_return<>
982 {
983     typedef tuple<> type;
984 };
985
986 inline _LIBCPP_INLINE_VISIBILITY
987 tuple<>
988 tuple_cat()
989 {
990     return tuple<>();
991 }
992
993 template <class _Rp, class _Indices, class _Tuple0, class ..._Tuples>
994 struct __tuple_cat_return_ref_imp;
995
996 template <class ..._Types, size_t ..._I0, class _Tuple0>
997 struct __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
1004 template <class ..._Types, size_t ..._I0, class _Tuple0, class _Tuple1, class ..._Tuples>
1005 struct __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
1017 template <class _Tuple0, class ..._Tuples>
1018 struct __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
1026 template <class _Types, class _I0, class _J0>
1027 struct __tuple_cat;
1028
1029 template <class ..._Types, size_t ..._I0, size_t ..._J0>
1030 struct __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
1061 template <class _Tuple0, class... _Tuples>
1062 inline _LIBCPP_INLINE_VISIBILITY
1063 typename __tuple_cat_return<_Tuple0, _Tuples...>::type
1064 tuple_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
1073 template <class ..._Tp, class _Alloc>
1074 struct _LIBCPP_TYPE_VIS uses_allocator<tuple<_Tp...>, _Alloc>
1075     : true_type {};
1076
1077 template <class _T1, class _T2>
1078 template <class... _Args1, class... _Args2, size_t ..._I1, size_t ..._I2>
1079 inline _LIBCPP_INLINE_VISIBILITY
1080 pair<_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