OSDN Git Service

2007-05-17 Benjamin Kosnik <bkoz@redhat.com>
[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   template<int __i, typename _Head, typename... _Tail>
273     inline typename __add_ref<_Head>::type
274     __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t)
275     {
276       return __t._M_head;
277     }
278
279   template<int __i, typename _Head, typename... _Tail>
280     inline typename __add_c_ref<_Head>::type
281     __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t)
282     {
283       return __t._M_head;
284     }
285
286   // Return a reference (const reference) to the ith element of a tuple.
287   // Any const or non-const ref elements are returned with their original type.
288   template<int __i, typename... _Elements>
289     inline typename __add_ref<
290                       typename tuple_element<__i, tuple<_Elements...> >::type
291                     >::type
292     get(tuple<_Elements...>& __t)
293     { 
294       return __get_helper<__i>(__t); 
295     }
296
297   template<int __i, typename... _Elements>
298     inline typename __add_c_ref<
299                       typename tuple_element<__i, tuple<_Elements...> >::type
300                     >::type
301     get(const tuple<_Elements...>& __t)
302     {
303       return __get_helper<__i>(__t);
304     }
305
306   // This class helps construct the various comparison operations on tuples
307   template<int __check_equal_size, int __i, int __j,
308            typename _Tp, typename _Up>
309     struct __tuple_compare;
310
311   template<int __i, int __j, typename _Tp, typename _Up>
312     struct __tuple_compare<0, __i, __j, _Tp, _Up>
313     {
314       static bool __eq(const _Tp& __t, const _Up& __u)
315       {
316         return (get<__i>(__t) == get<__i>(__u) &&
317                 __tuple_compare<0, __i+1, __j, _Tp, _Up>::__eq(__t, __u));
318       }
319      
320       static bool __less(const _Tp& __t, const _Up& __u)
321       {
322         return ((get<__i>(__t) < get<__i>(__u))
323                 || !(get<__i>(__u) < get<__i>(__t)) &&
324                 __tuple_compare<0, __i+1, __j, _Tp, _Up>::__less(__t, __u));
325       }
326     };
327
328   template<int __i, typename _Tp, typename _Up>
329     struct __tuple_compare<0, __i, __i, _Tp, _Up>
330     {
331       static bool __eq(const _Tp&, const _Up&)
332       { return true; }
333      
334       static bool __less(const _Tp&, const _Up&)
335       { return false; }
336     };
337
338   template<typename... _TElements, typename... _UElements>
339     bool
340     operator==(const tuple<_TElements...>& __t,
341                const tuple<_UElements...>& __u)
342     {
343       typedef tuple<_TElements...> _Tp;
344       typedef tuple<_UElements...> _Up;
345       return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Tp>::value,
346               0, tuple_size<_Tp>::value, _Tp, _Up>::__eq(__t, __u));
347     }
348
349   template<typename... _TElements, typename... _UElements>
350     bool
351     operator<(const tuple<_TElements...>& __t,
352               const tuple<_UElements...>& __u)
353     {
354       typedef tuple<_TElements...> _Tp;
355       typedef tuple<_UElements...> _Up;
356       return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Tp>::value,
357               0, tuple_size<_Tp>::value, _Tp, _Up>::__less(__t, __u));
358     }
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   template<typename... _TElements, typename... _UElements>
367     bool
368     operator>(const tuple<_TElements...>& __t,
369               const tuple<_UElements...>& __u)
370     { return __u < __t; }
371
372   template<typename... _TElements, typename... _UElements>
373     bool
374     operator<=(const tuple<_TElements...>& __t,
375                const tuple<_UElements...>& __u)
376     { return !(__u < __t); }
377
378   template<typename... _TElements, typename... _UElements>
379     bool
380     operator>=(const tuple<_TElements...>& __t,
381                const tuple<_UElements...>& __u)
382     { return !(__t < __u); }
383
384   // Helper which adds a reference to a type when given a reference_wrapper
385   template<typename _Tp>
386     struct __strip_reference_wrapper
387     {
388       typedef _Tp __type;
389     };
390
391   template<typename _Tp>
392     struct __strip_reference_wrapper<reference_wrapper<_Tp> >
393     {
394       typedef _Tp& __type;
395     };
396
397   template<typename _Tp>
398     struct __strip_reference_wrapper<const reference_wrapper<_Tp> >
399     {
400       typedef _Tp& __type;
401     };
402
403   template<typename... _Elements>
404     inline tuple<typename __strip_reference_wrapper<_Elements>::__type...>
405     make_tuple(_Elements... __args)
406     {
407       typedef tuple<typename __strip_reference_wrapper<_Elements>::__type...>
408         __result_type;
409       return __result_type(__args...);
410     }
411
412   template<typename... _Elements>
413     inline tuple<_Elements&...>
414     tie(_Elements&... __args)
415     {
416       return tuple<_Elements&...>(__args...);
417     }
418
419   // A class (and instance) which can be used in 'tie' when an element
420   // of a tuple is not required
421   struct _Swallow_assign
422   {
423     template<class _Tp>
424       _Swallow_assign&
425       operator=(const _Tp&)
426       { return *this; }
427   };
428
429   // TODO: Put this in some kind of shared file.
430   namespace
431   {
432     _Swallow_assign ignore;
433   }; // anonymous namespace
434
435 _GLIBCXX_END_NAMESPACE
436 }
437
438 #endif