3 // Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 // <http://www.gnu.org/licenses/>.
25 /** @file include/tuple
26 * This is a Standard C++ Library header.
29 #ifndef _GLIBCXX_TUPLE
30 #define _GLIBCXX_TUPLE 1
32 #pragma GCC system_header
34 #ifndef __GXX_EXPERIMENTAL_CXX0X__
35 # include <bits/c++0x_warning.h>
39 #include <bits/uses_allocator.h>
41 namespace std _GLIBCXX_VISIBILITY(default)
43 _GLIBCXX_BEGIN_NAMESPACE_VERSION
45 // Adds a const reference to a non-reference type.
46 template<typename _Tp>
48 { typedef const _Tp& type; };
50 template<typename _Tp>
51 struct __add_c_ref<_Tp&>
52 { typedef _Tp& type; };
54 // Adds a reference to a non-reference type.
55 template<typename _Tp>
57 { typedef _Tp& type; };
59 template<typename _Tp>
60 struct __add_ref<_Tp&>
61 { typedef _Tp& type; };
63 // Adds an rvalue reference to a non-reference type.
64 template<typename _Tp>
66 { typedef _Tp&& type; };
68 template<typename _Tp>
69 struct __add_r_ref<_Tp&>
70 { typedef _Tp& type; };
72 template<std::size_t _Idx, typename _Head, bool _IsEmptyNotFinal>
75 template<std::size_t _Idx, typename _Head>
76 struct _Head_base<_Idx, _Head, true>
79 constexpr _Head_base()
82 constexpr _Head_base(const _Head& __h)
85 template<typename _UHead, typename = typename
86 enable_if<!is_convertible<_UHead,
87 __uses_alloc_base>::value>::type>
88 constexpr _Head_base(_UHead&& __h)
89 : _Head(std::forward<_UHead>(__h)) { }
91 _Head_base(__uses_alloc0)
94 template<typename _Alloc>
95 _Head_base(__uses_alloc1<_Alloc> __a)
96 : _Head(allocator_arg, *__a._M_a) { }
98 template<typename _Alloc>
99 _Head_base(__uses_alloc2<_Alloc> __a)
100 : _Head(*__a._M_a) { }
102 template<typename _UHead>
103 _Head_base(__uses_alloc0, _UHead&& __uhead)
104 : _Head(std::forward<_UHead>(__uhead)) { }
106 template<typename _Alloc, typename _UHead>
107 _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
108 : _Head(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { }
110 template<typename _Alloc, typename _UHead>
111 _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
112 : _Head(std::forward<_UHead>(__uhead), *__a._M_a) { }
114 static constexpr _Head&
115 _M_head(_Head_base& __b) noexcept { return __b; }
117 static constexpr const _Head&
118 _M_head(const _Head_base& __b) noexcept { return __b; }
121 template<std::size_t _Idx, typename _Head>
122 struct _Head_base<_Idx, _Head, false>
124 constexpr _Head_base()
127 constexpr _Head_base(const _Head& __h)
128 : _M_head_impl(__h) { }
130 template<typename _UHead, typename = typename
131 enable_if<!is_convertible<_UHead,
132 __uses_alloc_base>::value>::type>
133 constexpr _Head_base(_UHead&& __h)
134 : _M_head_impl(std::forward<_UHead>(__h)) { }
136 _Head_base(__uses_alloc0)
139 template<typename _Alloc>
140 _Head_base(__uses_alloc1<_Alloc> __a)
141 : _M_head_impl(allocator_arg, *__a._M_a) { }
143 template<typename _Alloc>
144 _Head_base(__uses_alloc2<_Alloc> __a)
145 : _M_head_impl(*__a._M_a) { }
147 template<typename _UHead>
148 _Head_base(__uses_alloc0, _UHead&& __uhead)
149 : _M_head_impl(std::forward<_UHead>(__uhead)) { }
151 template<typename _Alloc, typename _UHead>
152 _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
153 : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead))
156 template<typename _Alloc, typename _UHead>
157 _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
158 : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { }
160 static constexpr _Head&
161 _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; }
163 static constexpr const _Head&
164 _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; }
170 * Contains the actual implementation of the @c tuple template, stored
171 * as a recursive inheritance hierarchy from the first element (most
172 * derived class) to the last (least derived class). The @c Idx
173 * parameter gives the 0-based index of the element stored at this
174 * point in the hierarchy; we use it to implement a constant-time
177 template<std::size_t _Idx, typename... _Elements>
181 * Zero-element tuple implementation. This is the basis case for the
182 * inheritance recursion.
184 template<std::size_t _Idx>
185 struct _Tuple_impl<_Idx>
187 template<std::size_t, typename...> friend class _Tuple_impl;
189 _Tuple_impl() = default;
191 template<typename _Alloc>
192 _Tuple_impl(allocator_arg_t, const _Alloc&) { }
194 template<typename _Alloc>
195 _Tuple_impl(allocator_arg_t, const _Alloc&, const _Tuple_impl&) { }
197 template<typename _Alloc>
198 _Tuple_impl(allocator_arg_t, const _Alloc&, _Tuple_impl&&) { }
201 void _M_swap(_Tuple_impl&) noexcept { /* no-op */ }
204 // Use the Empty Base-class Optimization for empty, non-final types.
205 template<typename _Tp>
206 using __empty_not_final
207 = typename conditional<__is_final(_Tp), false_type, is_empty<_Tp>>::type;
210 * Recursive tuple implementation. Here we store the @c Head element
211 * and derive from a @c Tuple_impl containing the remaining elements
212 * (which contains the @c Tail).
214 template<std::size_t _Idx, typename _Head, typename... _Tail>
215 struct _Tuple_impl<_Idx, _Head, _Tail...>
216 : public _Tuple_impl<_Idx + 1, _Tail...>,
217 private _Head_base<_Idx, _Head, __empty_not_final<_Head>::value>
219 template<std::size_t, typename...> friend class _Tuple_impl;
221 typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
222 typedef _Head_base<_Idx, _Head, __empty_not_final<_Head>::value> _Base;
224 static constexpr _Head&
225 _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
227 static constexpr const _Head&
228 _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
230 static constexpr _Inherited&
231 _M_tail(_Tuple_impl& __t) noexcept { return __t; }
233 static constexpr const _Inherited&
234 _M_tail(const _Tuple_impl& __t) noexcept { return __t; }
236 constexpr _Tuple_impl()
237 : _Inherited(), _Base() { }
240 constexpr _Tuple_impl(const _Head& __head, const _Tail&... __tail)
241 : _Inherited(__tail...), _Base(__head) { }
243 template<typename _UHead, typename... _UTail, typename = typename
244 enable_if<sizeof...(_Tail) == sizeof...(_UTail)>::type>
246 constexpr _Tuple_impl(_UHead&& __head, _UTail&&... __tail)
247 : _Inherited(std::forward<_UTail>(__tail)...),
248 _Base(std::forward<_UHead>(__head)) { }
250 constexpr _Tuple_impl(const _Tuple_impl&) = default;
253 _Tuple_impl(_Tuple_impl&& __in)
254 noexcept(__and_<is_nothrow_move_constructible<_Head>,
255 is_nothrow_move_constructible<_Inherited>>::value)
256 : _Inherited(std::move(_M_tail(__in))),
257 _Base(std::forward<_Head>(_M_head(__in))) { }
259 template<typename... _UElements>
260 constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in)
261 : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
262 _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { }
264 template<typename _UHead, typename... _UTails>
265 constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
266 : _Inherited(std::move
267 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
268 _Base(std::forward<_UHead>
269 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { }
271 template<typename _Alloc>
272 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
273 : _Inherited(__tag, __a),
274 _Base(__use_alloc<_Head>(__a)) { }
276 template<typename _Alloc>
277 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
278 const _Head& __head, const _Tail&... __tail)
279 : _Inherited(__tag, __a, __tail...),
280 _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { }
282 template<typename _Alloc, typename _UHead, typename... _UTail,
283 typename = typename enable_if<sizeof...(_Tail)
284 == sizeof...(_UTail)>::type>
285 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
286 _UHead&& __head, _UTail&&... __tail)
287 : _Inherited(__tag, __a, std::forward<_UTail>(__tail)...),
288 _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
289 std::forward<_UHead>(__head)) { }
291 template<typename _Alloc>
292 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
293 const _Tuple_impl& __in)
294 : _Inherited(__tag, __a, _M_tail(__in)),
295 _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { }
297 template<typename _Alloc>
298 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
300 : _Inherited(__tag, __a, std::move(_M_tail(__in))),
301 _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
302 std::forward<_Head>(_M_head(__in))) { }
304 template<typename _Alloc, typename... _UElements>
305 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
306 const _Tuple_impl<_Idx, _UElements...>& __in)
307 : _Inherited(__tag, __a,
308 _Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
309 _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
310 _Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { }
312 template<typename _Alloc, typename _UHead, typename... _UTails>
313 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
314 _Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
315 : _Inherited(__tag, __a, std::move
316 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
317 _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
319 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { }
322 operator=(const _Tuple_impl& __in)
324 _M_head(*this) = _M_head(__in);
325 _M_tail(*this) = _M_tail(__in);
330 operator=(_Tuple_impl&& __in)
331 noexcept(__and_<is_nothrow_move_assignable<_Head>,
332 is_nothrow_move_assignable<_Inherited>>::value)
334 _M_head(*this) = std::forward<_Head>(_M_head(__in));
335 _M_tail(*this) = std::move(_M_tail(__in));
339 template<typename... _UElements>
341 operator=(const _Tuple_impl<_Idx, _UElements...>& __in)
343 _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in);
344 _M_tail(*this) = _Tuple_impl<_Idx, _UElements...>::_M_tail(__in);
348 template<typename _UHead, typename... _UTails>
350 operator=(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
352 _M_head(*this) = std::forward<_UHead>
353 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in));
354 _M_tail(*this) = std::move
355 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in));
361 _M_swap(_Tuple_impl& __in)
362 noexcept(noexcept(swap(std::declval<_Head&>(),
363 std::declval<_Head&>()))
364 && noexcept(_M_tail(__in)._M_swap(_M_tail(__in))))
367 swap(_M_head(*this), _M_head(__in));
368 _Inherited::_M_swap(_M_tail(__in));
372 /// Primary class template, tuple
373 template<typename... _Elements>
374 class tuple : public _Tuple_impl<0, _Elements...>
376 typedef _Tuple_impl<0, _Elements...> _Inherited;
383 constexpr tuple(const _Elements&... __elements)
384 : _Inherited(__elements...) { }
386 template<typename... _UElements, typename = typename
387 enable_if<__and_<is_convertible<_UElements,
388 _Elements>...>::value>::type>
390 constexpr tuple(_UElements&&... __elements)
391 : _Inherited(std::forward<_UElements>(__elements)...) { }
393 constexpr tuple(const tuple&) = default;
395 constexpr tuple(tuple&&) = default;
397 template<typename... _UElements, typename = typename
398 enable_if<__and_<is_convertible<const _UElements&,
399 _Elements>...>::value>::type>
400 constexpr tuple(const tuple<_UElements...>& __in)
401 : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
404 template<typename... _UElements, typename = typename
405 enable_if<__and_<is_convertible<_UElements,
406 _Elements>...>::value>::type>
407 constexpr tuple(tuple<_UElements...>&& __in)
408 : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
410 // Allocator-extended constructors.
412 template<typename _Alloc>
413 tuple(allocator_arg_t __tag, const _Alloc& __a)
414 : _Inherited(__tag, __a) { }
416 template<typename _Alloc>
417 tuple(allocator_arg_t __tag, const _Alloc& __a,
418 const _Elements&... __elements)
419 : _Inherited(__tag, __a, __elements...) { }
421 template<typename _Alloc, typename... _UElements, typename = typename
422 enable_if<sizeof...(_UElements)
423 == sizeof...(_Elements)>::type>
424 tuple(allocator_arg_t __tag, const _Alloc& __a,
425 _UElements&&... __elements)
426 : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
429 template<typename _Alloc>
430 tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
431 : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
433 template<typename _Alloc>
434 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
435 : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
437 template<typename _Alloc, typename... _UElements, typename = typename
438 enable_if<sizeof...(_UElements)
439 == sizeof...(_Elements)>::type>
440 tuple(allocator_arg_t __tag, const _Alloc& __a,
441 const tuple<_UElements...>& __in)
442 : _Inherited(__tag, __a,
443 static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
446 template<typename _Alloc, typename... _UElements, typename = typename
447 enable_if<sizeof...(_UElements)
448 == sizeof...(_Elements)>::type>
449 tuple(allocator_arg_t __tag, const _Alloc& __a,
450 tuple<_UElements...>&& __in)
451 : _Inherited(__tag, __a,
452 static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
456 operator=(const tuple& __in)
458 static_cast<_Inherited&>(*this) = __in;
463 operator=(tuple&& __in)
464 noexcept(is_nothrow_move_assignable<_Inherited>::value)
466 static_cast<_Inherited&>(*this) = std::move(__in);
470 template<typename... _UElements, typename = typename
471 enable_if<sizeof...(_UElements)
472 == sizeof...(_Elements)>::type>
474 operator=(const tuple<_UElements...>& __in)
476 static_cast<_Inherited&>(*this) = __in;
480 template<typename... _UElements, typename = typename
481 enable_if<sizeof...(_UElements)
482 == sizeof...(_Elements)>::type>
484 operator=(tuple<_UElements...>&& __in)
486 static_cast<_Inherited&>(*this) = std::move(__in);
492 noexcept(noexcept(__in._M_swap(__in)))
493 { _Inherited::_M_swap(__in); }
496 // Explicit specialization, zero-element tuple.
501 void swap(tuple&) noexcept { /* no-op */ }
504 /// Partial specialization, 2-element tuple.
505 /// Includes construction and assignment from a pair.
506 template<typename _T1, typename _T2>
507 class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
509 typedef _Tuple_impl<0, _T1, _T2> _Inherited;
516 constexpr tuple(const _T1& __a1, const _T2& __a2)
517 : _Inherited(__a1, __a2) { }
519 template<typename _U1, typename _U2, typename = typename
520 enable_if<__and_<is_convertible<_U1, _T1>,
521 is_convertible<_U2, _T2>>::value>::type>
523 constexpr tuple(_U1&& __a1, _U2&& __a2)
524 : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
526 constexpr tuple(const tuple&) = default;
528 constexpr tuple(tuple&&) = default;
530 template<typename _U1, typename _U2, typename = typename
531 enable_if<__and_<is_convertible<const _U1&, _T1>,
532 is_convertible<const _U2&, _T2>>::value>::type>
533 constexpr tuple(const tuple<_U1, _U2>& __in)
534 : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
536 template<typename _U1, typename _U2, typename = typename
537 enable_if<__and_<is_convertible<_U1, _T1>,
538 is_convertible<_U2, _T2>>::value>::type>
539 constexpr tuple(tuple<_U1, _U2>&& __in)
540 : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
542 template<typename _U1, typename _U2, typename = typename
543 enable_if<__and_<is_convertible<const _U1&, _T1>,
544 is_convertible<const _U2&, _T2>>::value>::type>
545 constexpr tuple(const pair<_U1, _U2>& __in)
546 : _Inherited(__in.first, __in.second) { }
548 template<typename _U1, typename _U2, typename = typename
549 enable_if<__and_<is_convertible<_U1, _T1>,
550 is_convertible<_U2, _T2>>::value>::type>
551 constexpr tuple(pair<_U1, _U2>&& __in)
552 : _Inherited(std::forward<_U1>(__in.first),
553 std::forward<_U2>(__in.second)) { }
555 // Allocator-extended constructors.
557 template<typename _Alloc>
558 tuple(allocator_arg_t __tag, const _Alloc& __a)
559 : _Inherited(__tag, __a) { }
561 template<typename _Alloc>
562 tuple(allocator_arg_t __tag, const _Alloc& __a,
563 const _T1& __a1, const _T2& __a2)
564 : _Inherited(__tag, __a, __a1, __a2) { }
566 template<typename _Alloc, typename _U1, typename _U2>
567 tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2)
568 : _Inherited(__tag, __a, std::forward<_U1>(__a1),
569 std::forward<_U2>(__a2)) { }
571 template<typename _Alloc>
572 tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
573 : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
575 template<typename _Alloc>
576 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
577 : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
579 template<typename _Alloc, typename _U1, typename _U2>
580 tuple(allocator_arg_t __tag, const _Alloc& __a,
581 const tuple<_U1, _U2>& __in)
582 : _Inherited(__tag, __a,
583 static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
586 template<typename _Alloc, typename _U1, typename _U2>
587 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
588 : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
591 template<typename _Alloc, typename _U1, typename _U2>
592 tuple(allocator_arg_t __tag, const _Alloc& __a,
593 const pair<_U1, _U2>& __in)
594 : _Inherited(__tag, __a, __in.first, __in.second) { }
596 template<typename _Alloc, typename _U1, typename _U2>
597 tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
598 : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
599 std::forward<_U2>(__in.second)) { }
602 operator=(const tuple& __in)
604 static_cast<_Inherited&>(*this) = __in;
609 operator=(tuple&& __in)
610 noexcept(is_nothrow_move_assignable<_Inherited>::value)
612 static_cast<_Inherited&>(*this) = std::move(__in);
616 template<typename _U1, typename _U2>
618 operator=(const tuple<_U1, _U2>& __in)
620 static_cast<_Inherited&>(*this) = __in;
624 template<typename _U1, typename _U2>
626 operator=(tuple<_U1, _U2>&& __in)
628 static_cast<_Inherited&>(*this) = std::move(__in);
632 template<typename _U1, typename _U2>
634 operator=(const pair<_U1, _U2>& __in)
636 this->_M_head(*this) = __in.first;
637 this->_M_tail(*this)._M_head(*this) = __in.second;
641 template<typename _U1, typename _U2>
643 operator=(pair<_U1, _U2>&& __in)
645 this->_M_head(*this) = std::forward<_U1>(__in.first);
646 this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second);
652 noexcept(noexcept(__in._M_swap(__in)))
653 { _Inherited::_M_swap(__in); }
657 /// Gives the type of the ith element of a given tuple type.
658 template<std::size_t __i, typename _Tp>
659 struct tuple_element;
662 * Recursive case for tuple_element: strip off the first element in
663 * the tuple and retrieve the (i-1)th element of the remaining tuple.
665 template<std::size_t __i, typename _Head, typename... _Tail>
666 struct tuple_element<__i, tuple<_Head, _Tail...> >
667 : tuple_element<__i - 1, tuple<_Tail...> > { };
670 * Basis case for tuple_element: The first element is the one we're seeking.
672 template<typename _Head, typename... _Tail>
673 struct tuple_element<0, tuple<_Head, _Tail...> >
678 template<std::size_t __i, typename _Tp>
679 struct tuple_element<__i, const _Tp>
682 add_const<typename tuple_element<__i, _Tp>::type>::type type;
685 template<std::size_t __i, typename _Tp>
686 struct tuple_element<__i, volatile _Tp>
689 add_volatile<typename tuple_element<__i, _Tp>::type>::type type;
692 template<std::size_t __i, typename _Tp>
693 struct tuple_element<__i, const volatile _Tp>
696 add_cv<typename tuple_element<__i, _Tp>::type>::type type;
699 /// Finds the size of a given tuple type.
700 template<typename _Tp>
703 template<typename _Tp>
704 struct tuple_size<const _Tp>
705 : public integral_constant<
706 typename remove_cv<decltype(tuple_size<_Tp>::value)>::type,
707 tuple_size<_Tp>::value> { };
709 template<typename _Tp>
710 struct tuple_size<volatile _Tp>
711 : public integral_constant<
712 typename remove_cv<decltype(tuple_size<_Tp>::value)>::type,
713 tuple_size<_Tp>::value> { };
715 template<typename _Tp>
716 struct tuple_size<const volatile _Tp>
717 : public integral_constant<
718 typename remove_cv<decltype(tuple_size<_Tp>::value)>::type,
719 tuple_size<_Tp>::value> { };
722 template<typename... _Elements>
723 struct tuple_size<tuple<_Elements...>>
724 : public integral_constant<std::size_t, sizeof...(_Elements)> { };
726 template<std::size_t __i, typename _Head, typename... _Tail>
727 constexpr typename __add_ref<_Head>::type
728 __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
729 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
731 template<std::size_t __i, typename _Head, typename... _Tail>
732 constexpr typename __add_c_ref<_Head>::type
733 __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
734 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
736 // Return a reference (const reference, rvalue reference) to the ith element
737 // of a tuple. Any const or non-const ref elements are returned with their
739 template<std::size_t __i, typename... _Elements>
740 constexpr typename __add_ref<
741 typename tuple_element<__i, tuple<_Elements...>>::type
743 get(tuple<_Elements...>& __t) noexcept
744 { return __get_helper<__i>(__t); }
746 template<std::size_t __i, typename... _Elements>
747 constexpr typename __add_c_ref<
748 typename tuple_element<__i, tuple<_Elements...>>::type
750 get(const tuple<_Elements...>& __t) noexcept
751 { return __get_helper<__i>(__t); }
753 template<std::size_t __i, typename... _Elements>
754 constexpr typename __add_r_ref<
755 typename tuple_element<__i, tuple<_Elements...>>::type
757 get(tuple<_Elements...>&& __t) noexcept
758 { return std::forward<typename tuple_element<__i,
759 tuple<_Elements...>>::type&&>(get<__i>(__t)); }
761 // This class helps construct the various comparison operations on tuples
762 template<std::size_t __check_equal_size, std::size_t __i, std::size_t __j,
763 typename _Tp, typename _Up>
764 struct __tuple_compare;
766 template<std::size_t __i, std::size_t __j, typename _Tp, typename _Up>
767 struct __tuple_compare<0, __i, __j, _Tp, _Up>
770 __eq(const _Tp& __t, const _Up& __u)
772 return (get<__i>(__t) == get<__i>(__u) &&
773 __tuple_compare<0, __i + 1, __j, _Tp, _Up>::__eq(__t, __u));
777 __less(const _Tp& __t, const _Up& __u)
779 return ((get<__i>(__t) < get<__i>(__u))
780 || !(get<__i>(__u) < get<__i>(__t)) &&
781 __tuple_compare<0, __i + 1, __j, _Tp, _Up>::__less(__t, __u));
785 template<std::size_t __i, typename _Tp, typename _Up>
786 struct __tuple_compare<0, __i, __i, _Tp, _Up>
789 __eq(const _Tp&, const _Up&) { return true; }
792 __less(const _Tp&, const _Up&) { return false; }
795 template<typename... _TElements, typename... _UElements>
797 operator==(const tuple<_TElements...>& __t,
798 const tuple<_UElements...>& __u)
800 typedef tuple<_TElements...> _Tp;
801 typedef tuple<_UElements...> _Up;
802 return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value,
803 0, tuple_size<_Tp>::value, _Tp, _Up>::__eq(__t, __u));
806 template<typename... _TElements, typename... _UElements>
808 operator<(const tuple<_TElements...>& __t,
809 const tuple<_UElements...>& __u)
811 typedef tuple<_TElements...> _Tp;
812 typedef tuple<_UElements...> _Up;
813 return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value,
814 0, tuple_size<_Tp>::value, _Tp, _Up>::__less(__t, __u));
817 template<typename... _TElements, typename... _UElements>
819 operator!=(const tuple<_TElements...>& __t,
820 const tuple<_UElements...>& __u)
821 { return !(__t == __u); }
823 template<typename... _TElements, typename... _UElements>
825 operator>(const tuple<_TElements...>& __t,
826 const tuple<_UElements...>& __u)
827 { return __u < __t; }
829 template<typename... _TElements, typename... _UElements>
831 operator<=(const tuple<_TElements...>& __t,
832 const tuple<_UElements...>& __u)
833 { return !(__u < __t); }
835 template<typename... _TElements, typename... _UElements>
837 operator>=(const tuple<_TElements...>& __t,
838 const tuple<_UElements...>& __u)
839 { return !(__t < __u); }
842 template<typename... _Elements>
843 constexpr tuple<typename __decay_and_strip<_Elements>::__type...>
844 make_tuple(_Elements&&... __args)
846 typedef tuple<typename __decay_and_strip<_Elements>::__type...>
848 return __result_type(std::forward<_Elements>(__args)...);
851 template<typename... _Elements>
852 constexpr tuple<_Elements&&...>
853 forward_as_tuple(_Elements&&... __args) noexcept
854 { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
857 template<typename, std::size_t> struct array;
859 template<std::size_t _Int, typename _Tp, std::size_t _Nm>
860 constexpr _Tp& get(array<_Tp, _Nm>&) noexcept;
862 template<std::size_t _Int, typename _Tp, std::size_t _Nm>
863 constexpr _Tp&& get(array<_Tp, _Nm>&&) noexcept;
865 template<std::size_t _Int, typename _Tp, std::size_t _Nm>
866 constexpr const _Tp& get(const array<_Tp, _Nm>&) noexcept;
869 struct __is_tuple_like_impl : false_type
872 template<typename... _Tps>
873 struct __is_tuple_like_impl<tuple<_Tps...>> : true_type
876 template<typename _T1, typename _T2>
877 struct __is_tuple_like_impl<pair<_T1, _T2>> : true_type
880 template<typename _Tp, std::size_t _Nm>
881 struct __is_tuple_like_impl<array<_Tp, _Nm>> : true_type
884 // Internal type trait that allows us to sfinae-protect tuple_cat.
885 template<typename _Tp>
886 struct __is_tuple_like
887 : public __is_tuple_like_impl<typename std::remove_cv
888 <typename std::remove_reference<_Tp>::type>::type>::type
891 // Stores a tuple of indices. Also used by bind() to extract the elements
893 template<std::size_t... _Indexes>
896 typedef _Index_tuple<_Indexes..., sizeof...(_Indexes)> __next;
899 // Builds an _Index_tuple<0, 1, 2, ..., _Num-1>.
900 template<std::size_t _Num>
901 struct _Build_index_tuple
903 typedef typename _Build_index_tuple<_Num - 1>::__type::__next __type;
907 struct _Build_index_tuple<0>
909 typedef _Index_tuple<> __type;
912 template<std::size_t, typename, typename, std::size_t>
913 struct __make_tuple_impl;
915 template<std::size_t _Idx, typename _Tuple, typename... _Tp,
917 struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm>
919 typedef typename __make_tuple_impl<_Idx + 1, tuple<_Tp...,
920 typename std::tuple_element<_Idx, _Tuple>::type>, _Tuple, _Nm>::__type
924 template<std::size_t _Nm, typename _Tuple, typename... _Tp>
925 struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm>
927 typedef tuple<_Tp...> __type;
930 template<typename _Tuple>
931 struct __do_make_tuple
932 : public __make_tuple_impl<0, tuple<>, _Tuple,
933 std::tuple_size<_Tuple>::value>
936 // Returns the std::tuple equivalent of a tuple-like type.
937 template<typename _Tuple>
939 : public __do_make_tuple<typename std::remove_cv
940 <typename std::remove_reference<_Tuple>::type>::type>
943 // Combines several std::tuple's into a single one.
944 template<typename...>
945 struct __combine_tuples;
948 struct __combine_tuples<>
950 typedef tuple<> __type;
953 template<typename... _Ts>
954 struct __combine_tuples<tuple<_Ts...>>
956 typedef tuple<_Ts...> __type;
959 template<typename... _T1s, typename... _T2s, typename... _Rem>
960 struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...>
962 typedef typename __combine_tuples<tuple<_T1s..., _T2s...>,
963 _Rem...>::__type __type;
966 // Computes the result type of tuple_cat given a set of tuple-like types.
967 template<typename... _Tpls>
968 struct __tuple_cat_result
970 typedef typename __combine_tuples
971 <typename __make_tuple<_Tpls>::__type...>::__type __type;
974 // Helper to determine the index set for the first tuple-like
975 // type of a given set.
976 template<typename...>
977 struct __make_1st_indices;
980 struct __make_1st_indices<>
982 typedef std::_Index_tuple<> __type;
985 template<typename _Tp, typename... _Tpls>
986 struct __make_1st_indices<_Tp, _Tpls...>
988 typedef typename std::_Build_index_tuple<std::tuple_size<
989 typename std::remove_reference<_Tp>::type>::value>::__type __type;
992 // Performs the actual concatenation by step-wise expanding tuple-like
993 // objects into the elements, which are finally forwarded into the
995 template<typename _Ret, typename _Indices, typename... _Tpls>
996 struct __tuple_concater;
998 template<typename _Ret, std::size_t... _Is, typename _Tp, typename... _Tpls>
999 struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...>
1001 template<typename... _Us>
1002 static constexpr _Ret
1003 _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us)
1005 typedef typename __make_1st_indices<_Tpls...>::__type __idx;
1006 typedef __tuple_concater<_Ret, __idx, _Tpls...> __next;
1007 return __next::_S_do(std::forward<_Tpls>(__tps)...,
1008 std::forward<_Us>(__us)...,
1009 std::get<_Is>(std::forward<_Tp>(__tp))...);
1013 template<typename _Ret>
1014 struct __tuple_concater<_Ret, std::_Index_tuple<>>
1016 template<typename... _Us>
1017 static constexpr _Ret
1018 _S_do(_Us&&... __us)
1020 return _Ret(std::forward<_Us>(__us)...);
1024 template<typename... _Tpls, typename = typename
1025 enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type>
1027 tuple_cat(_Tpls&&... __tpls)
1028 -> typename __tuple_cat_result<_Tpls...>::__type
1030 typedef typename __tuple_cat_result<_Tpls...>::__type __ret;
1031 typedef typename __make_1st_indices<_Tpls...>::__type __idx;
1032 typedef __tuple_concater<__ret, __idx, _Tpls...> __concater;
1033 return __concater::_S_do(std::forward<_Tpls>(__tpls)...);
1036 template<typename... _Elements>
1037 inline tuple<_Elements&...>
1038 tie(_Elements&... __args) noexcept
1039 { return tuple<_Elements&...>(__args...); }
1041 template<typename... _Elements>
1043 swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
1044 noexcept(noexcept(__x.swap(__y)))
1047 // A class (and instance) which can be used in 'tie' when an element
1048 // of a tuple is not required
1049 struct _Swallow_assign
1052 const _Swallow_assign&
1053 operator=(const _Tp&) const
1057 const _Swallow_assign ignore{};
1059 /// Partial specialization for tuples
1060 template<typename... _Types, typename _Alloc>
1061 struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { };
1063 // See stl_pair.h...
1064 template<class _T1, class _T2>
1065 template<typename... _Args1, typename... _Args2>
1068 pair(piecewise_construct_t,
1069 tuple<_Args1...> __first, tuple<_Args2...> __second)
1070 : pair(__first, __second,
1071 typename _Build_index_tuple<sizeof...(_Args1)>::__type(),
1072 typename _Build_index_tuple<sizeof...(_Args2)>::__type())
1075 template<class _T1, class _T2>
1076 template<typename... _Args1, std::size_t... _Indexes1,
1077 typename... _Args2, std::size_t... _Indexes2>
1080 pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2,
1081 _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)
1082 : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...),
1083 second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
1086 _GLIBCXX_END_NAMESPACE_VERSION
1089 #endif // __GXX_EXPERIMENTAL_CXX0X__
1091 #endif // _GLIBCXX_TUPLE