blob: 27c16ed51fb1885208357e38e50b64c94ac4dcb5 [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;
28 tuple(tuple&&);
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& operator=(tuple&&);
60 template <class... U>
61 tuple& operator=(const tuple<U...>&);
62 template <class... U>
63 tuple& operator=(tuple<U...>&&);
64 template <class U1, class U2>
65 tuple& operator=(const pair<U1, U2>&); // iff sizeof...(T) == 2
66 template <class U1, class U2>
67 tuple& operator=(pair<U1, U2>&&); //iffsizeof...(T) == 2
68
69 void swap(tuple&);
70};
71
72const unspecified ignore;
73
74template <class... T> tuple<V...> make_tuple(T&&...);
Howard Hinnant3c1ffba2010-08-19 18:59:38 +000075template <class... T> tuple<ATypes...> forward_as_tuple(T&&...);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000076template <class... T> tuple<T&...> tie(T&...);
77template <class... T, class... U> tuple<T..., U...> tuple_cat(const tuple<T...>&, const tuple<U...>&);
78template <class... T, class... U> tuple<T..., U...> tuple_cat(tuple<T...>&&, const tuple<U...>&);
79template <class... T, class... U> tuple<T..., U...> tuple_cat(const tuple<T...>&, tuple<U...>&&);
80template <class... T, class... U> tuple<T..., U...> tuple_cat(tuple<T...>&&, tuple<U...>&&);
81
82// 20.4.1.4, tuple helper classes:
83template <class T> class tuple_size; // undefined
84template <class... T> class tuple_size<tuple<T...>>;
85template <intsize_t I, class T> class tuple_element; // undefined
86template <intsize_t I, class... T> class tuple_element<I, tuple<T...>>;
87
88// 20.4.1.5, element access:
89template <intsize_t I, class... T> typename tuple_element<I, tuple<T...>>::type& get(tuple<T...>&);
90template <intsize_t I, class... T> typename tuple_element<I, tuple<T...>>::type const& get(const tuple<T...>&);
Howard Hinnantcd2254b2010-11-17 19:52:17 +000091template <intsize_t I, class... T> typename tuple_element<I, tuple<T...>>::type&& get(tuple<T...>&&);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +000092
93// 20.4.1.6, relational operators:
94template<class... T, class... U> bool operator==(const tuple<T...>&, const tuple<U...>&);
95template<class... T, class... U> bool operator<(const tuple<T...>&, const tuple<U...>&);
96template<class... T, class... U> bool operator!=(const tuple<T...>&, const tuple<U...>&);
97template<class... T, class... U> bool operator>(const tuple<T...>&, const tuple<U...>&);
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...>&);
100
101template <class... Types, class Alloc>
102 struct uses_allocator<tuple<Types...>, Alloc>;
103
104template <class... Types>
105 void swap(tuple<Types...>& x, tuple<Types...>& y);
106
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000107} // std
108
109*/
110
111#include <__config>
112#include <__tuple>
113#include <cstddef>
114#include <memory>
115#include <type_traits>
116
117#pragma GCC system_header
118
119_LIBCPP_BEGIN_NAMESPACE_STD
120
121#ifndef _LIBCPP_HAS_NO_VARIADICS
122
123// tuple_size
124
125template <class ..._Tp>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000126class _LIBCPP_VISIBLE tuple_size<tuple<_Tp...>>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000127 : public integral_constant<size_t, sizeof...(_Tp)>
128{
129};
130
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000131// tuple_element
132
133template <size_t _Ip, class ..._Tp>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000134class _LIBCPP_VISIBLE tuple_element<_Ip, tuple<_Tp...>>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000135{
136public:
137 typedef typename tuple_element<_Ip, __tuple_types<_Tp...>>::type type;
138};
139
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000140// __tuple_leaf
141
142template <size_t _Ip, class _Hp, bool=is_empty<_Hp>::value>
143class __tuple_leaf;
144
145template <size_t _Ip, class _Hp, bool _Ep>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000146inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000147void swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y)
148{
149 swap(__x.get(), __y.get());
150}
151
152template <size_t _Ip, class _Hp, bool>
153class __tuple_leaf
154{
155 _Hp value;
156
157 __tuple_leaf& operator=(const __tuple_leaf&);
158public:
159 _LIBCPP_INLINE_VISIBILITY __tuple_leaf() : value()
160 {static_assert(!is_reference<_Hp>::value,
161 "Attempted to default construct a reference element in a tuple");}
162
163 template <class _Alloc>
164 _LIBCPP_INLINE_VISIBILITY
165 __tuple_leaf(integral_constant<int, 0>, const _Alloc&)
166 : value()
167 {static_assert(!is_reference<_Hp>::value,
168 "Attempted to default construct a reference element in a tuple");}
169
170 template <class _Alloc>
171 _LIBCPP_INLINE_VISIBILITY
172 __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
173 : value(allocator_arg_t(), __a)
174 {static_assert(!is_reference<_Hp>::value,
175 "Attempted to default construct a reference element in a tuple");}
176
177 template <class _Alloc>
178 _LIBCPP_INLINE_VISIBILITY
179 __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
180 : value(__a)
181 {static_assert(!is_reference<_Hp>::value,
182 "Attempted to default construct a reference element in a tuple");}
183
Howard Hinnante049cc52010-09-27 17:54:17 +0000184 template <class _Tp,
185 class = typename enable_if<is_constructible<_Hp, _Tp>::value>::type>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000186 _LIBCPP_INLINE_VISIBILITY
187 explicit __tuple_leaf(_Tp&& __t)
188 : value(_STD::forward<_Tp>(__t))
Howard Hinnante049cc52010-09-27 17:54:17 +0000189 {static_assert(!is_reference<_Hp>::value ||
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000190 is_lvalue_reference<_Hp>::value &&
191 (is_lvalue_reference<_Tp>::value ||
192 is_same<typename remove_reference<_Tp>::type,
193 reference_wrapper<
194 typename remove_reference<_Hp>::type
195 >
Howard Hinnante049cc52010-09-27 17:54:17 +0000196 >::value) ||
197 (is_rvalue_reference<_Hp>::value &&
198 !is_lvalue_reference<_Tp>::value),
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000199 "Attempted to construct a reference element in a tuple with an rvalue");}
200
201 template <class _Tp, class _Alloc>
202 _LIBCPP_INLINE_VISIBILITY
203 explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
204 : value(_STD::forward<_Tp>(__t))
205 {static_assert(!is_lvalue_reference<_Hp>::value ||
206 is_lvalue_reference<_Hp>::value &&
207 (is_lvalue_reference<_Tp>::value ||
208 is_same<typename remove_reference<_Tp>::type,
209 reference_wrapper<
210 typename remove_reference<_Hp>::type
211 >
212 >::value),
213 "Attempted to construct a reference element in a tuple with an rvalue");}
214
215 template <class _Tp, class _Alloc>
216 _LIBCPP_INLINE_VISIBILITY
217 explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
218 : value(allocator_arg_t(), __a, _STD::forward<_Tp>(__t))
219 {static_assert(!is_lvalue_reference<_Hp>::value ||
220 is_lvalue_reference<_Hp>::value &&
221 (is_lvalue_reference<_Tp>::value ||
222 is_same<typename remove_reference<_Tp>::type,
223 reference_wrapper<
224 typename remove_reference<_Hp>::type
225 >
226 >::value),
227 "Attempted to construct a reference element in a tuple with an rvalue");}
228
229 template <class _Tp, class _Alloc>
230 _LIBCPP_INLINE_VISIBILITY
231 explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
232 : value(_STD::forward<_Tp>(__t), __a)
233 {static_assert(!is_lvalue_reference<_Hp>::value ||
234 is_lvalue_reference<_Hp>::value &&
235 (is_lvalue_reference<_Tp>::value ||
236 is_same<typename remove_reference<_Tp>::type,
237 reference_wrapper<
238 typename remove_reference<_Hp>::type
239 >
240 >::value),
241 "Attempted to construct a reference element in a tuple with an rvalue");}
242
Howard Hinnante049cc52010-09-27 17:54:17 +0000243 __tuple_leaf(const __tuple_leaf& __t)
244 : value(__t.get())
245 {static_assert(!is_rvalue_reference<_Hp>::value, "Can not copy a tuple with rvalue reference member");}
246
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000247 template <class _Tp>
248 _LIBCPP_INLINE_VISIBILITY
249 explicit __tuple_leaf(const __tuple_leaf<_Ip, _Tp>& __t)
250 : value(__t.get()) {}
251
252 template <class _Tp>
253 _LIBCPP_INLINE_VISIBILITY
254 __tuple_leaf&
255 operator=(_Tp&& __t)
256 {
257 value = _STD::forward<_Tp>(__t);
258 return *this;
259 }
260
261 _LIBCPP_INLINE_VISIBILITY
262 int swap(__tuple_leaf& __t)
263 {
264 _STD::swap(*this, __t);
265 return 0;
266 }
267
268 _LIBCPP_INLINE_VISIBILITY _Hp& get() {return value;}
269 _LIBCPP_INLINE_VISIBILITY const _Hp& get() const {return value;}
270};
271
272template <size_t _Ip, class _Hp>
273class __tuple_leaf<_Ip, _Hp, true>
274 : private _Hp
275{
276
277 __tuple_leaf& operator=(const __tuple_leaf&);
278public:
279 _LIBCPP_INLINE_VISIBILITY __tuple_leaf() {}
280
281 template <class _Alloc>
282 _LIBCPP_INLINE_VISIBILITY
283 __tuple_leaf(integral_constant<int, 0>, const _Alloc&) {}
284
285 template <class _Alloc>
286 _LIBCPP_INLINE_VISIBILITY
287 __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
288 : _Hp(allocator_arg_t(), __a) {}
289
290 template <class _Alloc>
291 _LIBCPP_INLINE_VISIBILITY
292 __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
293 : _Hp(__a) {}
294
Howard Hinnante049cc52010-09-27 17:54:17 +0000295 template <class _Tp,
296 class = typename enable_if<is_constructible<_Hp, _Tp>::value>::type>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000297 _LIBCPP_INLINE_VISIBILITY
298 explicit __tuple_leaf(_Tp&& __t)
299 : _Hp(_STD::forward<_Tp>(__t)) {}
300
301 template <class _Tp, class _Alloc>
302 _LIBCPP_INLINE_VISIBILITY
303 explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
304 : _Hp(_STD::forward<_Tp>(__t)) {}
305
306 template <class _Tp, class _Alloc>
307 _LIBCPP_INLINE_VISIBILITY
308 explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
309 : _Hp(allocator_arg_t(), __a, _STD::forward<_Tp>(__t)) {}
310
311 template <class _Tp, class _Alloc>
312 _LIBCPP_INLINE_VISIBILITY
313 explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
314 : _Hp(_STD::forward<_Tp>(__t), __a) {}
315
316 template <class _Tp>
317 _LIBCPP_INLINE_VISIBILITY
318 explicit __tuple_leaf(const __tuple_leaf<_Ip, _Tp>& __t)
319 : _Hp(__t.get()) {}
320
321 template <class _Tp>
322 _LIBCPP_INLINE_VISIBILITY
323 __tuple_leaf&
324 operator=(_Tp&& __t)
325 {
326 _Hp::operator=(_STD::forward<_Tp>(__t));
327 return *this;
328 }
329
330 _LIBCPP_INLINE_VISIBILITY int swap(__tuple_leaf& __t)
331 {
332 _STD::swap(*this, __t);
333 return 0;
334 }
335
336 _LIBCPP_INLINE_VISIBILITY _Hp& get() {return static_cast<_Hp&>(*this);}
337 _LIBCPP_INLINE_VISIBILITY const _Hp& get() const {return static_cast<const _Hp&>(*this);}
338};
339
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000340template <class ..._Tp>
341_LIBCPP_INLINE_VISIBILITY
342void __swallow(_Tp&&...) {}
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000343
344// __tuple_impl
345
346template<class _Indx, class ..._Tp> struct __tuple_impl;
347
348template<size_t ..._Indx, class ..._Tp>
349struct __tuple_impl<__tuple_indices<_Indx...>, _Tp...>
350 : public __tuple_leaf<_Indx, _Tp>...
351{
352 template <size_t ..._Uf, class ..._Tf,
353 size_t ..._Ul, class ..._Tl, class ..._Up>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000354 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000355 explicit
356 __tuple_impl(__tuple_indices<_Uf...>, __tuple_types<_Tf...>,
357 __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
358 _Up&&... __u) :
359 __tuple_leaf<_Uf, _Tf>(_STD::forward<_Up>(__u))...,
360 __tuple_leaf<_Ul, _Tl>()...
361 {}
362
363 template <class _Alloc, size_t ..._Uf, class ..._Tf,
364 size_t ..._Ul, class ..._Tl, class ..._Up>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000365 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000366 explicit
367 __tuple_impl(allocator_arg_t, const _Alloc& __a,
368 __tuple_indices<_Uf...>, __tuple_types<_Tf...>,
369 __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
370 _Up&&... __u) :
371 __tuple_leaf<_Uf, _Tf>(__uses_alloc_ctor<_Tf, _Alloc, _Up>(), __a,
372 _STD::forward<_Up>(__u))...,
373 __tuple_leaf<_Ul, _Tl>(__uses_alloc_ctor<_Tl, _Alloc>(), __a)...
374 {}
375
376 template <class _Tuple,
377 class = typename enable_if
378 <
379 __tuple_convertible<_Tuple, tuple<_Tp...>>::value
380 >::type
381 >
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000382 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000383 __tuple_impl(_Tuple&& __t)
384 : __tuple_leaf<_Indx, _Tp>(_STD::forward<typename tuple_element<_Indx,
385 typename __make_tuple_types<_Tuple>::type>::type>(_STD::get<_Indx>(__t)))...
386 {}
387
388 template <class _Alloc, class _Tuple,
389 class = typename enable_if
390 <
391 __tuple_convertible<_Tuple, tuple<_Tp...>>::value
392 >::type
393 >
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000394 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000395 __tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
396 : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, typename tuple_element<_Indx,
Howard Hinnant324bb032010-08-22 00:02:43 +0000397 typename __make_tuple_types<_Tuple>::type>::type>(), __a,
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000398 _STD::forward<typename tuple_element<_Indx,
399 typename __make_tuple_types<_Tuple>::type>::type>(_STD::get<_Indx>(__t)))...
400 {}
401
402 template <class _Tuple>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000403 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000404 typename enable_if
405 <
406 __tuple_assignable<_Tuple, tuple<_Tp...>>::value,
407 __tuple_impl&
408 >::type
409 operator=(_Tuple&& __t)
410 {
411 __swallow(__tuple_leaf<_Indx, _Tp>::operator=(_STD::forward<typename tuple_element<_Indx,
412 typename __make_tuple_types<_Tuple>::type>::type>(_STD::get<_Indx>(__t)))...);
413 return *this;
414 }
415
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000416 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000417 void swap(__tuple_impl& __t)
418 {
419 __swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...);
420 }
421};
422
423template <class ..._Tp>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000424class _LIBCPP_VISIBLE tuple
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000425{
426 typedef __tuple_impl<typename __make_tuple_indices<sizeof...(_Tp)>::type, _Tp...> base;
427
428 base base_;
429
430 template <size_t _Jp, class ..._Up> friend
431 typename tuple_element<_Jp, tuple<_Up...>>::type& get(tuple<_Up...>&);
432 template <size_t _Jp, class ..._Up> friend
433 const typename tuple_element<_Jp, tuple<_Up...>>::type& get(const tuple<_Up...>&);
Howard Hinnantcd2254b2010-11-17 19:52:17 +0000434 template <size_t _Jp, class ..._Up> friend
435 typename tuple_element<_Jp, tuple<_Up...>>::type&& get(tuple<_Up...>&&);
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000436public:
437
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000438 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000439 explicit tuple(const _Tp& ... __t)
440 : base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
441 typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
442 typename __make_tuple_indices<0>::type(),
443 typename __make_tuple_types<tuple, 0>::type(),
444 __t...
445 ) {}
446
447 template <class _Alloc>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000448 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000449 tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
450 : base_(allocator_arg_t(), __a,
451 typename __make_tuple_indices<sizeof...(_Tp)>::type(),
452 typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
453 typename __make_tuple_indices<0>::type(),
454 typename __make_tuple_types<tuple, 0>::type(),
455 __t...
456 ) {}
457
458 template <class ..._Up,
459 class = typename enable_if
460 <
461 sizeof...(_Up) <= sizeof...(_Tp) &&
462 __tuple_convertible
463 <
464 tuple<_Up...>,
465 typename __make_tuple_types<tuple,
466 sizeof...(_Up) < sizeof...(_Tp) ?
467 sizeof...(_Up) :
468 sizeof...(_Tp)>::type
469 >::value
470 >::type
471 >
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000472 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000473 explicit
474 tuple(_Up&&... __u)
475 : base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
476 typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
477 typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
478 typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
479 _STD::forward<_Up>(__u)...) {}
480
481 template <class _Alloc, class ..._Up,
482 class = typename enable_if
483 <
484 sizeof...(_Up) <= sizeof...(_Tp) &&
485 __tuple_convertible
486 <
487 tuple<_Up...>,
488 typename __make_tuple_types<tuple,
489 sizeof...(_Up) < sizeof...(_Tp) ?
490 sizeof...(_Up) :
491 sizeof...(_Tp)>::type
492 >::value
493 >::type
494 >
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000495 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000496 tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
497 : base_(allocator_arg_t(), __a,
498 typename __make_tuple_indices<sizeof...(_Up)>::type(),
499 typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
500 typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
501 typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
502 _STD::forward<_Up>(__u)...) {}
503
504 template <class _Tuple,
505 class = typename enable_if
506 <
507 __tuple_convertible<_Tuple, tuple>::value
508 >::type
509 >
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000510 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000511 tuple(_Tuple&& __t)
512 : base_(_STD::forward<_Tuple>(__t)) {}
513
514 template <class _Alloc, class _Tuple,
515 class = typename enable_if
516 <
517 __tuple_convertible<_Tuple, tuple>::value
518 >::type
519 >
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000520 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000521 tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
522 : base_(allocator_arg_t(), __a, _STD::forward<_Tuple>(__t)) {}
523
524 template <class _Tuple,
525 class = typename enable_if
526 <
527 __tuple_assignable<_Tuple, tuple>::value
528 >::type
529 >
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000530 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000531 tuple&
532 operator=(_Tuple&& __t)
533 {
534 base_.operator=(_STD::forward<_Tuple>(__t));
535 return *this;
536 }
537
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000538 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000539 void swap(tuple& __t) {base_.swap(__t.base_);}
540};
541
542template <>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000543class _LIBCPP_VISIBLE tuple<>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000544{
545public:
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000546 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000547 tuple() {}
548 template <class _Alloc>
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&) {}
551 template <class _Alloc>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000552 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000553 tuple(allocator_arg_t, const _Alloc&, const tuple&) {}
554 template <class _U>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000555 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000556 tuple(array<_U, 0>) {}
557 template <class _Alloc, class _U>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000558 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000559 tuple(allocator_arg_t, const _Alloc&, array<_U, 0>) {}
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000560 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000561 void swap(tuple&) {}
562};
563
564template <class ..._Tp>
565inline _LIBCPP_INLINE_VISIBILITY
566void
567swap(tuple<_Tp...>& __t, tuple<_Tp...>& __u) {__t.swap(__u);}
568
569// get
570
571template <size_t _Ip, class ..._Tp>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000572inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000573typename tuple_element<_Ip, tuple<_Tp...>>::type&
574get(tuple<_Tp...>& __t)
575{
576 typedef typename tuple_element<_Ip, tuple<_Tp...>>::type type;
577 return static_cast<__tuple_leaf<_Ip, type>&>(__t.base_).get();
578}
579
580template <size_t _Ip, class ..._Tp>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000581inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000582const typename tuple_element<_Ip, tuple<_Tp...>>::type&
583get(const tuple<_Tp...>& __t)
584{
585 typedef typename tuple_element<_Ip, tuple<_Tp...>>::type type;
586 return static_cast<const __tuple_leaf<_Ip, type>&>(__t.base_).get();
587}
588
Howard Hinnantcd2254b2010-11-17 19:52:17 +0000589template <size_t _Ip, class ..._Tp>
590inline _LIBCPP_INLINE_VISIBILITY
591typename tuple_element<_Ip, tuple<_Tp...>>::type&&
592get(tuple<_Tp...>&& __t)
593{
594 typedef typename tuple_element<_Ip, tuple<_Tp...>>::type type;
595 return static_cast<__tuple_leaf<_Ip, type>&&>(__t.base_).get();
596}
597
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000598// tie
599
600template <class ..._Tp>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000601inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000602tuple<_Tp&...>
603tie(_Tp&... __t)
604{
605 return tuple<_Tp&...>(__t...);
606}
607
608template <class _Up>
609struct __ignore_t
610{
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000611 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000612 __ignore_t() {}
613 template <class _Tp>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000614 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000615 __ignore_t(_Tp&&) {}
616 template <class _Tp>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000617 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000618 const __ignore_t& operator=(_Tp&&) const {return *this;}
619};
620
621namespace { const __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>(); }
622
623template <class _Tp> class reference_wrapper;
624
625template <class _Tp>
626struct ___make_tuple_return
627{
628 typedef _Tp type;
629};
630
631template <class _Tp>
632struct ___make_tuple_return<reference_wrapper<_Tp>>
633{
634 typedef _Tp& type;
635};
636
637template <class _Tp>
638struct __make_tuple_return
639{
640 typedef typename ___make_tuple_return<typename decay<_Tp>::type>::type type;
641};
642
643template <class... _Tp>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000644inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000645tuple<typename __make_tuple_return<_Tp>::type...>
646make_tuple(_Tp&&... __t)
647{
648 return tuple<typename __make_tuple_return<_Tp>::type...>(_STD::forward<_Tp>(__t)...);
649}
650
Howard Hinnant3c1ffba2010-08-19 18:59:38 +0000651template <class... _Tp>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000652inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnant3c1ffba2010-08-19 18:59:38 +0000653tuple<_Tp&&...>
654forward_as_tuple(_Tp&&... __t)
655{
656 return tuple<_Tp&&...>(_STD::forward<_Tp>(__t)...);
657}
658
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000659template <size_t _I>
660struct __tuple_equal
661{
662 template <class _Tp, class _Up>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000663 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000664 bool operator()(const _Tp& __x, const _Up& __y)
665 {
666 return __tuple_equal<_I - 1>()(__x, __y) && get<_I-1>(__x) == get<_I-1>(__y);
667 }
668};
669
670template <>
671struct __tuple_equal<0>
672{
673 template <class _Tp, class _Up>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000674 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000675 bool operator()(const _Tp&, const _Up&)
676 {
677 return true;
678 }
679};
680
681template <class ..._Tp, class ..._Up>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000682inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000683bool
684operator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
685{
686 return __tuple_equal<sizeof...(_Tp)>()(__x, __y);
687}
688
689template <class ..._Tp, class ..._Up>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000690inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000691bool
692operator!=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
693{
694 return !(__x == __y);
695}
696
697template <size_t _I>
698struct __tuple_less
699{
700 template <class _Tp, class _Up>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000701 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000702 bool operator()(const _Tp& __x, const _Up& __y)
703 {
704 return __tuple_less<_I-1>()(__x, __y) ||
705 (!__tuple_less<_I-1>()(__y, __x) && get<_I-1>(__x) < get<_I-1>(__y));
706 }
707};
708
709template <>
710struct __tuple_less<0>
711{
712 template <class _Tp, class _Up>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000713 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000714 bool operator()(const _Tp&, const _Up&)
715 {
716 return false;
717 }
718};
719
720template <class ..._Tp, class ..._Up>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000721inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000722bool
723operator<(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
724{
725 return __tuple_less<sizeof...(_Tp)>()(__x, __y);
726}
727
728template <class ..._Tp, class ..._Up>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000729inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000730bool
731operator>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
732{
733 return __y < __x;
734}
735
736template <class ..._Tp, class ..._Up>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000737inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000738bool
739operator>=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
740{
741 return !(__x < __y);
742}
743
744template <class ..._Tp, class ..._Up>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000745inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000746bool
747operator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
748{
749 return !(__y < __x);
750}
751
752// tuple_cat
753
754template <class... _Tp, size_t ..._I1, class... _Up, size_t ..._I2>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000755inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000756tuple<_Tp..., _Up...>
757__tuple_cat(const tuple<_Tp...>& __x, __tuple_indices<_I1...>, const tuple<_Up...>& __y, __tuple_indices<_I2...>)
758{
759 return tuple<_Tp..., _Up...>(get<_I1>(__x)..., get<_I2>(__y)...);
760}
761
762template <class... _Tp, class... _Up>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000763inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000764tuple<_Tp..., _Up...>
765tuple_cat(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
766{
767 return __tuple_cat(__x, typename __make_tuple_indices<sizeof...(_Tp)>::type(),
768 __y, typename __make_tuple_indices<sizeof...(_Up)>::type());
769}
770
771template <class... _Tp, size_t ..._I1, class... _Up, size_t ..._I2>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000772inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000773tuple<_Tp..., _Up...>
774__tuple_cat(tuple<_Tp...>&& __x, __tuple_indices<_I1...>, const tuple<_Up...>& __y, __tuple_indices<_I2...>)
775{
776 return tuple<_Tp..., _Up...>(_STD::forward<_Tp>(get<_I1>(__x))..., get<_I2>(__y)...);
777}
778
779template <class... _Tp, class... _Up>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000780inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000781tuple<_Tp..., _Up...>
782tuple_cat(tuple<_Tp...>&& __x, const tuple<_Up...>& __y)
783{
784 return __tuple_cat(_STD::move(__x), typename __make_tuple_indices<sizeof...(_Tp)>::type(),
785 __y, typename __make_tuple_indices<sizeof...(_Up)>::type());
786}
787
788template <class... _Tp, size_t ..._I1, class... _Up, size_t ..._I2>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000789inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000790tuple<_Tp..., _Up...>
791__tuple_cat(const tuple<_Tp...>& __x, __tuple_indices<_I1...>, tuple<_Up...>&& __y, __tuple_indices<_I2...>)
792{
793 return tuple<_Tp..., _Up...>(get<_I1>(__x)..., _STD::forward<_Up>(get<_I2>(__y))...);
794}
795
796template <class... _Tp, class... _Up>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000797inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000798tuple<_Tp..., _Up...>
799tuple_cat(const tuple<_Tp...>& __x, tuple<_Up...>&& __y)
800{
801 return __tuple_cat(__x, typename __make_tuple_indices<sizeof...(_Tp)>::type(),
802 _STD::move(__y), typename __make_tuple_indices<sizeof...(_Up)>::type());
803}
804
805template <class... _Tp, size_t ..._I1, class... _Up, size_t ..._I2>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000806inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000807tuple<_Tp..., _Up...>
808__tuple_cat(tuple<_Tp...>&& __x, __tuple_indices<_I1...>, tuple<_Up...>&& __y, __tuple_indices<_I2...>)
809{
810 return tuple<_Tp..., _Up...>(_STD::forward<_Tp>(get<_I1>(__x))..., _STD::forward<_Up>(get<_I2>(__y))...);
811}
812
813template <class... _Tp, class... _Up>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000814inline _LIBCPP_INLINE_VISIBILITY
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000815tuple<_Tp..., _Up...>
816tuple_cat(tuple<_Tp...>&& __x, tuple<_Up...>&& __y)
817{
818 return __tuple_cat(_STD::move(__x), typename __make_tuple_indices<sizeof...(_Tp)>::type(),
819 _STD::move(__y), typename __make_tuple_indices<sizeof...(_Up)>::type());
820}
821
822template <class ..._Tp, class _Alloc>
Howard Hinnantee6ccd02010-09-23 18:58:28 +0000823struct _LIBCPP_VISIBLE uses_allocator<tuple<_Tp...>, _Alloc>
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000824 : true_type {};
825
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000826template <class _T1, class _T2>
827template <class... _Args1, class... _Args2, size_t ..._I1, size_t ..._I2>
828inline _LIBCPP_INLINE_VISIBILITY
829pair<_T1, _T2>::pair(piecewise_construct_t,
830 tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,
831 __tuple_indices<_I1...>, __tuple_indices<_I2...>)
832 : first(_STD::forward<_Args1>(get<_I1>( __first_args))...),
833 second(_STD::forward<_Args2>(get<_I2>(__second_args))...)
834{
835}
836
Howard Hinnant324bb032010-08-22 00:02:43 +0000837#endif // _LIBCPP_HAS_NO_VARIADICS
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000838
839_LIBCPP_END_NAMESPACE_STD
840
841#endif // _LIBCPP_TUPLE