OSDN Git Service

2007-03-13 Paolo Carlini <pcarlini@suse.de>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / tr1 / tuple
1 // class template tuple -*- C++ -*-
2
3 // Copyright (C) 2004, 2005, 2006, 2007 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 along
17 // with this library; see the file COPYING.  If not, write to the Free
18 // Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
19 // 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 tr1/tuple
31 *  This is a TR1 C++ Library header.
32 */
33
34 // Chris Jefferson <chris@bubblescope.net>
35 // Variadic Templates support by Douglas Gregor <doug.gregor@gmail.com>
36
37 #ifndef _TR1_TUPLE
38 #define _TR1_TUPLE 1
39
40 #pragma GCC system_header
41
42 #include <utility>
43
44 namespace std
45 {
46 _GLIBCXX_BEGIN_NAMESPACE(_GLIBCXX_TR1)
47
48   template<typename _Tp>
49     class reference_wrapper;
50
51   // Adds a const reference to a non-reference type.
52   template<typename _Tp>
53     struct __add_c_ref
54     { typedef const _Tp& type; };
55
56   template<typename _Tp>
57     struct __add_c_ref<_Tp&>
58     { typedef _Tp& type; };
59
60   // Adds a reference to a non-reference type.
61   template<typename _Tp>
62     struct __add_ref
63     { typedef _Tp& type; };
64
65   template<typename _Tp>
66     struct __add_ref<_Tp&>
67     { typedef _Tp& type; };
68
69   /**
70    * @if maint
71    * Contains the actual implementation of the @c tuple template, stored
72    * as a recursive inheritance hierarchy from the first element (most
73    * derived class) to the last (least derived class). The @c Idx
74    * parameter gives the 0-based index of the element stored at this
75    * point in the hierarchy; we use it to implement a constant-time
76    * get() operation.
77    * @endif
78    */
79   template<int _Idx, typename... _Elements>
80     struct _Tuple_impl; 
81
82   /**
83    * @if maint
84    * Zero-element tuple implementation. This is the basis case for the 
85    * inheritance recursion.
86    * @endif maint
87    */
88   template<int _Idx>
89     struct _Tuple_impl<_Idx> { };
90
91   /**
92    * @if maint
93    * Recursive tuple implementation. Here we store the @c Head element
94    * and derive from a @c Tuple_impl containing the remaining elements
95    * (which contains the @c Tail).
96    * @endif
97    */
98   template<int _Idx, typename _Head, typename... _Tail>
99     struct _Tuple_impl<_Idx, _Head, _Tail...>
100     : public _Tuple_impl<_Idx + 1, _Tail...>
101     {
102       typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
103       
104       _Head _M_head;
105       
106       _Inherited&       _M_tail()       { return *this; }
107       const _Inherited& _M_tail() const { return *this; }
108       
109       _Tuple_impl() : _Inherited(), _M_head() { }
110       
111       explicit 
112       _Tuple_impl(typename __add_c_ref<_Head>::type __head,
113                   typename __add_c_ref<_Tail>::type... __tail)
114       : _Inherited(__tail...), _M_head(__head) { }
115
116       template<typename... _UElements>
117       _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in)
118       : _Inherited(__in._M_tail()), _M_head(__in._M_head) { }
119
120       _Tuple_impl(const _Tuple_impl& __in)
121       : _Inherited(__in._M_tail()), _M_head(__in._M_head) { }
122      
123       template<typename... _UElements>
124         _Tuple_impl&
125         operator=(const _Tuple_impl<_Idx, _UElements...>& __in)
126         {
127           _M_head = __in._M_head;
128           _M_tail() = __in._M_tail();
129           return *this;
130         }
131
132       _Tuple_impl&
133       operator=(const _Tuple_impl& __in)
134       {
135         _M_head = __in._M_head;
136         _M_tail() = __in._M_tail();
137         return *this;
138       }
139     };
140
141   template<typename... _Elements> 
142     class tuple : public _Tuple_impl<0, _Elements...>
143     {
144       typedef _Tuple_impl<0, _Elements...> _Inherited;
145
146     public:
147       tuple() : _Inherited() { }
148
149       explicit
150       tuple(typename __add_c_ref<_Elements>::type... __elements)
151       : _Inherited(__elements...) { }
152
153       template<typename... _UElements>
154         tuple(const tuple<_UElements...>& __in)
155         : _Inherited(__in) { }
156
157       tuple(const tuple& __in)
158       : _Inherited(__in) { }
159
160       template<typename... _UElements>
161         tuple&
162         operator=(const tuple<_UElements...>& __in)
163         {
164           static_cast<_Inherited&>(*this) = __in;
165           return *this;
166         }
167
168       tuple&
169       operator=(const tuple& __in)
170       {
171         static_cast<_Inherited&>(*this) = __in;
172         return *this;
173       }
174     };
175
176   template<> class tuple<> { };
177
178   // 2-element tuple, with construction and assignment from a pair.
179   template<typename _T1, typename _T2>
180     class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
181     {
182       typedef _Tuple_impl<0, _T1, _T2> _Inherited;
183
184     public:
185       tuple() : _Inherited() { }
186
187       explicit
188       tuple(typename __add_c_ref<_T1>::type __a1,
189             typename __add_c_ref<_T2>::type __a2)
190       : _Inherited(__a1, __a2) { }
191
192       template<typename _U1, typename _U2>
193         tuple(const tuple<_U1, _U2>& __in)
194         : _Inherited(__in) { }
195
196       tuple(const tuple& __in)
197       : _Inherited(__in) { }
198
199       template<typename _U1, typename _U2>
200         tuple(const pair<_U1, _U2>& __in)
201         : _Inherited(_Tuple_impl<0, 
202                      typename __add_c_ref<_U1>::type,
203                      typename __add_c_ref<_U2>::type>(__in.first, 
204                                                       __in.second))
205         { }
206   
207       template<typename _U1, typename _U2>
208         tuple&
209         operator=(const tuple<_U1, _U2>& __in)
210         {
211           static_cast<_Inherited&>(*this) = __in;
212           return *this;
213         }
214
215       tuple&
216       operator=(const tuple& __in)
217       {
218         static_cast<_Inherited&>(*this) = __in;
219         return *this;
220       }
221
222       template<typename _U1, typename _U2>
223         tuple&
224         operator=(const pair<_U1, _U2>& __in)
225         {
226           this->_M_head = __in.first;
227           this->_M_tail()._M_head = __in.second;
228           return *this;
229         }
230     };
231
232   
233   /// Gives the type of the ith element of a given tuple type.
234   template<int __i, typename _Tp>
235     struct tuple_element;
236
237   /**
238    * @if maint
239    * Recursive case for tuple_element: strip off the first element in
240    * the tuple and retrieve the (i-1)th element of the remaining tuple.
241    * @endif
242    */
243   template<int __i, typename _Head, typename... _Tail>
244     struct tuple_element<__i, tuple<_Head, _Tail...> >
245     : tuple_element<__i - 1, tuple<_Tail...> > { };
246
247   /**
248    * @if maint
249    * Basis case for tuple_element: The first element is the one we're seeking.
250    * @endif
251    */
252   template<typename _Head, typename... _Tail>
253     struct tuple_element<0, tuple<_Head, _Tail...> >
254     {
255       typedef _Head type;
256     };
257
258   /// Finds the size of a given tuple type.
259   template<typename _Tp>
260     struct tuple_size;
261
262   /// @brief class tuple_size
263   template<typename... _Elements>
264     struct tuple_size<tuple<_Elements...> >
265     {
266       static const int value = sizeof...(_Elements);
267     };
268
269   template<typename... _Elements>
270     const int tuple_size<tuple<_Elements...> >::value;
271
272   // Returns a const reference to the ith element of a tuple.
273   // Any const or non-const ref elements are returned with their original type.
274   template<int __i, typename _Head, typename... _Tail>
275     inline typename __add_ref<_Head>::type
276     get(_Tuple_impl<__i, _Head, _Tail...>& __t)
277     {
278       return __t._M_head;
279     }
280
281   template<int __i, typename _Head, typename... _Tail>
282     inline typename __add_c_ref<_Head>::type
283     get(const _Tuple_impl<__i, _Head, _Tail...>& __t)
284     {
285       return __t._M_head;
286     }
287
288   // This class helps construct the various comparison operations on tuples
289   template<int __check_equal_size, int __i, int __j,
290            typename _Tp, typename _Up>
291     struct __tuple_compare;
292
293   template<int __i, int __j, typename _Tp, typename _Up>
294     struct __tuple_compare<0, __i, __j, _Tp, _Up>
295     {
296       static bool __eq(const _Tp& __t, const _Up& __u)
297       {
298         return (get<__i>(__t) == get<__i>(__u) &&
299                 __tuple_compare<0, __i+1, __j, _Tp, _Up>::__eq(__t, __u));
300       }
301      
302       static bool __less(const _Tp& __t, const _Up& __u)
303       {
304         return ((get<__i>(__t) < get<__i>(__u))
305                 || !(get<__i>(__u) < get<__i>(__t)) &&
306                 __tuple_compare<0, __i+1, __j, _Tp, _Up>::__less(__t, __u));
307       }
308     };
309
310   template<int __i, typename _Tp, typename _Up>
311     struct __tuple_compare<0, __i, __i, _Tp, _Up>
312     {
313       static bool __eq(const _Tp&, const _Up&)
314       { return true; }
315      
316       static bool __less(const _Tp&, const _Up&)
317       { return false; }
318     };
319
320   template<typename... _TElements, typename... _UElements>
321     bool
322     operator==(const tuple<_TElements...>& __t,
323                const tuple<_UElements...>& __u)
324     {
325       typedef tuple<_TElements...> _Tp;
326       typedef tuple<_UElements...> _Up;
327       return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Tp>::value,
328               0, tuple_size<_Tp>::value, _Tp, _Up>::__eq(__t, __u));
329     }
330
331   template<typename... _TElements, typename... _UElements>
332     bool
333     operator<(const tuple<_TElements...>& __t,
334               const tuple<_UElements...>& __u)
335     {
336       typedef tuple<_TElements...> _Tp;
337       typedef tuple<_UElements...> _Up;
338       return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Tp>::value,
339               0, tuple_size<_Tp>::value, _Tp, _Up>::__less(__t, __u));
340     }
341
342   template<typename... _TElements, typename... _UElements>
343     bool
344     operator!=(const tuple<_TElements...>& __t,
345                const tuple<_UElements...>& __u)
346     { return !(__t == __u); }
347
348   template<typename... _TElements, typename... _UElements>
349     bool
350     operator>(const tuple<_TElements...>& __t,
351               const tuple<_UElements...>& __u)
352     { return __u < __t; }
353
354   template<typename... _TElements, typename... _UElements>
355     bool
356     operator<=(const tuple<_TElements...>& __t,
357                const tuple<_UElements...>& __u)
358     { return !(__u < __t); }
359
360   template<typename... _TElements, typename... _UElements>
361     bool
362     operator>=(const tuple<_TElements...>& __t,
363                const tuple<_UElements...>& __u)
364     { return !(__t < __u); }
365
366   // Helper which adds a reference to a type when given a reference_wrapper
367   template<typename _Tp>
368     struct __strip_reference_wrapper
369     {
370       typedef _Tp __type;
371     };
372
373   template<typename _Tp>
374     struct __strip_reference_wrapper<reference_wrapper<_Tp> >
375     {
376       typedef _Tp& __type;
377     };
378
379   template<typename _Tp>
380     struct __strip_reference_wrapper<const reference_wrapper<_Tp> >
381     {
382       typedef _Tp& __type;
383     };
384
385   template<typename... _Elements>
386     inline tuple<typename __strip_reference_wrapper<_Elements>::__type...>
387     make_tuple(_Elements... __args)
388     {
389       typedef tuple<typename __strip_reference_wrapper<_Elements>::__type...>
390         __result_type;
391       return __result_type(__args...);
392     }
393
394   template<typename... _Elements>
395     inline tuple<_Elements&...>
396     tie(_Elements&... __args)
397     {
398       return tuple<_Elements&...>(__args...);
399     }
400
401   // A class (and instance) which can be used in 'tie' when an element
402   // of a tuple is not required
403   struct _Swallow_assign
404   {
405     template<class _Tp>
406       _Swallow_assign&
407       operator=(const _Tp&)
408       { return *this; }
409   };
410
411   // TODO: Put this in some kind of shared file.
412   namespace
413   {
414     _Swallow_assign ignore;
415   }; // anonymous namespace
416
417 _GLIBCXX_END_NAMESPACE
418 }
419
420 #endif