blob: b1136e52b2ef83e26ac61eced701360b5bcae10a [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...>&);
91
92// 20.4.1.6, relational operators:
93template<class... T, class... U> bool operator==(const tuple<T...>&, const tuple<U...>&);
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...>&);
99
100template <class... Types, class Alloc>
101 struct uses_allocator<tuple<Types...>, Alloc>;
102
103template <class... Types>
104 void swap(tuple<Types...>& x, tuple<Types...>& y);
105
106template <class InputIterator>
107 InputIterator begin(const std::tuple<InputIterator, InputIterator>& t);
108
109template <class InputIterator>
110 InputIterator end(const std::tuple<InputIterator, InputIterator>& t);
111
112} // std
113
114*/
115
116#include <__config>
117#include <__tuple>
118#include <cstddef>
119#include <memory>
120#include <type_traits>
121
122#pragma GCC system_header
123
124_LIBCPP_BEGIN_NAMESPACE_STD
125
126#ifndef _LIBCPP_HAS_NO_VARIADICS
127
128// tuple_size
129
130template <class ..._Tp>
131class tuple_size<tuple<_Tp...>>
132 : public integral_constant<size_t, sizeof...(_Tp)>
133{
134};
135
136template <class ..._Tp>
137class tuple_size<const tuple<_Tp...>>
138 : public integral_constant<size_t, sizeof...(_Tp)>
139{
140};
141
142// tuple_element
143
144template <size_t _Ip, class ..._Tp>
145class tuple_element<_Ip, tuple<_Tp...>>
146{
147public:
148 typedef typename tuple_element<_Ip, __tuple_types<_Tp...>>::type type;
149};
150
151template <size_t _Ip, class ..._Tp>
152class tuple_element<_Ip, const tuple<_Tp...>>
153{
154public:
155 typedef const typename tuple_element<_Ip, __tuple_types<_Tp...>>::type type;
156};
157
158// __tuple_leaf
159
160template <size_t _Ip, class _Hp, bool=is_empty<_Hp>::value>
161class __tuple_leaf;
162
163template <size_t _Ip, class _Hp, bool _Ep>
164inline
165void swap(__tuple_leaf<_Ip, _Hp, _Ep>& __x, __tuple_leaf<_Ip, _Hp, _Ep>& __y)
166{
167 swap(__x.get(), __y.get());
168}
169
170template <size_t _Ip, class _Hp, bool>
171class __tuple_leaf
172{
173 _Hp value;
174
175 __tuple_leaf& operator=(const __tuple_leaf&);
176public:
177 _LIBCPP_INLINE_VISIBILITY __tuple_leaf() : value()
178 {static_assert(!is_reference<_Hp>::value,
179 "Attempted to default construct a reference element in a tuple");}
180
181 template <class _Alloc>
182 _LIBCPP_INLINE_VISIBILITY
183 __tuple_leaf(integral_constant<int, 0>, const _Alloc&)
184 : value()
185 {static_assert(!is_reference<_Hp>::value,
186 "Attempted to default construct a reference element in a tuple");}
187
188 template <class _Alloc>
189 _LIBCPP_INLINE_VISIBILITY
190 __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
191 : value(allocator_arg_t(), __a)
192 {static_assert(!is_reference<_Hp>::value,
193 "Attempted to default construct a reference element in a tuple");}
194
195 template <class _Alloc>
196 _LIBCPP_INLINE_VISIBILITY
197 __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
198 : value(__a)
199 {static_assert(!is_reference<_Hp>::value,
200 "Attempted to default construct a reference element in a tuple");}
201
202 template <class _Tp>
203 _LIBCPP_INLINE_VISIBILITY
204 explicit __tuple_leaf(_Tp&& __t)
205 : value(_STD::forward<_Tp>(__t))
206 {static_assert(!is_lvalue_reference<_Hp>::value ||
207 is_lvalue_reference<_Hp>::value &&
208 (is_lvalue_reference<_Tp>::value ||
209 is_same<typename remove_reference<_Tp>::type,
210 reference_wrapper<
211 typename remove_reference<_Hp>::type
212 >
213 >::value),
214 "Attempted to construct a reference element in a tuple with an rvalue");}
215
216 template <class _Tp, class _Alloc>
217 _LIBCPP_INLINE_VISIBILITY
218 explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
219 : value(_STD::forward<_Tp>(__t))
220 {static_assert(!is_lvalue_reference<_Hp>::value ||
221 is_lvalue_reference<_Hp>::value &&
222 (is_lvalue_reference<_Tp>::value ||
223 is_same<typename remove_reference<_Tp>::type,
224 reference_wrapper<
225 typename remove_reference<_Hp>::type
226 >
227 >::value),
228 "Attempted to construct a reference element in a tuple with an rvalue");}
229
230 template <class _Tp, class _Alloc>
231 _LIBCPP_INLINE_VISIBILITY
232 explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
233 : value(allocator_arg_t(), __a, _STD::forward<_Tp>(__t))
234 {static_assert(!is_lvalue_reference<_Hp>::value ||
235 is_lvalue_reference<_Hp>::value &&
236 (is_lvalue_reference<_Tp>::value ||
237 is_same<typename remove_reference<_Tp>::type,
238 reference_wrapper<
239 typename remove_reference<_Hp>::type
240 >
241 >::value),
242 "Attempted to construct a reference element in a tuple with an rvalue");}
243
244 template <class _Tp, class _Alloc>
245 _LIBCPP_INLINE_VISIBILITY
246 explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
247 : value(_STD::forward<_Tp>(__t), __a)
248 {static_assert(!is_lvalue_reference<_Hp>::value ||
249 is_lvalue_reference<_Hp>::value &&
250 (is_lvalue_reference<_Tp>::value ||
251 is_same<typename remove_reference<_Tp>::type,
252 reference_wrapper<
253 typename remove_reference<_Hp>::type
254 >
255 >::value),
256 "Attempted to construct a reference element in a tuple with an rvalue");}
257
258 template <class _Tp>
259 _LIBCPP_INLINE_VISIBILITY
260 explicit __tuple_leaf(const __tuple_leaf<_Ip, _Tp>& __t)
261 : value(__t.get()) {}
262
263 template <class _Tp>
264 _LIBCPP_INLINE_VISIBILITY
265 __tuple_leaf&
266 operator=(_Tp&& __t)
267 {
268 value = _STD::forward<_Tp>(__t);
269 return *this;
270 }
271
272 _LIBCPP_INLINE_VISIBILITY
273 int swap(__tuple_leaf& __t)
274 {
275 _STD::swap(*this, __t);
276 return 0;
277 }
278
279 _LIBCPP_INLINE_VISIBILITY _Hp& get() {return value;}
280 _LIBCPP_INLINE_VISIBILITY const _Hp& get() const {return value;}
281};
282
283template <size_t _Ip, class _Hp>
284class __tuple_leaf<_Ip, _Hp, true>
285 : private _Hp
286{
287
288 __tuple_leaf& operator=(const __tuple_leaf&);
289public:
290 _LIBCPP_INLINE_VISIBILITY __tuple_leaf() {}
291
292 template <class _Alloc>
293 _LIBCPP_INLINE_VISIBILITY
294 __tuple_leaf(integral_constant<int, 0>, const _Alloc&) {}
295
296 template <class _Alloc>
297 _LIBCPP_INLINE_VISIBILITY
298 __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a)
299 : _Hp(allocator_arg_t(), __a) {}
300
301 template <class _Alloc>
302 _LIBCPP_INLINE_VISIBILITY
303 __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a)
304 : _Hp(__a) {}
305
306 template <class _Tp>
307 _LIBCPP_INLINE_VISIBILITY
308 explicit __tuple_leaf(_Tp&& __t)
309 : _Hp(_STD::forward<_Tp>(__t)) {}
310
311 template <class _Tp, class _Alloc>
312 _LIBCPP_INLINE_VISIBILITY
313 explicit __tuple_leaf(integral_constant<int, 0>, const _Alloc&, _Tp&& __t)
314 : _Hp(_STD::forward<_Tp>(__t)) {}
315
316 template <class _Tp, class _Alloc>
317 _LIBCPP_INLINE_VISIBILITY
318 explicit __tuple_leaf(integral_constant<int, 1>, const _Alloc& __a, _Tp&& __t)
319 : _Hp(allocator_arg_t(), __a, _STD::forward<_Tp>(__t)) {}
320
321 template <class _Tp, class _Alloc>
322 _LIBCPP_INLINE_VISIBILITY
323 explicit __tuple_leaf(integral_constant<int, 2>, const _Alloc& __a, _Tp&& __t)
324 : _Hp(_STD::forward<_Tp>(__t), __a) {}
325
326 template <class _Tp>
327 _LIBCPP_INLINE_VISIBILITY
328 explicit __tuple_leaf(const __tuple_leaf<_Ip, _Tp>& __t)
329 : _Hp(__t.get()) {}
330
331 template <class _Tp>
332 _LIBCPP_INLINE_VISIBILITY
333 __tuple_leaf&
334 operator=(_Tp&& __t)
335 {
336 _Hp::operator=(_STD::forward<_Tp>(__t));
337 return *this;
338 }
339
340 _LIBCPP_INLINE_VISIBILITY int swap(__tuple_leaf& __t)
341 {
342 _STD::swap(*this, __t);
343 return 0;
344 }
345
346 _LIBCPP_INLINE_VISIBILITY _Hp& get() {return static_cast<_Hp&>(*this);}
347 _LIBCPP_INLINE_VISIBILITY const _Hp& get() const {return static_cast<const _Hp&>(*this);}
348};
349
350template <class ..._Tp> void __swallow(_Tp&&...) {}
351
352// __tuple_impl
353
354template<class _Indx, class ..._Tp> struct __tuple_impl;
355
356template<size_t ..._Indx, class ..._Tp>
357struct __tuple_impl<__tuple_indices<_Indx...>, _Tp...>
358 : public __tuple_leaf<_Indx, _Tp>...
359{
360 template <size_t ..._Uf, class ..._Tf,
361 size_t ..._Ul, class ..._Tl, class ..._Up>
362 explicit
363 __tuple_impl(__tuple_indices<_Uf...>, __tuple_types<_Tf...>,
364 __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
365 _Up&&... __u) :
366 __tuple_leaf<_Uf, _Tf>(_STD::forward<_Up>(__u))...,
367 __tuple_leaf<_Ul, _Tl>()...
368 {}
369
370 template <class _Alloc, size_t ..._Uf, class ..._Tf,
371 size_t ..._Ul, class ..._Tl, class ..._Up>
372 explicit
373 __tuple_impl(allocator_arg_t, const _Alloc& __a,
374 __tuple_indices<_Uf...>, __tuple_types<_Tf...>,
375 __tuple_indices<_Ul...>, __tuple_types<_Tl...>,
376 _Up&&... __u) :
377 __tuple_leaf<_Uf, _Tf>(__uses_alloc_ctor<_Tf, _Alloc, _Up>(), __a,
378 _STD::forward<_Up>(__u))...,
379 __tuple_leaf<_Ul, _Tl>(__uses_alloc_ctor<_Tl, _Alloc>(), __a)...
380 {}
381
382 template <class _Tuple,
383 class = typename enable_if
384 <
385 __tuple_convertible<_Tuple, tuple<_Tp...>>::value
386 >::type
387 >
388 __tuple_impl(_Tuple&& __t)
389 : __tuple_leaf<_Indx, _Tp>(_STD::forward<typename tuple_element<_Indx,
390 typename __make_tuple_types<_Tuple>::type>::type>(_STD::get<_Indx>(__t)))...
391 {}
392
393 template <class _Alloc, class _Tuple,
394 class = typename enable_if
395 <
396 __tuple_convertible<_Tuple, tuple<_Tp...>>::value
397 >::type
398 >
399 __tuple_impl(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
400 : __tuple_leaf<_Indx, _Tp>(__uses_alloc_ctor<_Tp, _Alloc, typename tuple_element<_Indx,
401 typename __make_tuple_types<_Tuple>::type>::type>(), __a,
402 _STD::forward<typename tuple_element<_Indx,
403 typename __make_tuple_types<_Tuple>::type>::type>(_STD::get<_Indx>(__t)))...
404 {}
405
406 template <class _Tuple>
407 typename enable_if
408 <
409 __tuple_assignable<_Tuple, tuple<_Tp...>>::value,
410 __tuple_impl&
411 >::type
412 operator=(_Tuple&& __t)
413 {
414 __swallow(__tuple_leaf<_Indx, _Tp>::operator=(_STD::forward<typename tuple_element<_Indx,
415 typename __make_tuple_types<_Tuple>::type>::type>(_STD::get<_Indx>(__t)))...);
416 return *this;
417 }
418
419 void swap(__tuple_impl& __t)
420 {
421 __swallow(__tuple_leaf<_Indx, _Tp>::swap(static_cast<__tuple_leaf<_Indx, _Tp>&>(__t))...);
422 }
423};
424
425template <class ..._Tp>
426class tuple
427{
428 typedef __tuple_impl<typename __make_tuple_indices<sizeof...(_Tp)>::type, _Tp...> base;
429
430 base base_;
431
432 template <size_t _Jp, class ..._Up> friend
433 typename tuple_element<_Jp, tuple<_Up...>>::type& get(tuple<_Up...>&);
434 template <size_t _Jp, class ..._Up> friend
435 const typename tuple_element<_Jp, tuple<_Up...>>::type& get(const tuple<_Up...>&);
436public:
437
438 explicit tuple(const _Tp& ... __t)
439 : base_(typename __make_tuple_indices<sizeof...(_Tp)>::type(),
440 typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
441 typename __make_tuple_indices<0>::type(),
442 typename __make_tuple_types<tuple, 0>::type(),
443 __t...
444 ) {}
445
446 template <class _Alloc>
447 tuple(allocator_arg_t, const _Alloc& __a, const _Tp& ... __t)
448 : base_(allocator_arg_t(), __a,
449 typename __make_tuple_indices<sizeof...(_Tp)>::type(),
450 typename __make_tuple_types<tuple, sizeof...(_Tp)>::type(),
451 typename __make_tuple_indices<0>::type(),
452 typename __make_tuple_types<tuple, 0>::type(),
453 __t...
454 ) {}
455
456 template <class ..._Up,
457 class = typename enable_if
458 <
459 sizeof...(_Up) <= sizeof...(_Tp) &&
460 __tuple_convertible
461 <
462 tuple<_Up...>,
463 typename __make_tuple_types<tuple,
464 sizeof...(_Up) < sizeof...(_Tp) ?
465 sizeof...(_Up) :
466 sizeof...(_Tp)>::type
467 >::value
468 >::type
469 >
470 explicit
471 tuple(_Up&&... __u)
472 : base_(typename __make_tuple_indices<sizeof...(_Up)>::type(),
473 typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
474 typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
475 typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
476 _STD::forward<_Up>(__u)...) {}
477
478 template <class _Alloc, class ..._Up,
479 class = typename enable_if
480 <
481 sizeof...(_Up) <= sizeof...(_Tp) &&
482 __tuple_convertible
483 <
484 tuple<_Up...>,
485 typename __make_tuple_types<tuple,
486 sizeof...(_Up) < sizeof...(_Tp) ?
487 sizeof...(_Up) :
488 sizeof...(_Tp)>::type
489 >::value
490 >::type
491 >
492 tuple(allocator_arg_t, const _Alloc& __a, _Up&&... __u)
493 : base_(allocator_arg_t(), __a,
494 typename __make_tuple_indices<sizeof...(_Up)>::type(),
495 typename __make_tuple_types<tuple, sizeof...(_Up)>::type(),
496 typename __make_tuple_indices<sizeof...(_Tp), sizeof...(_Up)>::type(),
497 typename __make_tuple_types<tuple, sizeof...(_Tp), sizeof...(_Up)>::type(),
498 _STD::forward<_Up>(__u)...) {}
499
500 template <class _Tuple,
501 class = typename enable_if
502 <
503 __tuple_convertible<_Tuple, tuple>::value
504 >::type
505 >
506 tuple(_Tuple&& __t)
507 : base_(_STD::forward<_Tuple>(__t)) {}
508
509 template <class _Alloc, class _Tuple,
510 class = typename enable_if
511 <
512 __tuple_convertible<_Tuple, tuple>::value
513 >::type
514 >
515 tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
516 : base_(allocator_arg_t(), __a, _STD::forward<_Tuple>(__t)) {}
517
518 template <class _Tuple,
519 class = typename enable_if
520 <
521 __tuple_assignable<_Tuple, tuple>::value
522 >::type
523 >
524 tuple&
525 operator=(_Tuple&& __t)
526 {
527 base_.operator=(_STD::forward<_Tuple>(__t));
528 return *this;
529 }
530
531 void swap(tuple& __t) {base_.swap(__t.base_);}
532};
533
534template <>
535class tuple<>
536{
537public:
538 tuple() {}
539 template <class _Alloc>
540 tuple(allocator_arg_t, const _Alloc&) {}
541 template <class _Alloc>
542 tuple(allocator_arg_t, const _Alloc&, const tuple&) {}
543 template <class _U>
544 tuple(array<_U, 0>) {}
545 template <class _Alloc, class _U>
546 tuple(allocator_arg_t, const _Alloc&, array<_U, 0>) {}
547 void swap(tuple&) {}
548};
549
550template <class ..._Tp>
551inline _LIBCPP_INLINE_VISIBILITY
552void
553swap(tuple<_Tp...>& __t, tuple<_Tp...>& __u) {__t.swap(__u);}
554
555// get
556
557template <size_t _Ip, class ..._Tp>
558inline
559typename tuple_element<_Ip, tuple<_Tp...>>::type&
560get(tuple<_Tp...>& __t)
561{
562 typedef typename tuple_element<_Ip, tuple<_Tp...>>::type type;
563 return static_cast<__tuple_leaf<_Ip, type>&>(__t.base_).get();
564}
565
566template <size_t _Ip, class ..._Tp>
567inline
568const typename tuple_element<_Ip, tuple<_Tp...>>::type&
569get(const tuple<_Tp...>& __t)
570{
571 typedef typename tuple_element<_Ip, tuple<_Tp...>>::type type;
572 return static_cast<const __tuple_leaf<_Ip, type>&>(__t.base_).get();
573}
574
575// tie
576
577template <class ..._Tp>
578inline
579tuple<_Tp&...>
580tie(_Tp&... __t)
581{
582 return tuple<_Tp&...>(__t...);
583}
584
585template <class _Up>
586struct __ignore_t
587{
588 __ignore_t() {}
589 template <class _Tp>
590 __ignore_t(_Tp&&) {}
591 template <class _Tp>
592 const __ignore_t& operator=(_Tp&&) const {return *this;}
593};
594
595namespace { const __ignore_t<unsigned char> ignore = __ignore_t<unsigned char>(); }
596
597template <class _Tp> class reference_wrapper;
598
599template <class _Tp>
600struct ___make_tuple_return
601{
602 typedef _Tp type;
603};
604
605template <class _Tp>
606struct ___make_tuple_return<reference_wrapper<_Tp>>
607{
608 typedef _Tp& type;
609};
610
611template <class _Tp>
612struct __make_tuple_return
613{
614 typedef typename ___make_tuple_return<typename decay<_Tp>::type>::type type;
615};
616
617template <class... _Tp>
618inline
619tuple<typename __make_tuple_return<_Tp>::type...>
620make_tuple(_Tp&&... __t)
621{
622 return tuple<typename __make_tuple_return<_Tp>::type...>(_STD::forward<_Tp>(__t)...);
623}
624
Howard Hinnant3c1ffba2010-08-19 18:59:38 +0000625template <class... _Tp>
626inline
627tuple<_Tp&&...>
628forward_as_tuple(_Tp&&... __t)
629{
630 return tuple<_Tp&&...>(_STD::forward<_Tp>(__t)...);
631}
632
Howard Hinnantbc8d3f92010-05-11 19:42:16 +0000633template <size_t _I>
634struct __tuple_equal
635{
636 template <class _Tp, class _Up>
637 bool operator()(const _Tp& __x, const _Up& __y)
638 {
639 return __tuple_equal<_I - 1>()(__x, __y) && get<_I-1>(__x) == get<_I-1>(__y);
640 }
641};
642
643template <>
644struct __tuple_equal<0>
645{
646 template <class _Tp, class _Up>
647 bool operator()(const _Tp&, const _Up&)
648 {
649 return true;
650 }
651};
652
653template <class ..._Tp, class ..._Up>
654inline
655bool
656operator==(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
657{
658 return __tuple_equal<sizeof...(_Tp)>()(__x, __y);
659}
660
661template <class ..._Tp, class ..._Up>
662inline
663bool
664operator!=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
665{
666 return !(__x == __y);
667}
668
669template <size_t _I>
670struct __tuple_less
671{
672 template <class _Tp, class _Up>
673 bool operator()(const _Tp& __x, const _Up& __y)
674 {
675 return __tuple_less<_I-1>()(__x, __y) ||
676 (!__tuple_less<_I-1>()(__y, __x) && get<_I-1>(__x) < get<_I-1>(__y));
677 }
678};
679
680template <>
681struct __tuple_less<0>
682{
683 template <class _Tp, class _Up>
684 bool operator()(const _Tp&, const _Up&)
685 {
686 return false;
687 }
688};
689
690template <class ..._Tp, class ..._Up>
691inline
692bool
693operator<(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
694{
695 return __tuple_less<sizeof...(_Tp)>()(__x, __y);
696}
697
698template <class ..._Tp, class ..._Up>
699inline
700bool
701operator>(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
702{
703 return __y < __x;
704}
705
706template <class ..._Tp, class ..._Up>
707inline
708bool
709operator>=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
710{
711 return !(__x < __y);
712}
713
714template <class ..._Tp, class ..._Up>
715inline
716bool
717operator<=(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
718{
719 return !(__y < __x);
720}
721
722// tuple_cat
723
724template <class... _Tp, size_t ..._I1, class... _Up, size_t ..._I2>
725inline
726tuple<_Tp..., _Up...>
727__tuple_cat(const tuple<_Tp...>& __x, __tuple_indices<_I1...>, const tuple<_Up...>& __y, __tuple_indices<_I2...>)
728{
729 return tuple<_Tp..., _Up...>(get<_I1>(__x)..., get<_I2>(__y)...);
730}
731
732template <class... _Tp, class... _Up>
733inline
734tuple<_Tp..., _Up...>
735tuple_cat(const tuple<_Tp...>& __x, const tuple<_Up...>& __y)
736{
737 return __tuple_cat(__x, typename __make_tuple_indices<sizeof...(_Tp)>::type(),
738 __y, typename __make_tuple_indices<sizeof...(_Up)>::type());
739}
740
741template <class... _Tp, size_t ..._I1, class... _Up, size_t ..._I2>
742inline
743tuple<_Tp..., _Up...>
744__tuple_cat(tuple<_Tp...>&& __x, __tuple_indices<_I1...>, const tuple<_Up...>& __y, __tuple_indices<_I2...>)
745{
746 return tuple<_Tp..., _Up...>(_STD::forward<_Tp>(get<_I1>(__x))..., get<_I2>(__y)...);
747}
748
749template <class... _Tp, class... _Up>
750inline
751tuple<_Tp..., _Up...>
752tuple_cat(tuple<_Tp...>&& __x, const tuple<_Up...>& __y)
753{
754 return __tuple_cat(_STD::move(__x), typename __make_tuple_indices<sizeof...(_Tp)>::type(),
755 __y, typename __make_tuple_indices<sizeof...(_Up)>::type());
756}
757
758template <class... _Tp, size_t ..._I1, class... _Up, size_t ..._I2>
759inline
760tuple<_Tp..., _Up...>
761__tuple_cat(const tuple<_Tp...>& __x, __tuple_indices<_I1...>, tuple<_Up...>&& __y, __tuple_indices<_I2...>)
762{
763 return tuple<_Tp..., _Up...>(get<_I1>(__x)..., _STD::forward<_Up>(get<_I2>(__y))...);
764}
765
766template <class... _Tp, class... _Up>
767inline
768tuple<_Tp..., _Up...>
769tuple_cat(const tuple<_Tp...>& __x, tuple<_Up...>&& __y)
770{
771 return __tuple_cat(__x, typename __make_tuple_indices<sizeof...(_Tp)>::type(),
772 _STD::move(__y), typename __make_tuple_indices<sizeof...(_Up)>::type());
773}
774
775template <class... _Tp, size_t ..._I1, class... _Up, size_t ..._I2>
776inline
777tuple<_Tp..., _Up...>
778__tuple_cat(tuple<_Tp...>&& __x, __tuple_indices<_I1...>, tuple<_Up...>&& __y, __tuple_indices<_I2...>)
779{
780 return tuple<_Tp..., _Up...>(_STD::forward<_Tp>(get<_I1>(__x))..., _STD::forward<_Up>(get<_I2>(__y))...);
781}
782
783template <class... _Tp, class... _Up>
784inline
785tuple<_Tp..., _Up...>
786tuple_cat(tuple<_Tp...>&& __x, tuple<_Up...>&& __y)
787{
788 return __tuple_cat(_STD::move(__x), typename __make_tuple_indices<sizeof...(_Tp)>::type(),
789 _STD::move(__y), typename __make_tuple_indices<sizeof...(_Up)>::type());
790}
791
792template <class ..._Tp, class _Alloc>
793struct uses_allocator<tuple<_Tp...>, _Alloc>
794 : true_type {};
795
796template <class _InputIterator>
797inline
798_InputIterator
799begin(const std::tuple<_InputIterator, _InputIterator>& __t)
800{
801 return get<0>(__t);
802}
803
804template <class _InputIterator>
805inline
806_InputIterator
807end(const std::tuple<_InputIterator, _InputIterator>& __t)
808{
809 return get<1>(__t);
810}
811
812template <class _T1, class _T2>
813template <class... _Args1, class... _Args2, size_t ..._I1, size_t ..._I2>
814inline _LIBCPP_INLINE_VISIBILITY
815pair<_T1, _T2>::pair(piecewise_construct_t,
816 tuple<_Args1...>& __first_args, tuple<_Args2...>& __second_args,
817 __tuple_indices<_I1...>, __tuple_indices<_I2...>)
818 : first(_STD::forward<_Args1>(get<_I1>( __first_args))...),
819 second(_STD::forward<_Args2>(get<_I2>(__second_args))...)
820{
821}
822
823#endif
824
825_LIBCPP_END_NAMESPACE_STD
826
827#endif // _LIBCPP_TUPLE