• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/toolchains/hndtools-arm-linux-2.6.36-uclibc-4.5.3/arm-linux/include/c++/4.5.3/tr1/
1// class template tuple -*- C++ -*-
2
3// Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 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 tr1/tuple
26*  This is a TR1 C++ Library header.
27*/
28
29// Chris Jefferson <chris@bubblescope.net>
30// Variadic Templates support by Douglas Gregor <doug.gregor@gmail.com>
31
32#ifndef _GLIBCXX_TR1_TUPLE
33#define _GLIBCXX_TR1_TUPLE 1
34
35#pragma GCC system_header
36
37#include <utility>
38
39namespace std
40{
41namespace tr1
42{
43  // Adds a const reference to a non-reference type.
44  template<typename _Tp>
45    struct __add_c_ref
46    { typedef const _Tp& type; };
47
48  template<typename _Tp>
49    struct __add_c_ref<_Tp&>
50    { typedef _Tp& type; };
51
52  // Adds a reference to a non-reference type.
53  template<typename _Tp>
54    struct __add_ref
55    { typedef _Tp& type; };
56
57  template<typename _Tp>
58    struct __add_ref<_Tp&>
59    { typedef _Tp& type; };
60
61  /**
62   * Contains the actual implementation of the @c tuple template, stored
63   * as a recursive inheritance hierarchy from the first element (most
64   * derived class) to the last (least derived class). The @c Idx
65   * parameter gives the 0-based index of the element stored at this
66   * point in the hierarchy; we use it to implement a constant-time
67   * get() operation.
68   */
69  template<int _Idx, typename... _Elements>
70    struct _Tuple_impl; 
71
72  /**
73   * Zero-element tuple implementation. This is the basis case for the 
74   * inheritance recursion.
75   */
76  template<int _Idx>
77    struct _Tuple_impl<_Idx> { };
78
79  /**
80   * Recursive tuple implementation. Here we store the @c Head element
81   * and derive from a @c Tuple_impl containing the remaining elements
82   * (which contains the @c Tail).
83   */
84  template<int _Idx, typename _Head, typename... _Tail>
85    struct _Tuple_impl<_Idx, _Head, _Tail...>
86    : public _Tuple_impl<_Idx + 1, _Tail...>
87    {
88      typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
89      
90      _Head _M_head;
91      
92      _Inherited&       _M_tail()       { return *this; }
93      const _Inherited& _M_tail() const { return *this; }
94      
95      _Tuple_impl() : _Inherited(), _M_head() { }
96      
97      explicit 
98      _Tuple_impl(typename __add_c_ref<_Head>::type __head,
99		  typename __add_c_ref<_Tail>::type... __tail)
100      : _Inherited(__tail...), _M_head(__head) { }
101
102      template<typename... _UElements>
103      _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in)
104      : _Inherited(__in._M_tail()), _M_head(__in._M_head) { }
105
106      _Tuple_impl(const _Tuple_impl& __in)
107      : _Inherited(__in._M_tail()), _M_head(__in._M_head) { }
108     
109      template<typename... _UElements>
110        _Tuple_impl&
111        operator=(const _Tuple_impl<_Idx, _UElements...>& __in)
112        {
113	  _M_head = __in._M_head;
114	  _M_tail() = __in._M_tail();
115	  return *this;
116	}
117
118      _Tuple_impl&
119      operator=(const _Tuple_impl& __in)
120      {
121	_M_head = __in._M_head;
122	_M_tail() = __in._M_tail();
123	return *this;
124      }
125    };
126
127  template<typename... _Elements> 
128    class tuple : public _Tuple_impl<0, _Elements...>
129    {
130      typedef _Tuple_impl<0, _Elements...> _Inherited;
131
132    public:
133      tuple() : _Inherited() { }
134
135      explicit
136      tuple(typename __add_c_ref<_Elements>::type... __elements)
137      : _Inherited(__elements...) { }
138
139      template<typename... _UElements>
140        tuple(const tuple<_UElements...>& __in)
141	: _Inherited(__in) { }
142
143      tuple(const tuple& __in)
144      : _Inherited(__in) { }
145
146      template<typename... _UElements>
147        tuple&
148        operator=(const tuple<_UElements...>& __in)
149        {
150	  static_cast<_Inherited&>(*this) = __in;
151	  return *this;
152	}
153
154      tuple&
155      operator=(const tuple& __in)
156      {
157	static_cast<_Inherited&>(*this) = __in;
158	return *this;
159      }
160    };
161
162  template<> class tuple<> { };
163
164  // 2-element tuple, with construction and assignment from a pair.
165  template<typename _T1, typename _T2>
166    class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
167    {
168      typedef _Tuple_impl<0, _T1, _T2> _Inherited;
169
170    public:
171      tuple() : _Inherited() { }
172
173      explicit
174      tuple(typename __add_c_ref<_T1>::type __a1,
175	    typename __add_c_ref<_T2>::type __a2)
176      : _Inherited(__a1, __a2) { }
177
178      template<typename _U1, typename _U2>
179        tuple(const tuple<_U1, _U2>& __in)
180	: _Inherited(__in) { }
181
182      tuple(const tuple& __in)
183      : _Inherited(__in) { }
184
185      template<typename _U1, typename _U2>
186        tuple(const pair<_U1, _U2>& __in)
187	: _Inherited(_Tuple_impl<0, 
188		     typename __add_c_ref<_U1>::type,
189		     typename __add_c_ref<_U2>::type>(__in.first, 
190						      __in.second))
191        { }
192  
193      template<typename _U1, typename _U2>
194        tuple&
195        operator=(const tuple<_U1, _U2>& __in)
196        {
197	  static_cast<_Inherited&>(*this) = __in;
198	  return *this;
199	}
200
201      tuple&
202      operator=(const tuple& __in)
203      {
204	static_cast<_Inherited&>(*this) = __in;
205	return *this;
206      }
207
208      template<typename _U1, typename _U2>
209        tuple&
210        operator=(const pair<_U1, _U2>& __in)
211        {
212	  this->_M_head = __in.first;
213	  this->_M_tail()._M_head = __in.second;
214	  return *this;
215	}
216    };
217
218  
219  /// Gives the type of the ith element of a given tuple type.
220  template<int __i, typename _Tp>
221    struct tuple_element;
222
223  /**
224   * Recursive case for tuple_element: strip off the first element in
225   * the tuple and retrieve the (i-1)th element of the remaining tuple.
226   */
227  template<int __i, typename _Head, typename... _Tail>
228    struct tuple_element<__i, tuple<_Head, _Tail...> >
229    : tuple_element<__i - 1, tuple<_Tail...> > { };
230
231  /**
232   * Basis case for tuple_element: The first element is the one we're seeking.
233   */
234  template<typename _Head, typename... _Tail>
235    struct tuple_element<0, tuple<_Head, _Tail...> >
236    {
237      typedef _Head type;
238    };
239
240  /// Finds the size of a given tuple type.
241  template<typename _Tp>
242    struct tuple_size;
243
244  /// class tuple_size
245  template<typename... _Elements>
246    struct tuple_size<tuple<_Elements...> >
247    {
248      static const int value = sizeof...(_Elements);
249    };
250
251  template<typename... _Elements>
252    const int tuple_size<tuple<_Elements...> >::value;
253
254  template<int __i, typename _Head, typename... _Tail>
255    inline typename __add_ref<_Head>::type
256    __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t)
257    {
258      return __t._M_head;
259    }
260
261  template<int __i, typename _Head, typename... _Tail>
262    inline typename __add_c_ref<_Head>::type
263    __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t)
264    {
265      return __t._M_head;
266    }
267
268  // Return a reference (const reference) to the ith element of a tuple.
269  // Any const or non-const ref elements are returned with their original type.
270  template<int __i, typename... _Elements>
271    inline typename __add_ref<
272                      typename tuple_element<__i, tuple<_Elements...> >::type
273                    >::type
274    get(tuple<_Elements...>& __t)
275    { 
276      return __get_helper<__i>(__t); 
277    }
278
279  template<int __i, typename... _Elements>
280    inline typename __add_c_ref<
281                      typename tuple_element<__i, tuple<_Elements...> >::type
282                    >::type
283    get(const tuple<_Elements...>& __t)
284    {
285      return __get_helper<__i>(__t);
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<_Up>::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<_Up>::value,
339	      0, tuple_size<_Tp>::value, _Tp, _Up>::__less(__t, __u));
340    }
341
342  template<typename... _TElements, typename... _UElements>
343    inline bool
344    operator!=(const tuple<_TElements...>& __t,
345	       const tuple<_UElements...>& __u)
346    { return !(__t == __u); }
347
348  template<typename... _TElements, typename... _UElements>
349    inline bool
350    operator>(const tuple<_TElements...>& __t,
351	      const tuple<_UElements...>& __u)
352    { return __u < __t; }
353
354  template<typename... _TElements, typename... _UElements>
355    inline bool
356    operator<=(const tuple<_TElements...>& __t,
357	       const tuple<_UElements...>& __u)
358    { return !(__u < __t); }
359
360  template<typename... _TElements, typename... _UElements>
361    inline bool
362    operator>=(const tuple<_TElements...>& __t,
363	       const tuple<_UElements...>& __u)
364    { return !(__t < __u); }
365
366  template<typename _Tp>
367    class reference_wrapper;
368
369  // Helper which adds a reference to a type when given a reference_wrapper
370  template<typename _Tp>
371    struct __strip_reference_wrapper
372    {
373      typedef _Tp __type;
374    };
375
376  template<typename _Tp>
377    struct __strip_reference_wrapper<reference_wrapper<_Tp> >
378    {
379      typedef _Tp& __type;
380    };
381
382  template<typename _Tp>
383    struct __strip_reference_wrapper<const reference_wrapper<_Tp> >
384    {
385      typedef _Tp& __type;
386    };
387
388  template<typename... _Elements>
389    inline tuple<typename __strip_reference_wrapper<_Elements>::__type...>
390    make_tuple(_Elements... __args)
391    {
392      typedef tuple<typename __strip_reference_wrapper<_Elements>::__type...>
393        __result_type;
394      return __result_type(__args...);
395    }
396
397  template<typename... _Elements>
398    inline tuple<_Elements&...>
399    tie(_Elements&... __args)
400    {
401      return tuple<_Elements&...>(__args...);
402    }
403
404  // A class (and instance) which can be used in 'tie' when an element
405  // of a tuple is not required
406  struct _Swallow_assign
407  {
408    template<class _Tp>
409      _Swallow_assign&
410      operator=(const _Tp&)
411      { return *this; }
412  };
413
414  // TODO: Put this in some kind of shared file.
415  namespace
416  {
417    _Swallow_assign ignore;
418  }; // anonymous namespace
419}
420}
421
422#endif // _GLIBCXX_TR1_TUPLE
423