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