OSDN Git Service

682e3c92a4721dbd89d28a49d423eaabcda9f6f0
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / std / tuple
1 // <tuple> -*- C++ -*-
2
3 // Copyright (C) 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
4 //
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)
9 // any later version.
10
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.
15
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.
19
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/>.
24
25 /** @file include/tuple
26  *  This is a Standard C++ Library header.
27  */
28
29 #ifndef _GLIBCXX_TUPLE
30 #define _GLIBCXX_TUPLE 1
31
32 #pragma GCC system_header
33
34 #ifndef __GXX_EXPERIMENTAL_CXX0X__
35 # include <bits/c++0x_warning.h>
36 #else
37
38 #include <utility>
39
40 namespace std _GLIBCXX_VISIBILITY(default)
41 {
42 _GLIBCXX_BEGIN_NAMESPACE_VERSION
43
44   // Adds a const reference to a non-reference type.
45   template<typename _Tp>
46     struct __add_c_ref
47     { typedef const _Tp& type; };
48
49   template<typename _Tp>
50     struct __add_c_ref<_Tp&>
51     { typedef _Tp& type; };
52
53   // Adds a reference to a non-reference type.
54   template<typename _Tp>
55     struct __add_ref
56     { typedef _Tp& type; };
57
58   template<typename _Tp>
59     struct __add_ref<_Tp&>
60     { typedef _Tp& type; };
61
62   // Adds an rvalue reference to a non-reference type.
63   template<typename _Tp>
64     struct __add_r_ref
65     { typedef _Tp&& type; };
66
67   template<typename _Tp>
68     struct __add_r_ref<_Tp&>
69     { typedef _Tp& type; };
70
71   template<std::size_t _Idx, typename _Head, bool _IsEmpty>
72     struct _Head_base;
73
74   template<std::size_t _Idx, typename _Head>
75     struct _Head_base<_Idx, _Head, true>
76     : public _Head
77     {
78       constexpr _Head_base()
79       : _Head() { }
80
81       constexpr _Head_base(const _Head& __h)
82       : _Head(__h) { }
83
84       template<typename _UHead>
85         _Head_base(_UHead&& __h)
86         : _Head(std::forward<_UHead>(__h)) { }
87
88       _Head&       _M_head() noexcept       { return *this; }
89       const _Head& _M_head() const noexcept { return *this; }
90     };
91
92   template<std::size_t _Idx, typename _Head>
93     struct _Head_base<_Idx, _Head, false>
94     {
95       constexpr _Head_base()
96       : _M_head_impl() { }
97
98       constexpr _Head_base(const _Head& __h)
99       : _M_head_impl(__h) { }
100
101       template<typename _UHead>
102         _Head_base(_UHead&& __h)
103         : _M_head_impl(std::forward<_UHead>(__h)) { }
104
105       _Head&       _M_head() noexcept       { return _M_head_impl; }
106       const _Head& _M_head() const noexcept { return _M_head_impl; }        
107
108       _Head _M_head_impl; 
109     };
110
111   /**
112    * Contains the actual implementation of the @c tuple template, stored
113    * as a recursive inheritance hierarchy from the first element (most
114    * derived class) to the last (least derived class). The @c Idx
115    * parameter gives the 0-based index of the element stored at this
116    * point in the hierarchy; we use it to implement a constant-time
117    * get() operation.
118    */
119   template<std::size_t _Idx, typename... _Elements>
120     struct _Tuple_impl; 
121
122   /**
123    * Zero-element tuple implementation. This is the basis case for the 
124    * inheritance recursion.
125    */
126   template<std::size_t _Idx>
127     struct _Tuple_impl<_Idx>
128     {
129       template<std::size_t, typename...> friend class _Tuple_impl;
130
131     protected:
132       void _M_swap(_Tuple_impl&) noexcept { /* no-op */ }
133     };
134
135   /**
136    * Recursive tuple implementation. Here we store the @c Head element
137    * and derive from a @c Tuple_impl containing the remaining elements
138    * (which contains the @c Tail).
139    */
140   template<std::size_t _Idx, typename _Head, typename... _Tail>
141     struct _Tuple_impl<_Idx, _Head, _Tail...>
142     : public _Tuple_impl<_Idx + 1, _Tail...>,
143       private _Head_base<_Idx, _Head, std::is_empty<_Head>::value>
144     {
145       template<std::size_t, typename...> friend class _Tuple_impl;
146
147       typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
148       typedef _Head_base<_Idx, _Head, std::is_empty<_Head>::value> _Base;
149
150       _Head&            _M_head() noexcept       { return _Base::_M_head(); }
151       const _Head&      _M_head() const noexcept { return _Base::_M_head(); }
152
153       _Inherited&       _M_tail() noexcept       { return *this; }
154       const _Inherited& _M_tail() const noexcept { return *this; }
155
156       constexpr _Tuple_impl()
157       : _Inherited(), _Base() { }
158
159       explicit 
160       constexpr _Tuple_impl(const _Head& __head, const _Tail&... __tail)
161       : _Inherited(__tail...), _Base(__head) { }
162
163       template<typename _UHead, typename... _UTail> 
164         explicit
165         _Tuple_impl(_UHead&& __head, _UTail&&... __tail)
166         : _Inherited(std::forward<_UTail>(__tail)...),
167           _Base(std::forward<_UHead>(__head)) { }
168
169       constexpr _Tuple_impl(const _Tuple_impl&) = default;
170
171       _Tuple_impl(_Tuple_impl&& __in)
172       : _Inherited(std::move(__in._M_tail())), 
173         _Base(std::forward<_Head>(__in._M_head())) { }
174
175       template<typename... _UElements>
176         _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in)
177         : _Inherited(__in._M_tail()), _Base(__in._M_head()) { }
178
179       template<typename _UHead, typename... _UTails>
180         _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
181         : _Inherited(std::move(__in._M_tail())),
182           _Base(std::forward<_UHead>(__in._M_head())) { }
183
184       _Tuple_impl&
185       operator=(const _Tuple_impl& __in)
186       {
187         _M_head() = __in._M_head();
188         _M_tail() = __in._M_tail();
189         return *this;
190       }
191
192       _Tuple_impl&
193       operator=(_Tuple_impl&& __in)
194       noexcept(is_nothrow_move_assignable<_Head>::value
195                && is_nothrow_move_assignable<_Inherited>::value)
196       {
197         _M_head() = std::forward<_Head>(__in._M_head());
198         _M_tail() = std::move(__in._M_tail());
199         return *this;
200       }
201
202       template<typename... _UElements>
203         _Tuple_impl&
204         operator=(const _Tuple_impl<_Idx, _UElements...>& __in)
205         {
206           _M_head() = __in._M_head();
207           _M_tail() = __in._M_tail();
208           return *this;
209         }
210
211       template<typename _UHead, typename... _UTails>
212         _Tuple_impl&
213         operator=(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
214         {
215           _M_head() = std::forward<_UHead>(__in._M_head());
216           _M_tail() = std::move(__in._M_tail());
217           return *this;
218         }
219
220     protected:
221       void
222       _M_swap(_Tuple_impl& __in)
223       noexcept(noexcept(swap(std::declval<_Head&>(),
224                              std::declval<_Head&>()))
225                && noexcept(__in._M_tail()._M_swap(__in._M_tail())))
226       {
227         using std::swap;
228         swap(this->_M_head(), __in._M_head());
229         _Inherited::_M_swap(__in._M_tail());
230       }
231     };
232
233   /// tuple
234   template<typename... _Elements> 
235     class tuple : public _Tuple_impl<0, _Elements...>
236     {
237       typedef _Tuple_impl<0, _Elements...> _Inherited;
238
239     public:
240       constexpr tuple()
241       : _Inherited() { }
242
243       explicit
244       constexpr tuple(const _Elements&... __elements)
245       : _Inherited(__elements...) { }
246
247       template<typename... _UElements, typename = typename
248                std::enable_if<sizeof...(_UElements)
249                               == sizeof...(_Elements)>::type>
250         explicit
251         tuple(_UElements&&... __elements)
252         : _Inherited(std::forward<_UElements>(__elements)...) { }
253
254       constexpr tuple(const tuple&) = default;
255
256       tuple(tuple&& __in)
257       : _Inherited(static_cast<_Inherited&&>(__in)) { }
258
259       template<typename... _UElements, typename = typename
260                std::enable_if<sizeof...(_UElements)
261                               == sizeof...(_Elements)>::type>
262         tuple(const tuple<_UElements...>& __in)
263         : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
264         { }
265
266       template<typename... _UElements, typename = typename
267                std::enable_if<sizeof...(_UElements)
268                               == sizeof...(_Elements)>::type>
269         tuple(tuple<_UElements...>&& __in)
270         : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
271
272       tuple&
273       operator=(const tuple& __in)
274       {
275         static_cast<_Inherited&>(*this) = __in;
276         return *this;
277       }
278
279       tuple&
280       operator=(tuple&& __in)
281       noexcept(is_nothrow_move_assignable<_Inherited>::value)
282       {
283         static_cast<_Inherited&>(*this) = std::move(__in);
284         return *this;
285       }
286
287       template<typename... _UElements, typename = typename
288                std::enable_if<sizeof...(_UElements)
289                               == sizeof...(_Elements)>::type>
290         tuple&
291         operator=(const tuple<_UElements...>& __in)
292         {
293           static_cast<_Inherited&>(*this) = __in;
294           return *this;
295         }
296
297       template<typename... _UElements, typename = typename
298                std::enable_if<sizeof...(_UElements)
299                               == sizeof...(_Elements)>::type>
300         tuple&
301         operator=(tuple<_UElements...>&& __in)
302         {
303           static_cast<_Inherited&>(*this) = std::move(__in);
304           return *this;
305         }
306
307       void
308       swap(tuple& __in)
309       noexcept(noexcept(__in._M_swap(__in)))
310       { _Inherited::_M_swap(__in); }
311     };
312
313   template<>  
314     class tuple<>
315     {
316     public:
317       void swap(tuple&) noexcept { /* no-op */ }
318     };
319
320   /// tuple (2-element), with construction and assignment from a pair.
321   template<typename _T1, typename _T2>
322     class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
323     {
324       typedef _Tuple_impl<0, _T1, _T2> _Inherited;
325
326     public:
327       constexpr tuple()
328       : _Inherited() { }
329
330       explicit
331       constexpr tuple(const _T1& __a1, const _T2& __a2)
332       : _Inherited(__a1, __a2) { }
333
334       template<typename _U1, typename _U2>
335         explicit
336         tuple(_U1&& __a1, _U2&& __a2)
337         : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
338
339       constexpr tuple(const tuple&) = default;
340
341       tuple(tuple&& __in)
342       : _Inherited(static_cast<_Inherited&&>(__in)) { }
343
344       template<typename _U1, typename _U2>
345         tuple(const tuple<_U1, _U2>& __in)
346         : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
347
348       template<typename _U1, typename _U2>
349         tuple(tuple<_U1, _U2>&& __in)
350         : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
351
352       template<typename _U1, typename _U2>
353         tuple(const pair<_U1, _U2>& __in)
354         : _Inherited(__in.first, __in.second) { }
355
356       template<typename _U1, typename _U2>
357         tuple(pair<_U1, _U2>&& __in)
358         : _Inherited(std::forward<_U1>(__in.first),
359                      std::forward<_U2>(__in.second)) { }
360
361       tuple&
362       operator=(const tuple& __in)
363       {
364         static_cast<_Inherited&>(*this) = __in;
365         return *this;
366       }
367
368       tuple&
369       operator=(tuple&& __in)
370       noexcept(is_nothrow_move_assignable<_Inherited>::value)
371       {
372         static_cast<_Inherited&>(*this) = std::move(__in);
373         return *this;
374       }
375
376       template<typename _U1, typename _U2>
377         tuple&
378         operator=(const tuple<_U1, _U2>& __in)
379         {
380           static_cast<_Inherited&>(*this) = __in;
381           return *this;
382         }
383
384       template<typename _U1, typename _U2>
385         tuple&
386         operator=(tuple<_U1, _U2>&& __in)
387         {
388           static_cast<_Inherited&>(*this) = std::move(__in);
389           return *this;
390         }
391
392       template<typename _U1, typename _U2>
393         tuple&
394         operator=(const pair<_U1, _U2>& __in)
395         {
396           this->_M_head() = __in.first;
397           this->_M_tail()._M_head() = __in.second;
398           return *this;
399         }
400
401       template<typename _U1, typename _U2>
402         tuple&
403         operator=(pair<_U1, _U2>&& __in)
404         {
405           this->_M_head() = std::forward<_U1>(__in.first);
406           this->_M_tail()._M_head() = std::forward<_U2>(__in.second);
407           return *this;
408         }
409
410       void
411       swap(tuple& __in)
412       noexcept(noexcept(__in._M_swap(__in)))
413       { _Inherited::_M_swap(__in); }
414     };
415
416   /// tuple (1-element).
417   template<typename _T1>
418     class tuple<_T1> : public _Tuple_impl<0, _T1>
419     {
420       typedef _Tuple_impl<0, _T1> _Inherited;
421
422     public:
423       constexpr tuple()
424       : _Inherited() { }
425
426       explicit
427       constexpr tuple(const _T1& __a1)
428       : _Inherited(__a1) { }
429
430       template<typename _U1, typename = typename
431                std::enable_if<std::is_convertible<_U1, _T1>::value>::type>
432         explicit
433         tuple(_U1&& __a1)
434         : _Inherited(std::forward<_U1>(__a1)) { }
435
436       constexpr tuple(const tuple&) = default;
437
438       tuple(tuple&& __in)
439       : _Inherited(static_cast<_Inherited&&>(__in)) { }
440
441       template<typename _U1>
442         tuple(const tuple<_U1>& __in)
443         : _Inherited(static_cast<const _Tuple_impl<0, _U1>&>(__in)) { }
444
445       template<typename _U1>
446         tuple(tuple<_U1>&& __in)
447         : _Inherited(static_cast<_Tuple_impl<0, _U1>&&>(__in)) { }
448
449       tuple&
450       operator=(const tuple& __in)
451       {
452         static_cast<_Inherited&>(*this) = __in;
453         return *this;
454       }
455
456       tuple&
457       operator=(tuple&& __in)
458       noexcept(is_nothrow_move_assignable<_Inherited>::value)
459       {
460         static_cast<_Inherited&>(*this) = std::move(__in);
461         return *this;
462       }
463
464       template<typename _U1>
465         tuple&
466         operator=(const tuple<_U1>& __in)
467         {
468           static_cast<_Inherited&>(*this) = __in;
469           return *this;
470         }
471
472       template<typename _U1>
473         tuple&
474         operator=(tuple<_U1>&& __in)
475         {
476           static_cast<_Inherited&>(*this) = std::move(__in);
477           return *this;
478         }
479
480       void
481       swap(tuple& __in)
482       noexcept(noexcept(__in._M_swap(__in)))
483       { _Inherited::_M_swap(__in); }
484     };
485
486
487   /// Gives the type of the ith element of a given tuple type.
488   template<std::size_t __i, typename _Tp>
489     struct tuple_element;
490
491   /**
492    * Recursive case for tuple_element: strip off the first element in
493    * the tuple and retrieve the (i-1)th element of the remaining tuple.
494    */
495   template<std::size_t __i, typename _Head, typename... _Tail>
496     struct tuple_element<__i, tuple<_Head, _Tail...> >
497     : tuple_element<__i - 1, tuple<_Tail...> > { };
498
499   /**
500    * Basis case for tuple_element: The first element is the one we're seeking.
501    */
502   template<typename _Head, typename... _Tail>
503     struct tuple_element<0, tuple<_Head, _Tail...> >
504     {
505       typedef _Head type;
506     };
507
508   /// Finds the size of a given tuple type.
509   template<typename _Tp>
510     struct tuple_size;
511
512   /// class tuple_size
513   template<typename... _Elements>
514     struct tuple_size<tuple<_Elements...> >
515     {
516       static const std::size_t value = sizeof...(_Elements);
517     };
518
519   template<typename... _Elements>
520     const std::size_t tuple_size<tuple<_Elements...> >::value;
521
522   template<std::size_t __i, typename _Head, typename... _Tail>
523     inline typename __add_ref<_Head>::type
524     __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
525     { return __t._M_head(); }
526
527   template<std::size_t __i, typename _Head, typename... _Tail>
528     inline typename __add_c_ref<_Head>::type
529     __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
530     { return __t._M_head(); }
531
532   // Return a reference (const reference, rvalue reference) to the ith element
533   // of a tuple.  Any const or non-const ref elements are returned with their
534   // original type.
535   template<std::size_t __i, typename... _Elements>
536     inline typename __add_ref<
537                       typename tuple_element<__i, tuple<_Elements...>>::type
538                     >::type
539     get(tuple<_Elements...>& __t) noexcept
540     { return __get_helper<__i>(__t); }
541
542   template<std::size_t __i, typename... _Elements>
543     inline typename __add_c_ref<
544                       typename tuple_element<__i, tuple<_Elements...>>::type
545                     >::type
546     get(const tuple<_Elements...>& __t) noexcept
547     { return __get_helper<__i>(__t); }
548
549   template<std::size_t __i, typename... _Elements>
550     inline typename __add_r_ref<
551                       typename tuple_element<__i, tuple<_Elements...>>::type
552                     >::type
553     get(tuple<_Elements...>&& __t) noexcept
554     { return std::forward<typename tuple_element<__i,
555         tuple<_Elements...>>::type&&>(get<__i>(__t)); }
556
557   // This class helps construct the various comparison operations on tuples
558   template<std::size_t __check_equal_size, std::size_t __i, std::size_t __j,
559            typename _Tp, typename _Up>
560     struct __tuple_compare;
561
562   template<std::size_t __i, std::size_t __j, typename _Tp, typename _Up>
563     struct __tuple_compare<0, __i, __j, _Tp, _Up>
564     {
565       static bool __eq(const _Tp& __t, const _Up& __u)
566       {
567         return (get<__i>(__t) == get<__i>(__u) &&
568                 __tuple_compare<0, __i + 1, __j, _Tp, _Up>::__eq(__t, __u));
569       }
570      
571       static bool __less(const _Tp& __t, const _Up& __u)
572       {
573         return ((get<__i>(__t) < get<__i>(__u))
574                 || !(get<__i>(__u) < get<__i>(__t)) &&
575                 __tuple_compare<0, __i + 1, __j, _Tp, _Up>::__less(__t, __u));
576       }
577     };
578
579   template<std::size_t __i, typename _Tp, typename _Up>
580     struct __tuple_compare<0, __i, __i, _Tp, _Up>
581     {
582       static bool __eq(const _Tp&, const _Up&)
583       { return true; }
584      
585       static bool __less(const _Tp&, const _Up&)
586       { return false; }
587     };
588
589   template<typename... _TElements, typename... _UElements>
590     bool
591     operator==(const tuple<_TElements...>& __t,
592                const tuple<_UElements...>& __u)
593     {
594       typedef tuple<_TElements...> _Tp;
595       typedef tuple<_UElements...> _Up;
596       return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value,
597               0, tuple_size<_Tp>::value, _Tp, _Up>::__eq(__t, __u));
598     }
599
600   template<typename... _TElements, typename... _UElements>
601     bool
602     operator<(const tuple<_TElements...>& __t,
603               const tuple<_UElements...>& __u)
604     {
605       typedef tuple<_TElements...> _Tp;
606       typedef tuple<_UElements...> _Up;
607       return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value,
608               0, tuple_size<_Tp>::value, _Tp, _Up>::__less(__t, __u));
609     }
610
611   template<typename... _TElements, typename... _UElements>
612     inline bool
613     operator!=(const tuple<_TElements...>& __t,
614                const tuple<_UElements...>& __u)
615     { return !(__t == __u); }
616
617   template<typename... _TElements, typename... _UElements>
618     inline bool
619     operator>(const tuple<_TElements...>& __t,
620               const tuple<_UElements...>& __u)
621     { return __u < __t; }
622
623   template<typename... _TElements, typename... _UElements>
624     inline bool
625     operator<=(const tuple<_TElements...>& __t,
626                const tuple<_UElements...>& __u)
627     { return !(__u < __t); }
628
629   template<typename... _TElements, typename... _UElements>
630     inline bool
631     operator>=(const tuple<_TElements...>& __t,
632                const tuple<_UElements...>& __u)
633     { return !(__t < __u); }
634
635   // NB: DR 705.
636   template<typename... _Elements>
637     inline tuple<typename __decay_and_strip<_Elements>::__type...>
638     make_tuple(_Elements&&... __args)
639     {
640       typedef tuple<typename __decay_and_strip<_Elements>::__type...>
641         __result_type;
642       return __result_type(std::forward<_Elements>(__args)...);
643     }
644
645   template<typename... _Elements>
646     inline tuple<_Elements&&...>
647     forward_as_tuple(_Elements&&... __args) noexcept
648     { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
649
650   template<std::size_t...> struct __index_holder { };    
651
652   template<std::size_t __i, typename _IdxHolder, typename... _Elements>
653     struct __index_holder_impl;
654
655   template<std::size_t __i, std::size_t... _Indexes, typename _IdxHolder,
656            typename... _Elements>
657     struct __index_holder_impl<__i, __index_holder<_Indexes...>,
658                                _IdxHolder, _Elements...> 
659     {
660       typedef typename __index_holder_impl<__i + 1,
661                                            __index_holder<_Indexes..., __i>,
662                                            _Elements...>::type type;
663     };
664  
665   template<std::size_t __i, std::size_t... _Indexes>
666     struct __index_holder_impl<__i, __index_holder<_Indexes...> >
667     { typedef __index_holder<_Indexes...> type; };
668
669   template<typename... _Elements>
670     struct __make_index_holder 
671     : __index_holder_impl<0, __index_holder<>, _Elements...> { };
672     
673   template<typename... _TElements, std::size_t... _TIdx,
674            typename... _UElements, std::size_t... _UIdx> 
675     inline tuple<_TElements..., _UElements...> 
676     __tuple_cat_helper(const tuple<_TElements...>& __t,
677                        const __index_holder<_TIdx...>&,
678                        const tuple<_UElements...>& __u,
679                        const __index_holder<_UIdx...>&)
680     { return tuple<_TElements..., _UElements...>(get<_TIdx>(__t)...,
681                                                  get<_UIdx>(__u)...); }
682
683   template<typename... _TElements, std::size_t... _TIdx,
684            typename... _UElements, std::size_t... _UIdx> 
685     inline tuple<_TElements..., _UElements...> 
686     __tuple_cat_helper(tuple<_TElements...>&& __t,
687                        const __index_holder<_TIdx...>&, 
688                        const tuple<_UElements...>& __u,
689                        const __index_holder<_UIdx...>&)
690     { return tuple<_TElements..., _UElements...>
691         (std::forward<_TElements>(get<_TIdx>(__t))..., get<_UIdx>(__u)...); }
692
693   template<typename... _TElements, std::size_t... _TIdx,
694            typename... _UElements, std::size_t... _UIdx>
695     inline tuple<_TElements..., _UElements...> 
696     __tuple_cat_helper(const tuple<_TElements...>& __t,
697                        const __index_holder<_TIdx...>&, 
698                        tuple<_UElements...>&& __u,
699                        const __index_holder<_UIdx...>&)
700     { return tuple<_TElements..., _UElements...>
701         (get<_TIdx>(__t)..., std::forward<_UElements>(get<_UIdx>(__u))...); }
702
703   template<typename... _TElements, std::size_t... _TIdx,
704            typename... _UElements, std::size_t... _UIdx> 
705     inline tuple<_TElements..., _UElements...> 
706     __tuple_cat_helper(tuple<_TElements...>&& __t,
707                        const __index_holder<_TIdx...>&, 
708                        tuple<_UElements...>&& __u,
709                        const __index_holder<_UIdx...>&)
710     { return tuple<_TElements..., _UElements...>
711         (std::forward<_TElements>(get<_TIdx>(__t))...,
712          std::forward<_UElements>(get<_UIdx>(__u))...); }
713
714   template<typename... _TElements, typename... _UElements>
715     inline tuple<_TElements..., _UElements...> 
716     tuple_cat(const tuple<_TElements...>& __t, const tuple<_UElements...>& __u)
717     {
718       return __tuple_cat_helper(__t, typename
719                                 __make_index_holder<_TElements...>::type(),
720                                 __u, typename
721                                 __make_index_holder<_UElements...>::type());
722     }
723
724   template<typename... _TElements, typename... _UElements>
725     inline tuple<_TElements..., _UElements...> 
726     tuple_cat(tuple<_TElements...>&& __t, const tuple<_UElements...>& __u)
727     {
728       return __tuple_cat_helper(std::move(__t), typename
729                                  __make_index_holder<_TElements...>::type(),
730                                  __u, typename
731                                  __make_index_holder<_UElements...>::type());
732     }
733
734   template<typename... _TElements, typename... _UElements>
735     inline tuple<_TElements..., _UElements...> 
736     tuple_cat(const tuple<_TElements...>& __t, tuple<_UElements...>&& __u)
737     {
738       return __tuple_cat_helper(__t, typename
739                                 __make_index_holder<_TElements...>::type(),
740                                 std::move(__u), typename
741                                 __make_index_holder<_UElements...>::type());
742     }
743
744   template<typename... _TElements, typename... _UElements>
745     inline tuple<_TElements..., _UElements...>
746     tuple_cat(tuple<_TElements...>&& __t, tuple<_UElements...>&& __u)
747     {
748       return __tuple_cat_helper(std::move(__t), typename
749                                 __make_index_holder<_TElements...>::type(),
750                                 std::move(__u), typename
751                                 __make_index_holder<_UElements...>::type());
752     }
753
754   template<typename... _Elements>
755     inline tuple<_Elements&...>
756     tie(_Elements&... __args) noexcept
757     { return tuple<_Elements&...>(__args...); }
758
759   template<typename... _Elements>
760     inline void 
761     swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
762     noexcept(noexcept(__x.swap(__y)))
763     { __x.swap(__y); }
764
765   // A class (and instance) which can be used in 'tie' when an element
766   // of a tuple is not required
767   struct _Swallow_assign
768   {
769     template<class _Tp>
770       const _Swallow_assign&
771       operator=(const _Tp&) const
772       { return *this; }
773   };
774
775   const _Swallow_assign ignore{};
776
777   /**
778    * Stores a tuple of indices. Used by bind() to extract the elements
779    * in a tuple. 
780    */
781   template<int... _Indexes>
782     struct _Index_tuple
783     {
784       typedef _Index_tuple<_Indexes..., sizeof...(_Indexes)> __next;
785     };
786
787   /// Builds an _Index_tuple<0, 1, 2, ..., _Num-1>.
788   template<std::size_t _Num>
789     struct _Build_index_tuple
790     {
791       typedef typename _Build_index_tuple<_Num-1>::__type::__next __type;
792     };
793
794   template<>
795     struct _Build_index_tuple<0>
796     {
797       typedef _Index_tuple<> __type;
798     };
799
800   // See stl_pair.h...
801   template<class _T1, class _T2>
802     template<typename _Tp, typename... _Args>
803       inline _Tp
804       pair<_T1, _T2>::
805       __cons(tuple<_Args...>&& __tuple)
806       {
807         typedef typename _Build_index_tuple<sizeof...(_Args)>::__type
808           _Indexes;
809         return __do_cons<_Tp>(std::move(__tuple), _Indexes());
810       }
811
812   template<class _T1, class _T2>
813     template<typename _Tp, typename... _Args, int... _Indexes>
814       inline _Tp
815       pair<_T1, _T2>::
816       __do_cons(tuple<_Args...>&& __tuple,
817                 const _Index_tuple<_Indexes...>&)
818       { return _Tp(std::forward<_Args>(get<_Indexes>(__tuple))...); }
819
820 _GLIBCXX_END_NAMESPACE_VERSION
821 } // namespace
822
823 #endif // __GXX_EXPERIMENTAL_CXX0X__
824
825 #endif // _GLIBCXX_TUPLE