blob: 9ae0587a56928c2c832053c13cf90a388f8808c6 [file] [log] [blame]
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00001// -*- C++ -*-
2//===--------------------------- tuple ------------------------------------===//
3//
Howard Hinnantf5256e12010-05-11 21:36:01 +00004// The LLVM Compiler Infrastructure
Howard Hinnantbc8d3f92010-05-11 19:42:16 +00005//
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;
Howard Hinnanta5e01212011-05-27 19:08:18 +000028 tuple(tuple&&) = default;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000029 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&);
Howard Hinnanta5e01212011-05-27 19:08:18 +000059 tuple&
60 operator=(tuple&&) noexcept(AND(is_nothrow_move_assignable<T>::value ...));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000061 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
Howard Hinnanta5e01212011-05-27 19:08:18 +000070 void swap(tuple&) noexcept(AND(swap(declval<T&>(), declval<T&>())...));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000071};
72
73const unspecified ignore;
74
75template <class... T> tuple<V...> make_tuple(T&&...);
Howard Hinnanta5e01212011-05-27 19:08:18 +000076template <class... T> tuple<ATypes...> forward_as_tuple(T&&...) noexcept;
77template <class... T> tuple<T&...> tie(T&...) noexcept;
Howard Hinnant0e1493e2010-12-11 20:47:50 +000078template <class... Tuples> tuple<CTypes...> tuple_cat(Tuples&&... tpls);
79
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000080// 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:
Howard Hinnanta5e01212011-05-27 19:08:18 +000087template <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;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000096
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>
Howard Hinnanta5e01212011-05-27 19:08:18 +0000109 void
110 swap(tuple<Types...>& x, tuple<Types...>& y) noexcept(noexcept(x.swap(y)));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000111
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000112} // std
113
114*/
115
116#include <__config>
117#include <__tuple>
118#include <cstddef>
119#include <memory>
120#include <type_traits>
121
Howard Hinnant08e17472011-10-17 20:05:10 +0000122#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000123#pragma GCC system_header
Howard Hinnant08e17472011-10-17 20:05:10 +0000124#endif
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000125
126_LIBCPP_BEGIN_NAMESPACE_STD
127
128#ifndef _LIBCPP_HAS_NO_VARIADICS
129
130// tuple_size
131
132template <class ..._Tp>
Howard Hinnantf83417b2011-01-24 16:07:25 +0000133class _LIBCPP_VISIBLE tuple_size<tuple<_Tp...> >
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000134 : public integral_constant<size_t, sizeof...(_Tp)>
135{
136};
137
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000138// tuple_element
139
140template <size_t _Ip, class ..._Tp>
Howard Hinnantf83417b2011-01-24 16:07:25 +0000141class _LIBCPP_VISIBLE tuple_element<_Ip, tuple<_Tp...> >
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000142{
143public:
Howard Hinnantf83417b2011-01-24 16:07:25 +0000144 typedef typename tuple_element<_Ip, __tuple_types<_Tp...> >::type type;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000145};
146
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000147// __tuple_leaf
148
Howard Hinnantd4cf2152011-12-11 20:31:33 +0000149template <size_t _Ip, class _Hp, bool=is_empty<_Hp>::value
150#if __has_feature(is_final)
151 && !__is_final(_Hp)
152#endif
153 >
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000154class __tuple_leaf;
155
156template <size_t _Ip, class _Hp, bool _Ep>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000157inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000158void swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y)
Howard Hinnanta5e01212011-05-27 19:08:18 +0000159 _NOEXCEPT_(__is_nothrow_swappable<_Hp>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000160{
161 swap(__x.get(), __y.get());
162}
163
164template <size_t _Ip, class _Hp, bool>
165class __tuple_leaf
166{
167 _Hp value;
168
169 __tuple_leaf& operator=(const __tuple_leaf&);
170public:
171 _LIBCPP_INLINE_VISIBILITY __tuple_leaf() : value()
172 {static_assert(!is_reference<_Hp>::value,
173 "Attempted to default construct a reference element in a tuple");}
174
175 template <class _Alloc>
176 _LIBCPP_INLINE_VISIBILITY
177 __tuple_leaf(integral_constant<int, 0>, const _Alloc&)
178 : value()
179 {static_assert(!is_reference<_Hp>::value,
180 "Attempted to default construct a reference element in a tuple");}
181
182 template <class _Alloc>
183 _LIBCPP_INLINE_VISIBILITY
184 __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
185 : value(allocator_arg_t(), __a)
186 {static_assert(!is_reference<_Hp>::value,
187 "Attempted to default construct a reference element in a tuple");}
188
189 template <class _Alloc>
190 _LIBCPP_INLINE_VISIBILITY
191 __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
192 : value(__a)
193 {static_assert(!is_reference<_Hp>::value,
194 "Attempted to default construct a reference element in a tuple");}
195
Howard Hinnante049cc52010-09-27 17:54:17 +0000196 template <class _Tp,
197 class = typename enable_if<is_constructible<_Hp, _Tp>::value>::type>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000198 _LIBCPP_INLINE_VISIBILITY
199 explicit __tuple_leaf(_Tp&& __t)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000200 : value(_VSTD::forward<_Tp>(__t))
Howard Hinnante049cc52010-09-27 17:54:17 +0000201 {static_assert(!is_reference<_Hp>::value ||
Howard Hinnantec3773c2011-12-01 20:21:04 +0000202 (is_lvalue_reference<_Hp>::value &&
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000203 (is_lvalue_reference<_Tp>::value ||
204 is_same<typename remove_reference<_Tp>::type,
205 reference_wrapper<
206 typename remove_reference<_Hp>::type
207 >
Howard Hinnantec3773c2011-12-01 20:21:04 +0000208 >::value)) ||
Howard Hinnante049cc52010-09-27 17:54:17 +0000209 (is_rvalue_reference<_Hp>::value &&
210 !is_lvalue_reference<_Tp>::value),
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000211 "Attempted to construct a reference element in a tuple with an rvalue");}
212
213 template <class _Tp, class _Alloc>
214 _LIBCPP_INLINE_VISIBILITY
215 explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000216 : value(_VSTD::forward<_Tp>(__t))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000217 {static_assert(!is_lvalue_reference<_Hp>::value ||
Howard Hinnantec3773c2011-12-01 20:21:04 +0000218 (is_lvalue_reference<_Hp>::value &&
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000219 (is_lvalue_reference<_Tp>::value ||
220 is_same<typename remove_reference<_Tp>::type,
221 reference_wrapper<
222 typename remove_reference<_Hp>::type
223 >
Howard Hinnantec3773c2011-12-01 20:21:04 +0000224 >::value)),
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000225 "Attempted to construct a reference element in a tuple with an rvalue");}
226
227 template <class _Tp, class _Alloc>
228 _LIBCPP_INLINE_VISIBILITY
229 explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000230 : value(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t))
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000231 {static_assert(!is_lvalue_reference<_Hp>::value ||
Howard Hinnantec3773c2011-12-01 20:21:04 +0000232 (is_lvalue_reference<_Hp>::value &&
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000233 (is_lvalue_reference<_Tp>::value ||
234 is_same<typename remove_reference<_Tp>::type,
235 reference_wrapper<
236 typename remove_reference<_Hp>::type
237 >
Howard Hinnantec3773c2011-12-01 20:21:04 +0000238 >::value)),
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000239 "Attempted to construct a reference element in a tuple with an rvalue");}
240
241 template <class _Tp, class _Alloc>
242 _LIBCPP_INLINE_VISIBILITY
243 explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000244 : value(_VSTD::forward<_Tp>(__t), __a)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000245 {static_assert(!is_lvalue_reference<_Hp>::value ||
Howard Hinnantec3773c2011-12-01 20:21:04 +0000246 (is_lvalue_reference<_Hp>::value &&
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000247 (is_lvalue_reference<_Tp>::value ||
248 is_same<typename remove_reference<_Tp>::type,
249 reference_wrapper<
250 typename remove_reference<_Hp>::type
251 >
Howard Hinnantec3773c2011-12-01 20:21:04 +0000252 >::value)),
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000253 "Attempted to construct a reference element in a tuple with an rvalue");}
254
Howard Hinnante049cc52010-09-27 17:54:17 +0000255 __tuple_leaf(const __tuple_leaf& __t)
256 : value(__t.get())
257 {static_assert(!is_rvalue_reference<_Hp>::value, "Can not copy a tuple with rvalue reference member");}
258
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000259 template <class _Tp>
260 _LIBCPP_INLINE_VISIBILITY
261 explicit __tuple_leaf(const __tuple_leaf<_Ip, _Tp>& __t)
262 : value(__t.get()) {}
263
264 template <class _Tp>
265 _LIBCPP_INLINE_VISIBILITY
266 __tuple_leaf&
267 operator=(_Tp&& __t)
268 {
Howard Hinnant0949eed2011-06-30 21:18:19 +0000269 value = _VSTD::forward<_Tp>(__t);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000270 return *this;
271 }
272
273 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta5e01212011-05-27 19:08:18 +0000274 int swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000275 {
Howard Hinnant0949eed2011-06-30 21:18:19 +0000276 _VSTD::swap(*this, __t);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000277 return 0;
278 }
279
280 _LIBCPP_INLINE_VISIBILITY _Hp& get() {return value;}
281 _LIBCPP_INLINE_VISIBILITY const _Hp& get() const {return value;}
282};
283
284template <size_t _Ip, class _Hp>
285class __tuple_leaf<_Ip, _Hp, true>
286 : private _Hp
287{
288
289 __tuple_leaf& operator=(const __tuple_leaf&);
290public:
291 _LIBCPP_INLINE_VISIBILITY __tuple_leaf() {}
292
293 template <class _Alloc>
294 _LIBCPP_INLINE_VISIBILITY
295 __tuple_leaf(integral_constant<int, 0>, const _Alloc&) {}
296
297 template <class _Alloc>
298 _LIBCPP_INLINE_VISIBILITY
299 __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
300 : _Hp(allocator_arg_t(), __a) {}
301
302 template <class _Alloc>
303 _LIBCPP_INLINE_VISIBILITY
304 __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
305 : _Hp(__a) {}
306
Howard Hinnante049cc52010-09-27 17:54:17 +0000307 template <class _Tp,
308 class = typename enable_if<is_constructible<_Hp, _Tp>::value>::type>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000309 _LIBCPP_INLINE_VISIBILITY
310 explicit __tuple_leaf(_Tp&& __t)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000311 : _Hp(_VSTD::forward<_Tp>(__t)) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000312
313 template <class _Tp, class _Alloc>
314 _LIBCPP_INLINE_VISIBILITY
315 explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000316 : _Hp(_VSTD::forward<_Tp>(__t)) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000317
318 template <class _Tp, class _Alloc>
319 _LIBCPP_INLINE_VISIBILITY
320 explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000321 : _Hp(allocator_arg_t(), __a, _VSTD::forward<_Tp>(__t)) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000322
323 template <class _Tp, class _Alloc>
324 _LIBCPP_INLINE_VISIBILITY
325 explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000326 : _Hp(_VSTD::forward<_Tp>(__t), __a) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000327
328 template <class _Tp>
329 _LIBCPP_INLINE_VISIBILITY
330 explicit __tuple_leaf(const __tuple_leaf<_Ip, _Tp>& __t)
331 : _Hp(__t.get()) {}
332
333 template <class _Tp>
334 _LIBCPP_INLINE_VISIBILITY
335 __tuple_leaf&
336 operator=(_Tp&& __t)
337 {
Howard Hinnant0949eed2011-06-30 21:18:19 +0000338 _Hp::operator=(_VSTD::forward<_Tp>(__t));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000339 return *this;
340 }
341
Howard Hinnanta5e01212011-05-27 19:08:18 +0000342 _LIBCPP_INLINE_VISIBILITY
343 int
344 swap(__tuple_leaf& __t) _NOEXCEPT_(__is_nothrow_swappable<__tuple_leaf>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000345 {
Howard Hinnant0949eed2011-06-30 21:18:19 +0000346 _VSTD::swap(*this, __t);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000347 return 0;
348 }
349
350 _LIBCPP_INLINE_VISIBILITY _Hp& get() {return static_cast<_Hp&>(*this);}
351 _LIBCPP_INLINE_VISIBILITY const _Hp& get() const {return static_cast<const _Hp&>(*this);}
352};
353
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000354template <class ..._Tp>
355_LIBCPP_INLINE_VISIBILITY
356void __swallow(_Tp&&...) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000357
Howard Hinnanta5e01212011-05-27 19:08:18 +0000358template <bool ...> struct __all;
359
360template <>
361struct __all<>
362{
363 static const bool value = true;
364};
365
Howard Hinnant99968442011-11-29 18:15:50 +0000366template <bool _B0, bool ... _Bp>
367struct __all<_B0, _Bp...>
Howard Hinnanta5e01212011-05-27 19:08:18 +0000368{
Howard Hinnant99968442011-11-29 18:15:50 +0000369 static const bool value = _B0 && __all<_Bp...>::value;
Howard Hinnanta5e01212011-05-27 19:08:18 +0000370};
371
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000372// __tuple_impl
373
374template<class _Indx, class ..._Tp> struct __tuple_impl;
375
376template<size_t ..._Indx, class ..._Tp>
377struct __tuple_impl<__tuple_indices<_Indx...>, _Tp...>
378 : public __tuple_leaf<_Indx, _Tp>...
379{
380 template <size_t ..._Uf, class ..._Tf,
381 size_t ..._Ul, class ..._Tl, class ..._Up>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000382 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000383 explicit
384 __tuple_impl(__tuple_indices<_Uf...>, __tuple_types<_Tf...>,
385 __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
386 _Up&&... __u) :
Howard Hinnant0949eed2011-06-30 21:18:19 +0000387 __tuple_leaf<_Uf, _Tf>(_VSTD::forward<_Up>(__u))...,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000388 __tuple_leaf<_Ul, _Tl>()...
389 {}
390
391 template <class _Alloc, size_t ..._Uf, class ..._Tf,
392 size_t ..._Ul, class ..._Tl, class ..._Up>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000393 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000394 explicit
395 __tuple_impl(allocator_arg_t, const _Alloc& __a,
396 __tuple_indices<_Uf...>, __tuple_types<_Tf...>,
397 __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
398 _Up&&... __u) :
399 __tuple_leaf<_Uf, _Tf>(__uses_alloc_ctor<_Tf, _Alloc, _Up>(), __a,
Howard Hinnant0949eed2011-06-30 21:18:19 +0000400 _VSTD::forward<_Up>(__u))...,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000401 __tuple_leaf<_Ul, _Tl>(__uses_alloc_ctor<_Tl, _Alloc>(), __a)...
402 {}
403
404 template <class _Tuple,
405 class = typename enable_if
406 <
Howard Hinnantf83417b2011-01-24 16:07:25 +0000407 __tuple_convertible<_Tuple, tuple<_Tp...> >::value
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000408 >::type
409 >
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000410 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000411 __tuple_impl(_Tuple&& __t)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000412 : __tuple_leaf<_Indx, _Tp>(_VSTD::forward<typename tuple_element<_Indx,
413 typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000414 {}
415
416 template <class _Alloc, class _Tuple,
417 class = typename enable_if
418 <
Howard Hinnantf83417b2011-01-24 16:07:25 +0000419 __tuple_convertible<_Tuple, tuple<_Tp...> >::value
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000420 >::type
421 >
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000422 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000423 __tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
424 : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, typename tuple_element<_Indx,
Howard Hinnant324bb032010-08-22 00:02:43 +0000425 typename __make_tuple_types<_Tuple>::type>::type>(), __a,
Howard Hinnant0949eed2011-06-30 21:18:19 +0000426 _VSTD::forward<typename tuple_element<_Indx,
427 typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000428 {}
429
430 template <class _Tuple>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000431 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000432 typename enable_if
433 <
Howard Hinnantf83417b2011-01-24 16:07:25 +0000434 __tuple_assignable<_Tuple, tuple<_Tp...> >::value,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000435 __tuple_impl&
436 >::type
437 operator=(_Tuple&& __t)
438 {
Howard Hinnant0949eed2011-06-30 21:18:19 +0000439 __swallow(__tuple_leaf<_Indx, _Tp>::operator=(_VSTD::forward<typename tuple_element<_Indx,
440 typename __make_tuple_types<_Tuple>::type>::type>(_VSTD::get<_Indx>(__t)))...);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000441 return *this;
442 }
443
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000444 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000445 void swap(__tuple_impl& __t)
Howard Hinnanta5e01212011-05-27 19:08:18 +0000446 _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000447 {
448 __swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...);
449 }
450};
451
452template <class ..._Tp>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000453class _LIBCPP_VISIBLE tuple
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000454{
455 typedef __tuple_impl<typename __make_tuple_indices<sizeof...(_Tp)>::type, _Tp...> base;
456
457 base base_;
458
459 template <size_t _Jp, class ..._Up> friend
Howard Hinnantec3773c2011-12-01 20:21:04 +0000460 typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000461 template <size_t _Jp, class ..._Up> friend
Howard Hinnantec3773c2011-12-01 20:21:04 +0000462 const typename tuple_element<_Jp, tuple<_Up...> >::type& get(const tuple<_Up...>&) _NOEXCEPT;
Howard Hinnantcd2254b2010-11-17 19:52:17 +0000463 template <size_t _Jp, class ..._Up> friend
Howard Hinnantec3773c2011-12-01 20:21:04 +0000464 typename tuple_element<_Jp, tuple<_Up...> >::type&& get(tuple<_Up...>&&) _NOEXCEPT;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000465public:
466
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000467 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000468 explicit tuple(const _Tp& ... __t)
469 : base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
470 typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
471 typename __make_tuple_indices<0>::type(),
472 typename __make_tuple_types<tuple, 0>::type(),
473 __t...
474 ) {}
475
476 template <class _Alloc>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000477 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000478 tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
479 : base_(allocator_arg_t(), __a,
480 typename __make_tuple_indices<sizeof...(_Tp)>::type(),
481 typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
482 typename __make_tuple_indices<0>::type(),
483 typename __make_tuple_types<tuple, 0>::type(),
484 __t...
485 ) {}
486
487 template <class ..._Up,
488 class = typename enable_if
489 <
490 sizeof...(_Up) <= sizeof...(_Tp) &&
491 __tuple_convertible
492 <
493 tuple<_Up...>,
494 typename __make_tuple_types<tuple,
495 sizeof...(_Up) < sizeof...(_Tp) ?
496 sizeof...(_Up) :
497 sizeof...(_Tp)>::type
498 >::value
499 >::type
500 >
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000501 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000502 explicit
503 tuple(_Up&&... __u)
504 : base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
505 typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
506 typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
507 typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
Howard Hinnant0949eed2011-06-30 21:18:19 +0000508 _VSTD::forward<_Up>(__u)...) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000509
510 template <class _Alloc, class ..._Up,
511 class = typename enable_if
512 <
513 sizeof...(_Up) <= sizeof...(_Tp) &&
514 __tuple_convertible
515 <
516 tuple<_Up...>,
517 typename __make_tuple_types<tuple,
518 sizeof...(_Up) < sizeof...(_Tp) ?
519 sizeof...(_Up) :
520 sizeof...(_Tp)>::type
521 >::value
522 >::type
523 >
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000524 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000525 tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
526 : base_(allocator_arg_t(), __a,
527 typename __make_tuple_indices<sizeof...(_Up)>::type(),
528 typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
529 typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
530 typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
Howard Hinnant0949eed2011-06-30 21:18:19 +0000531 _VSTD::forward<_Up>(__u)...) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000532
533 template <class _Tuple,
534 class = typename enable_if
535 <
536 __tuple_convertible<_Tuple, tuple>::value
537 >::type
538 >
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000539 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000540 tuple(_Tuple&& __t)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000541 : base_(_VSTD::forward<_Tuple>(__t)) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000542
543 template <class _Alloc, class _Tuple,
544 class = typename enable_if
545 <
546 __tuple_convertible<_Tuple, tuple>::value
547 >::type
548 >
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000549 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000550 tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000551 : base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000552
553 template <class _Tuple,
554 class = typename enable_if
555 <
556 __tuple_assignable<_Tuple, tuple>::value
557 >::type
558 >
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000559 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000560 tuple&
561 operator=(_Tuple&& __t)
562 {
Howard Hinnant0949eed2011-06-30 21:18:19 +0000563 base_.operator=(_VSTD::forward<_Tuple>(__t));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000564 return *this;
565 }
566
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000567 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta5e01212011-05-27 19:08:18 +0000568 void swap(tuple& __t) _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
569 {base_.swap(__t.base_);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000570};
571
572template <>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000573class _LIBCPP_VISIBLE tuple<>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000574{
575public:
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000576 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000577 tuple() {}
578 template <class _Alloc>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000579 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000580 tuple(allocator_arg_t, const _Alloc&) {}
581 template <class _Alloc>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000582 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000583 tuple(allocator_arg_t, const _Alloc&, const tuple&) {}
Howard Hinnant99968442011-11-29 18:15:50 +0000584 template <class _Up>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000585 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000586 tuple(array<_Up, 0>) {}
587 template <class _Alloc, class _Up>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000588 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant99968442011-11-29 18:15:50 +0000589 tuple(allocator_arg_t, const _Alloc&, array<_Up, 0>) {}
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000590 _LIBCPP_INLINE_VISIBILITY
Howard Hinnanta5e01212011-05-27 19:08:18 +0000591 void swap(tuple&) _NOEXCEPT {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000592};
593
594template <class ..._Tp>
595inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantaabf2872011-06-01 19:59:32 +0000596typename enable_if
597<
598 __all<__is_swappable<_Tp>::value...>::value,
599 void
600>::type
Howard Hinnanta5e01212011-05-27 19:08:18 +0000601swap(tuple<_Tp...>& __t, tuple<_Tp...>& __u)
602 _NOEXCEPT_(__all<__is_nothrow_swappable<_Tp>::value...>::value)
603 {__t.swap(__u);}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000604
605// get
606
607template <size_t _Ip, class ..._Tp>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000608inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf83417b2011-01-24 16:07:25 +0000609typename tuple_element<_Ip, tuple<_Tp...> >::type&
Howard Hinnantec3773c2011-12-01 20:21:04 +0000610get(tuple<_Tp...>& __t) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000611{
Howard Hinnantf83417b2011-01-24 16:07:25 +0000612 typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000613 return static_cast<__tuple_leaf<_Ip, type>&>(__t.base_).get();
614}
615
616template <size_t _Ip, class ..._Tp>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000617inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf83417b2011-01-24 16:07:25 +0000618const typename tuple_element<_Ip, tuple<_Tp...> >::type&
Howard Hinnantec3773c2011-12-01 20:21:04 +0000619get(const tuple<_Tp...>& __t) _NOEXCEPT
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000620{
Howard Hinnantf83417b2011-01-24 16:07:25 +0000621 typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000622 return static_cast<const __tuple_leaf<_Ip, type>&>(__t.base_).get();
623}
624
Howard Hinnantcd2254b2010-11-17 19:52:17 +0000625template <size_t _Ip, class ..._Tp>
626inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantf83417b2011-01-24 16:07:25 +0000627typename tuple_element<_Ip, tuple<_Tp...> >::type&&
Howard Hinnantec3773c2011-12-01 20:21:04 +0000628get(tuple<_Tp...>&& __t) _NOEXCEPT
Howard Hinnantcd2254b2010-11-17 19:52:17 +0000629{
Howard Hinnantf83417b2011-01-24 16:07:25 +0000630 typedef typename tuple_element<_Ip, tuple<_Tp...> >::type type;
Howard Hinnant56a85ca2011-01-25 16:31:30 +0000631 return static_cast<type&&>(
Douglas Gregor6c669942011-01-25 16:14:21 +0000632 static_cast<__tuple_leaf<_Ip, type>&&>(__t.base_).get());
Howard Hinnantcd2254b2010-11-17 19:52:17 +0000633}
634
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000635// tie
636
637template <class ..._Tp>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000638inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000639tuple<_Tp&...>
640tie(_Tp&... __t)
641{
642 return tuple<_Tp&...>(__t...);
643}
644
645template <class _Up>
646struct __ignore_t
647{
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000648 template <class _Tp>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000649 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000650 const __ignore_t& operator=(_Tp&&) const {return *this;}
651};
652
653namespace { const __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>(); }
654
655template <class _Tp> class reference_wrapper;
656
657template <class _Tp>
658struct ___make_tuple_return
659{
660 typedef _Tp type;
661};
662
663template <class _Tp>
Howard Hinnantf83417b2011-01-24 16:07:25 +0000664struct ___make_tuple_return<reference_wrapper<_Tp> >
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000665{
666 typedef _Tp& type;
667};
668
669template <class _Tp>
670struct __make_tuple_return
671{
672 typedef typename ___make_tuple_return<typename decay<_Tp>::type>::type type;
673};
674
675template <class... _Tp>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000676inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000677tuple<typename __make_tuple_return<_Tp>::type...>
678make_tuple(_Tp&&... __t)
679{
Howard Hinnant0949eed2011-06-30 21:18:19 +0000680 return tuple<typename __make_tuple_return<_Tp>::type...>(_VSTD::forward<_Tp>(__t)...);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000681}
682
Howard Hinnant3c1ffba2010-08-19 18:59:38 +0000683template <class... _Tp>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000684inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3c1ffba2010-08-19 18:59:38 +0000685tuple<_Tp&&...>
686forward_as_tuple(_Tp&&... __t)
687{
Howard Hinnant0949eed2011-06-30 21:18:19 +0000688 return tuple<_Tp&&...>(_VSTD::forward<_Tp>(__t)...);
Howard Hinnant3c1ffba2010-08-19 18:59:38 +0000689}
690
Howard Hinnant99968442011-11-29 18:15:50 +0000691template <size_t _Ip>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000692struct __tuple_equal
693{
694 template <class _Tp, class _Up>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000695 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000696 bool operator()(const _Tp& __x, const _Up& __y)
697 {
Howard Hinnant99968442011-11-29 18:15:50 +0000698 return __tuple_equal<_Ip - 1>()(__x, __y) && get<_Ip-1>(__x) == get<_Ip-1>(__y);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000699 }
700};
701
702template <>
703struct __tuple_equal<0>
704{
705 template <class _Tp, class _Up>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000706 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000707 bool operator()(const _Tp&, const _Up&)
708 {
709 return true;
710 }
711};
712
713template <class ..._Tp, class ..._Up>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000714inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000715bool
716operator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
717{
718 return __tuple_equal<sizeof...(_Tp)>()(__x, __y);
719}
720
721template <class ..._Tp, class ..._Up>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000722inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000723bool
724operator!=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
725{
726 return !(__x == __y);
727}
728
Howard Hinnant99968442011-11-29 18:15:50 +0000729template <size_t _Ip>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000730struct __tuple_less
731{
732 template <class _Tp, class _Up>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000733 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000734 bool operator()(const _Tp& __x, const _Up& __y)
735 {
Howard Hinnant99968442011-11-29 18:15:50 +0000736 return __tuple_less<_Ip-1>()(__x, __y) ||
737 (!__tuple_less<_Ip-1>()(__y, __x) && get<_Ip-1>(__x) < get<_Ip-1>(__y));
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000738 }
739};
740
741template <>
742struct __tuple_less<0>
743{
744 template <class _Tp, class _Up>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000745 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000746 bool operator()(const _Tp&, const _Up&)
747 {
748 return false;
749 }
750};
751
752template <class ..._Tp, class ..._Up>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000753inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000754bool
755operator<(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
756{
757 return __tuple_less<sizeof...(_Tp)>()(__x, __y);
758}
759
760template <class ..._Tp, class ..._Up>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000761inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000762bool
763operator>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
764{
765 return __y < __x;
766}
767
768template <class ..._Tp, class ..._Up>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000769inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000770bool
771operator>=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
772{
773 return !(__x < __y);
774}
775
776template <class ..._Tp, class ..._Up>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000777inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000778bool
779operator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
780{
781 return !(__y < __x);
782}
783
784// tuple_cat
785
Howard Hinnant0e1493e2010-12-11 20:47:50 +0000786template <class _Tp, class _Up> struct __tuple_cat_type;
787
788template <class ..._Ttypes, class ..._Utypes>
Howard Hinnantf83417b2011-01-24 16:07:25 +0000789struct __tuple_cat_type<tuple<_Ttypes...>, __tuple_types<_Utypes...> >
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000790{
Howard Hinnant0e1493e2010-12-11 20:47:50 +0000791 typedef tuple<_Ttypes..., _Utypes...> type;
792};
793
794template <class _ResultTuple, bool _Is_Tuple0TupleLike, class ..._Tuples>
795struct __tuple_cat_return_1
796{
797};
798
799template <class ..._Types, class _Tuple0>
800struct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0>
801{
802 typedef typename __tuple_cat_type<tuple<_Types...>,
803 typename __make_tuple_types<typename remove_reference<_Tuple0>::type>::type>::type
804 type;
805};
806
807template <class ..._Types, class _Tuple0, class _Tuple1, class ..._Tuples>
808struct __tuple_cat_return_1<tuple<_Types...>, true, _Tuple0, _Tuple1, _Tuples...>
809 : public __tuple_cat_return_1<
810 typename __tuple_cat_type<
811 tuple<_Types...>,
812 typename __make_tuple_types<typename remove_reference<_Tuple0>::type>::type
813 >::type,
814 __tuple_like<typename remove_reference<_Tuple1>::type>::value,
815 _Tuple1, _Tuples...>
816{
817};
818
819template <class ..._Tuples> struct __tuple_cat_return;
820
821template <class _Tuple0, class ..._Tuples>
822struct __tuple_cat_return<_Tuple0, _Tuples...>
823 : public __tuple_cat_return_1<tuple<>,
824 __tuple_like<typename remove_reference<_Tuple0>::type>::value, _Tuple0,
825 _Tuples...>
826{
827};
828
829template <>
830struct __tuple_cat_return<>
831{
832 typedef tuple<> type;
833};
834
835inline _LIBCPP_INLINE_VISIBILITY
836tuple<>
837tuple_cat()
838{
839 return tuple<>();
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000840}
841
Howard Hinnant99968442011-11-29 18:15:50 +0000842template <class _Rp, class _Indices, class _Tuple0, class ..._Tuples>
Howard Hinnante48e3662010-12-12 23:04:37 +0000843struct __tuple_cat_return_ref_imp;
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000844
Howard Hinnante48e3662010-12-12 23:04:37 +0000845template <class ..._Types, size_t ..._I0, class _Tuple0>
846struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>, _Tuple0>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000847{
Howard Hinnant0e1493e2010-12-11 20:47:50 +0000848 typedef typename remove_reference<_Tuple0>::type _T0;
Howard Hinnante48e3662010-12-12 23:04:37 +0000849 typedef tuple<_Types..., typename __apply_cv<_Tuple0,
850 typename tuple_element<_I0, _T0>::type>::type&&...> type;
851};
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000852
Howard Hinnante48e3662010-12-12 23:04:37 +0000853template <class ..._Types, size_t ..._I0, class _Tuple0, class _Tuple1, class ..._Tuples>
854struct __tuple_cat_return_ref_imp<tuple<_Types...>, __tuple_indices<_I0...>,
855 _Tuple0, _Tuple1, _Tuples...>
856 : public __tuple_cat_return_ref_imp<
857 tuple<_Types..., typename __apply_cv<_Tuple0,
858 typename tuple_element<_I0,
859 typename remove_reference<_Tuple0>::type>::type>::type&&...>,
860 typename __make_tuple_indices<tuple_size<typename
861 remove_reference<_Tuple1>::type>::value>::type,
862 _Tuple1, _Tuples...>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000863{
Howard Hinnante48e3662010-12-12 23:04:37 +0000864};
865
866template <class _Tuple0, class ..._Tuples>
867struct __tuple_cat_return_ref
868 : public __tuple_cat_return_ref_imp<tuple<>,
869 typename __make_tuple_indices<
870 tuple_size<typename remove_reference<_Tuple0>::type>::value
871 >::type, _Tuple0, _Tuples...>
872{
873};
874
875template <class _Types, class _I0, class _J0>
876struct __tuple_cat;
877
878template <class ..._Types, size_t ..._I0, size_t ..._J0>
Howard Hinnantf83417b2011-01-24 16:07:25 +0000879struct __tuple_cat<tuple<_Types...>, __tuple_indices<_I0...>, __tuple_indices<_J0...> >
Howard Hinnante48e3662010-12-12 23:04:37 +0000880{
881 template <class _Tuple0>
882 _LIBCPP_INLINE_VISIBILITY
883 typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&>::type
884 operator()(tuple<_Types...> __t, _Tuple0&& __t0)
885 {
Howard Hinnant0949eed2011-06-30 21:18:19 +0000886 return _VSTD::forward_as_tuple(_VSTD::forward<_Types>(get<_I0>(__t))...,
887 get<_J0>(_VSTD::forward<_Tuple0>(__t0))...);
Howard Hinnante48e3662010-12-12 23:04:37 +0000888 }
889
890 template <class _Tuple0, class _Tuple1, class ..._Tuples>
891 _LIBCPP_INLINE_VISIBILITY
892 typename __tuple_cat_return_ref<tuple<_Types...>&&, _Tuple0&&, _Tuple1&&, _Tuples&&...>::type
893 operator()(tuple<_Types...> __t, _Tuple0&& __t0, _Tuple1&& __t1, _Tuples&& ...__tpls)
894 {
895 typedef typename remove_reference<_Tuple0>::type _T0;
896 typedef typename remove_reference<_Tuple1>::type _T1;
897 return __tuple_cat<
898 tuple<_Types..., typename __apply_cv<_Tuple0, typename tuple_element<_J0, _T0>::type>::type&&...>,
899 typename __make_tuple_indices<sizeof ...(_Types) + tuple_size<_T0>::value>::type,
900 typename __make_tuple_indices<tuple_size<_T1>::value>::type>()
Howard Hinnant0949eed2011-06-30 21:18:19 +0000901 (_VSTD::forward_as_tuple(
902 _VSTD::forward<_Types>(get<_I0>(__t))...,
903 get<_J0>(_VSTD::forward<_Tuple0>(__t0))...
Howard Hinnante48e3662010-12-12 23:04:37 +0000904 ),
Howard Hinnant0949eed2011-06-30 21:18:19 +0000905 _VSTD::forward<_Tuple1>(__t1),
906 _VSTD::forward<_Tuples>(__tpls)...);
Howard Hinnante48e3662010-12-12 23:04:37 +0000907 }
908};
909
910template <class _Tuple0, class... _Tuples>
911inline _LIBCPP_INLINE_VISIBILITY
912typename __tuple_cat_return<_Tuple0, _Tuples...>::type
913tuple_cat(_Tuple0&& __t0, _Tuples&&... __tpls)
914{
915 typedef typename remove_reference<_Tuple0>::type _T0;
916 return __tuple_cat<tuple<>, __tuple_indices<>,
917 typename __make_tuple_indices<tuple_size<_T0>::value>::type>()
Howard Hinnant0949eed2011-06-30 21:18:19 +0000918 (tuple<>(), _VSTD::forward<_Tuple0>(__t0),
919 _VSTD::forward<_Tuples>(__tpls)...);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000920}
921
922template <class ..._Tp, class _Alloc>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000923struct _LIBCPP_VISIBLE uses_allocator<tuple<_Tp...>, _Alloc>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000924 : true_type {};
925
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000926template <class _T1, class _T2>
927template <class... _Args1, class... _Args2, size_t ..._I1, size_t ..._I2>
928inline _LIBCPP_INLINE_VISIBILITY
929pair<_T1, _T2>::pair(piecewise_construct_t,
930 tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,
931 __tuple_indices<_I1...>, __tuple_indices<_I2...>)
Howard Hinnant0949eed2011-06-30 21:18:19 +0000932 : first(_VSTD::forward<_Args1>(get<_I1>( __first_args))...),
933 second(_VSTD::forward<_Args2>(get<_I2>(__second_args))...)
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000934{
935}
936
Howard Hinnant324bb032010-08-22 00:02:43 +0000937#endif // _LIBCPP_HAS_NO_VARIADICS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000938
939_LIBCPP_END_NAMESPACE_STD
940
941#endif // _LIBCPP_TUPLE