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