OSDN Git Service

2008-03-06 Chris Jefferson <chris@bubblescope.net>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / std / tuple
1 // <tuple> -*- C++ -*-
2
3 // Copyright (C) 2007, 2008 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 2, 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 // You should have received a copy of the GNU General Public License
17 // along with this library; see the file COPYING.  If not, write to
18 // the Free Software Foundation, 51 Franklin Street, Fifth Floor,
19 // Boston, MA 02110-1301, USA.
20
21 // As a special exception, you may use this file as part of a free software
22 // library without restriction.  Specifically, if other files instantiate
23 // templates or use macros or inline functions from this file, or you compile
24 // this file and link it with other files to produce an executable, this
25 // file does not by itself cause the resulting executable to be covered by
26 // the GNU General Public License.  This exception does not however
27 // invalidate any other reasons why the executable file might be covered by
28 // the GNU General Public License.
29
30 /** @file include/tuple
31  *  This is a Standard C++ Library header.
32  */
33
34 #ifndef _GLIBCXX_CXX0X_TUPLE
35 #define _GLIBCXX_CXX0X_TUPLE 1
36
37 #pragma GCC system_header
38
39 #ifndef __GXX_EXPERIMENTAL_CXX0X__
40 # include <c++0x_warning.h>
41 #endif
42
43 #include <utility>
44
45 namespace std
46 {
47   // Adds a const reference to a non-reference type.
48   template<typename _Tp>
49     struct __add_c_ref
50     { typedef const _Tp& type; };
51
52   template<typename _Tp>
53     struct __add_c_ref<_Tp&>
54     { typedef _Tp& type; };
55
56   // Adds a reference to a non-reference type.
57   template<typename _Tp>
58     struct __add_ref
59     { typedef _Tp& type; };
60
61   template<typename _Tp>
62     struct __add_ref<_Tp&>
63     { typedef _Tp& type; };
64
65   template<int _Idx, typename _Head, bool _IsEmpty>
66     struct _Head_base;
67
68   template<int _Idx, typename _Head>
69     struct _Head_base<_Idx, _Head, true>
70     : public _Head
71     {
72       _Head_base()
73       : _Head() { }
74
75       _Head_base(const _Head& __h)
76       : _Head(__h) { }
77
78       template<typename _UHead>
79       _Head_base(_UHead&& __h)
80       : _Head(std::forward<_UHead>(__h)) { }
81
82       _Head&       _M_head()       { return *this; }
83       const _Head& _M_head() const { return *this; }
84     };
85
86   template<int _Idx, typename _Head>
87     struct _Head_base<_Idx, _Head, false>
88     {
89       _Head_base()
90       : _M_head_impl() { }
91
92       _Head_base(const _Head& __h)
93       : _M_head_impl(__h) { }
94
95       template<typename _UHead>
96       _Head_base(_UHead&& __h)
97       : _M_head_impl(std::forward<_UHead>(__h)) { }
98
99       _Head&       _M_head()       { return _M_head_impl; }
100       const _Head& _M_head() const { return _M_head_impl; }        
101
102       _Head _M_head_impl; 
103     };
104
105   /**
106    * Contains the actual implementation of the @c tuple template, stored
107    * as a recursive inheritance hierarchy from the first element (most
108    * derived class) to the last (least derived class). The @c Idx
109    * parameter gives the 0-based index of the element stored at this
110    * point in the hierarchy; we use it to implement a constant-time
111    * get() operation.
112    */
113   template<int _Idx, typename... _Elements>
114     struct _Tuple_impl; 
115
116   /**
117    * Zero-element tuple implementation. This is the basis case for the 
118    * inheritance recursion.
119    */
120   template<int _Idx>
121     struct _Tuple_impl<_Idx> { };
122
123   /**
124    * Recursive tuple implementation. Here we store the @c Head element
125    * and derive from a @c Tuple_impl containing the remaining elements
126    * (which contains the @c Tail).
127    */
128   template<int _Idx, typename _Head, typename... _Tail>
129     struct _Tuple_impl<_Idx, _Head, _Tail...>
130     : public _Tuple_impl<_Idx + 1, _Tail...>,
131       private _Head_base<_Idx, _Head, std::is_empty<_Head>::value>
132     {
133       typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
134       typedef _Head_base<_Idx, _Head, std::is_empty<_Head>::value> _Base;
135
136       _Head&            _M_head()       { return _Base::_M_head(); }
137       const _Head&      _M_head() const { return _Base::_M_head(); }
138
139       _Inherited&       _M_tail()       { return *this; }
140       const _Inherited& _M_tail() const { return *this; }
141
142       _Tuple_impl()
143       : _Inherited(), _Base() { }
144
145       explicit 
146       _Tuple_impl(const _Head& __head, const _Tail&... __tail)
147       : _Inherited(__tail...), _Base(__head) { }
148
149       template<typename _UHead, typename... _UTail> 
150         explicit
151         _Tuple_impl(_UHead&& __head, _UTail&&... __tail)
152         : _Inherited(std::forward<_UTail>(__tail)...),
153           _Base(std::forward<_UHead>(__head)) { }
154
155       _Tuple_impl(const _Tuple_impl& __in)
156       : _Inherited(__in._M_tail()), _Base(__in._M_head()) { }
157
158       _Tuple_impl(_Tuple_impl&& __in)
159       : _Inherited(std::move<_Inherited&&>(__in._M_tail())),
160         _Base(std::forward<_Head>(__in._M_head())) { }
161
162       template<typename... _UElements>
163         _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in)
164         : _Inherited(__in._M_tail()), _Base(__in._M_head()) { }
165
166       template<typename... _UElements>
167         _Tuple_impl(_Tuple_impl<_Idx, _UElements...>&& __in)
168         : _Inherited(std::move<typename _Tuple_impl<_Idx, _UElements...>::
169                      _Inherited&&>(__in._M_tail())),
170           _Base(std::forward<typename _Tuple_impl<_Idx, _UElements...>::
171                 _Base>(__in._M_head())) { }
172
173       _Tuple_impl&
174       operator=(const _Tuple_impl& __in)
175       {
176         _M_head() = __in._M_head();
177         _M_tail() = __in._M_tail();
178         return *this;
179       }
180
181       _Tuple_impl&
182       operator=(_Tuple_impl&& __in)
183       {
184         _M_head() = std::move(__in._M_head());
185         _M_tail() = std::move(__in._M_tail());
186         return *this;
187       }
188
189       template<typename... _UElements>
190         _Tuple_impl&
191         operator=(const _Tuple_impl<_Idx, _UElements...>& __in)
192         {
193           _M_head() = __in._M_head();
194           _M_tail() = __in._M_tail();
195           return *this;
196         }
197
198       template<typename... _UElements>
199         _Tuple_impl&
200         operator=(_Tuple_impl<_Idx, _UElements...>&& __in)
201         {
202           _M_head() = std::move(__in._M_head());
203           _M_tail() = std::move(__in._M_tail());
204           return *this;
205         }
206     };
207
208   template<typename... _Elements> 
209     class tuple : public _Tuple_impl<0, _Elements...>
210     {
211       typedef _Tuple_impl<0, _Elements...> _Inherited;
212
213     public:
214       tuple()
215       : _Inherited() { }
216
217       explicit
218       tuple(const _Elements&... __elements)
219       : _Inherited(__elements...) { }
220
221       template<typename... _UElements>
222         explicit
223         tuple(_UElements&&... __elements)
224         : _Inherited(std::forward<_UElements>(__elements)...) { }
225
226       tuple(const tuple& __in)
227       : _Inherited(static_cast<const _Inherited&>(__in)) { }
228
229       tuple(tuple&& __in)
230       : _Inherited(std::move<_Inherited>(__in)) { }
231
232       template<typename... _UElements>
233         tuple(const tuple<_UElements...>& __in)
234         : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
235         { }
236
237       template<typename... _UElements>
238         tuple(tuple<_UElements...>&& __in)
239         : _Inherited(std::move<_Tuple_impl<0, _UElements...> >(__in)) { }
240
241       // XXX http://gcc.gnu.org/ml/libstdc++/2008-02/msg00047.html
242       template<typename... _UElements>
243         tuple(tuple<_UElements...>& __in)
244         : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
245         { }
246
247       tuple&
248       operator=(const tuple& __in)
249       {
250         static_cast<_Inherited&>(*this) = __in;
251         return *this;
252       }
253
254       tuple&
255       operator=(tuple&& __in)
256       {
257         static_cast<_Inherited&>(*this) = std::move(__in);
258         return *this;
259       }
260
261       template<typename... _UElements>
262         tuple&
263         operator=(const tuple<_UElements...>& __in)
264         {
265           static_cast<_Inherited&>(*this) = __in;
266           return *this;
267         }
268
269       template<typename... _UElements>
270         tuple&
271         operator=(tuple<_UElements...>&& __in)
272         {
273           static_cast<_Inherited&>(*this) = std::move(__in);
274           return *this;
275         }
276     };
277
278   template<> class tuple<> { };
279
280   // 2-element tuple, with construction and assignment from a pair.
281   template<typename _T1, typename _T2>
282     class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
283     {
284       typedef _Tuple_impl<0, _T1, _T2> _Inherited;
285
286     public:
287       tuple()
288       : _Inherited() { }
289
290       explicit
291       tuple(const _T1& __a1, const _T2& __a2)
292       : _Inherited(__a1, __a2) { }
293
294       template<typename _U1, typename _U2>
295         explicit
296         tuple(_U1&& __a1, _U2&& __a2)
297         : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
298
299       tuple(const tuple& __in)
300       : _Inherited(static_cast<const _Inherited&>(__in)) { }
301
302       tuple(tuple&& __in)
303       : _Inherited(std::move<_Inherited>(__in)) { }
304
305       template<typename _U1, typename _U2>
306         tuple(const tuple<_U1, _U2>& __in)
307         : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
308
309       template<typename _U1, typename _U2>
310         tuple(tuple<_U1, _U2>&& __in)
311         : _Inherited(std::move<_Tuple_impl<0, _U1, _U2> >(__in)) { }
312
313       template<typename _U1, typename _U2>
314         tuple(const pair<_U1, _U2>& __in)
315         : _Inherited(__in.first, __in.second) { }
316
317       template<typename _U1, typename _U2>
318         tuple(pair<_U1, _U2>&& __in)
319         : _Inherited(std::move(__in.first), std::move(__in.second)) { }
320
321       tuple&
322       operator=(const tuple& __in)
323       {
324         static_cast<_Inherited&>(*this) = __in;
325         return *this;
326       }
327
328       tuple&
329       operator=(tuple&& __in)
330       {
331         static_cast<_Inherited&>(*this) = std::move(__in);
332         return *this;
333       }
334
335       template<typename _U1, typename _U2>
336         tuple&
337         operator=(const tuple<_U1, _U2>& __in)
338         {
339           static_cast<_Inherited&>(*this) = __in;
340           return *this;
341         }
342
343       template<typename _U1, typename _U2>
344         tuple&
345         operator=(tuple<_U1, _U2>&& __in)
346         {
347           static_cast<_Inherited&>(*this) = std::move(__in);
348           return *this;
349         }
350
351       template<typename _U1, typename _U2>
352         tuple&
353         operator=(const pair<_U1, _U2>& __in)
354         {
355           this->_M_head() = __in.first;
356           this->_M_tail()._M_head() = __in.second;
357           return *this;
358         }
359
360       template<typename _U1, typename _U2>
361         tuple&
362         operator=(pair<_U1, _U2>&& __in)
363         {
364           this->_M_head() = std::move(__in.first);
365           this->_M_tail()._M_head() = std::move(__in.second);
366           return *this;
367         }
368     };
369
370
371   /// Gives the type of the ith element of a given tuple type.
372   template<int __i, typename _Tp>
373     struct tuple_element;
374
375   /**
376    * Recursive case for tuple_element: strip off the first element in
377    * the tuple and retrieve the (i-1)th element of the remaining tuple.
378    */
379   template<int __i, typename _Head, typename... _Tail>
380     struct tuple_element<__i, tuple<_Head, _Tail...> >
381     : tuple_element<__i - 1, tuple<_Tail...> > { };
382
383   /**
384    * Basis case for tuple_element: The first element is the one we're seeking.
385    */
386   template<typename _Head, typename... _Tail>
387     struct tuple_element<0, tuple<_Head, _Tail...> >
388     {
389       typedef _Head type;
390     };
391
392   /// Finds the size of a given tuple type.
393   template<typename _Tp>
394     struct tuple_size;
395
396   /// @brief class tuple_size
397   template<typename... _Elements>
398     struct tuple_size<tuple<_Elements...> >
399     {
400       static const int value = sizeof...(_Elements);
401     };
402
403   template<typename... _Elements>
404     const int tuple_size<tuple<_Elements...> >::value;
405
406   template<int __i, typename _Head, typename... _Tail>
407     inline typename __add_ref<_Head>::type
408     __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t)
409     { return __t._M_head(); }
410
411   template<int __i, typename _Head, typename... _Tail>
412     inline typename __add_c_ref<_Head>::type
413     __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t)
414     { return __t._M_head(); }
415
416   // Return a reference (const reference) to the ith element of a tuple.
417   // Any const or non-const ref elements are returned with their original type.
418   template<int __i, typename... _Elements>
419     inline typename __add_ref<
420                       typename tuple_element<__i, tuple<_Elements...> >::type
421                     >::type
422     get(tuple<_Elements...>& __t)
423     { return __get_helper<__i>(__t); }
424
425   template<int __i, typename... _Elements>
426     inline typename __add_c_ref<
427                       typename tuple_element<__i, tuple<_Elements...> >::type
428                     >::type
429     get(const tuple<_Elements...>& __t)
430     { return __get_helper<__i>(__t); }
431
432   // This class helps construct the various comparison operations on tuples
433   template<int __check_equal_size, int __i, int __j,
434            typename _Tp, typename _Up>
435     struct __tuple_compare;
436
437   template<int __i, int __j, typename _Tp, typename _Up>
438     struct __tuple_compare<0, __i, __j, _Tp, _Up>
439     {
440       static bool __eq(const _Tp& __t, const _Up& __u)
441       {
442         return (get<__i>(__t) == get<__i>(__u) &&
443                 __tuple_compare<0, __i+1, __j, _Tp, _Up>::__eq(__t, __u));
444       }
445      
446       static bool __less(const _Tp& __t, const _Up& __u)
447       {
448         return ((get<__i>(__t) < get<__i>(__u))
449                 || !(get<__i>(__u) < get<__i>(__t)) &&
450                 __tuple_compare<0, __i+1, __j, _Tp, _Up>::__less(__t, __u));
451       }
452     };
453
454   template<int __i, typename _Tp, typename _Up>
455     struct __tuple_compare<0, __i, __i, _Tp, _Up>
456     {
457       static bool __eq(const _Tp&, const _Up&)
458       { return true; }
459      
460       static bool __less(const _Tp&, const _Up&)
461       { return false; }
462     };
463
464   template<typename... _TElements, typename... _UElements>
465     bool
466     operator==(const tuple<_TElements...>& __t,
467                const tuple<_UElements...>& __u)
468     {
469       typedef tuple<_TElements...> _Tp;
470       typedef tuple<_UElements...> _Up;
471       return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value,
472               0, tuple_size<_Tp>::value, _Tp, _Up>::__eq(__t, __u));
473     }
474
475   template<typename... _TElements, typename... _UElements>
476     bool
477     operator<(const tuple<_TElements...>& __t,
478               const tuple<_UElements...>& __u)
479     {
480       typedef tuple<_TElements...> _Tp;
481       typedef tuple<_UElements...> _Up;
482       return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value,
483               0, tuple_size<_Tp>::value, _Tp, _Up>::__less(__t, __u));
484     }
485
486   template<typename... _TElements, typename... _UElements>
487     inline bool
488     operator!=(const tuple<_TElements...>& __t,
489                const tuple<_UElements...>& __u)
490     { return !(__t == __u); }
491
492   template<typename... _TElements, typename... _UElements>
493     inline bool
494     operator>(const tuple<_TElements...>& __t,
495               const tuple<_UElements...>& __u)
496     { return __u < __t; }
497
498   template<typename... _TElements, typename... _UElements>
499     inline bool
500     operator<=(const tuple<_TElements...>& __t,
501                const tuple<_UElements...>& __u)
502     { return !(__u < __t); }
503
504   template<typename... _TElements, typename... _UElements>
505     inline bool
506     operator>=(const tuple<_TElements...>& __t,
507                const tuple<_UElements...>& __u)
508     { return !(__t < __u); }
509
510   // NB: DR 705.
511   template<typename... _Elements>
512     inline tuple<typename __decay_and_strip<_Elements>::__type...>
513     make_tuple(_Elements&&... __args)
514     {
515       typedef tuple<typename __decay_and_strip<_Elements>::__type...>
516         __result_type;
517       return __result_type(std::forward<_Elements>(__args)...);
518     }
519
520   template<int...> struct __index_holder { };    
521
522   template<int __i, typename _IdxHolder, typename... _Elements>
523     struct __index_holder_impl;
524
525   template<int __i, int... _Indexes, typename _IdxHolder, typename... _Elements>
526     struct __index_holder_impl<__i, __index_holder<_Indexes...>,
527                                _IdxHolder, _Elements...> 
528     {
529       typedef typename __index_holder_impl<__i + 1,
530                                            __index_holder<_Indexes..., __i>,
531                                            _Elements...>::type type;
532     };
533  
534   template<int __i, int... _Indexes>
535     struct __index_holder_impl<__i, __index_holder<_Indexes...> >
536     { typedef __index_holder<_Indexes...> type; };
537
538   template<typename... _Elements>
539     struct __make_index_holder 
540     : __index_holder_impl<0, __index_holder<>, _Elements...> { };
541     
542   template<typename... _TElements, int... _TIdx,
543            typename... _UElements, int... _UIdx> 
544     inline tuple<_TElements..., _UElements...> 
545     __tuple_cat_helper(const tuple<_TElements...>& __t,
546                        const __index_holder<_TIdx...>&,
547                        const tuple<_UElements...>& __u,
548                        const __index_holder<_UIdx...>&)
549     { return tuple<_TElements..., _UElements...>(get<_TIdx>(__t)...,
550                                                  get<_UIdx>(__u)...); }
551
552   template<typename... _TElements, int... _TIdx,
553            typename... _UElements, int... _UIdx> 
554     inline tuple<_TElements..., _UElements...> 
555     __tuple_cat_helper(tuple<_TElements...>&& __t,
556                        const __index_holder<_TIdx...>&, 
557                        const tuple<_UElements...>& __u,
558                        const __index_holder<_UIdx...>&)
559     { return tuple<_TElements..., _UElements...>
560         (std::move(get<_TIdx>(__t))..., get<_UIdx>(__u)...); }
561
562   template<typename... _TElements, int... _TIdx,
563            typename... _UElements, int... _UIdx>
564     inline tuple<_TElements..., _UElements...> 
565     __tuple_cat_helper(const tuple<_TElements...>& __t,
566                        const __index_holder<_TIdx...>&, 
567                        tuple<_UElements...>&& __u,
568                        const __index_holder<_UIdx...>&)
569     { return tuple<_TElements..., _UElements...>
570         (get<_TIdx>(__t)..., std::move(get<_UIdx>(__u))...); }
571
572   template<typename... _TElements, int... _TIdx,
573            typename... _UElements, int... _UIdx> 
574     inline tuple<_TElements..., _UElements...> 
575     __tuple_cat_helper(tuple<_TElements...>&& __t,
576                        const __index_holder<_TIdx...>&, 
577                        tuple<_UElements...>&& __u,
578                        const __index_holder<_UIdx...>&)
579     { return tuple<_TElements..., _UElements...>
580         (std::move(get<_TIdx>(__t))..., std::move(get<_UIdx>(__u))...); }
581
582   template<typename... _TElements, typename... _UElements>
583     inline tuple<_TElements..., _UElements...> 
584     tuple_cat(const tuple<_TElements...>& __t, const tuple<_UElements...>& __u)
585     { 
586       return __tuple_cat_helper(__t, typename
587                                 __make_index_holder<_TElements...>::type(),
588                                 __u, typename
589                                 __make_index_holder<_UElements...>::type());
590     }
591
592   template<typename... _TElements, typename... _UElements>
593     inline tuple<_TElements..., _UElements...> 
594     tuple_cat(tuple<_TElements...>&& __t, const tuple<_UElements...>& __u)
595     {
596       return __tuple_cat_helper(std::move(__t), typename
597                                  __make_index_holder<_TElements...>::type(),
598                                  __u, typename
599                                  __make_index_holder<_UElements...>::type());
600     }
601
602   template<typename... _TElements, typename... _UElements>
603     inline tuple<_TElements..., _UElements...> 
604     tuple_cat(const tuple<_TElements...>& __t, tuple<_UElements...>&& __u)
605     {
606       return __tuple_cat_helper(__t, typename
607                                 __make_index_holder<_TElements...>::type(),
608                                 std::move(__u), typename
609                                 __make_index_holder<_UElements...>::type());
610     }
611
612   template<typename... _TElements, typename... _UElements>
613     inline tuple<_TElements..., _UElements...>
614     tuple_cat(tuple<_TElements...>&& __t, tuple<_UElements...>&& __u)
615     {
616       return __tuple_cat_helper(std::move(__t), typename
617                                 __make_index_holder<_TElements...>::type(),
618                                 std::move(__u), typename
619                                 __make_index_holder<_UElements...>::type());
620     }
621
622   template<typename... _Elements>
623     inline tuple<_Elements&...>
624     tie(_Elements&... __args)
625     { return tuple<_Elements&...>(__args...); }
626
627   // A class (and instance) which can be used in 'tie' when an element
628   // of a tuple is not required
629   struct _Swallow_assign
630   {
631     template<class _Tp>
632       _Swallow_assign&
633       operator=(const _Tp&)
634       { return *this; }
635   };
636
637   // TODO: Put this in some kind of shared file.
638   namespace
639   {
640     _Swallow_assign ignore;
641   }; // anonymous namespace
642 }
643
644 #endif // _GLIBCXX_CXX0X_TUPLE