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