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 | |
39 | namespace std _GLIBCXX_VISIBILITY(default) |
40 | { |
41 | _GLIBCXX_BEGIN_NAMESPACE_VERSION |
42 | |
43 | namespace 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 | |