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