OSDN Git Service

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