]>
Commit | Line | Data |
---|---|---|
af13a7a6 BK |
1 | // <tuple> -*- C++ -*- |
2 | ||
ab65a4c7 | 3 | // Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc. |
af13a7a6 BK |
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 | |
748086b7 | 8 | // Free Software Foundation; either version 3, or (at your option) |
af13a7a6 BK |
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 | ||
748086b7 JJ |
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/>. | |
af13a7a6 BK |
24 | |
25 | /** @file include/tuple | |
26 | * This is a Standard C++ Library header. | |
27 | */ | |
28 | ||
4514bed6 BK |
29 | #ifndef _GLIBCXX_TUPLE |
30 | #define _GLIBCXX_TUPLE 1 | |
af13a7a6 BK |
31 | |
32 | #pragma GCC system_header | |
33 | ||
e133ace8 | 34 | #ifndef __GXX_EXPERIMENTAL_CXX0X__ |
ab65a4c7 | 35 | # include <bits/c++0x_warning.h> |
57317d2a | 36 | #else |
af13a7a6 | 37 | |
e133ace8 PC |
38 | #include <utility> |
39 | ||
12ffa228 BK |
40 | namespace std _GLIBCXX_VISIBILITY(default) |
41 | { | |
42 | _GLIBCXX_BEGIN_NAMESPACE_VERSION | |
53dc5044 | 43 | |
894d0b15 CF |
44 | // Adds a const reference to a non-reference type. |
45 | template<typename _Tp> | |
46 | struct __add_c_ref | |
47 | { typedef const _Tp& type; }; | |
48 | ||
49 | template<typename _Tp> | |
50 | struct __add_c_ref<_Tp&> | |
51 | { typedef _Tp& type; }; | |
52 | ||
53 | // Adds a reference to a non-reference type. | |
54 | template<typename _Tp> | |
55 | struct __add_ref | |
56 | { typedef _Tp& type; }; | |
57 | ||
58 | template<typename _Tp> | |
59 | struct __add_ref<_Tp&> | |
60 | { typedef _Tp& type; }; | |
61 | ||
740508be | 62 | template<std::size_t _Idx, typename _Head, bool _IsEmpty> |
ba60f6f9 PC |
63 | struct _Head_base; |
64 | ||
740508be | 65 | template<std::size_t _Idx, typename _Head> |
894d0b15 CF |
66 | struct _Head_base<_Idx, _Head, true> |
67 | : public _Head | |
68 | { | |
0e6ac87e | 69 | constexpr _Head_base() |
894d0b15 CF |
70 | : _Head() { } |
71 | ||
094a14ef | 72 | constexpr _Head_base(const _Head& __h) |
894d0b15 CF |
73 | : _Head(__h) { } |
74 | ||
b5b5e640 | 75 | template<typename _UHead> |
fe960d92 CF |
76 | _Head_base(_UHead&& __h) |
77 | : _Head(std::forward<_UHead>(__h)) { } | |
894d0b15 CF |
78 | |
79 | _Head& _M_head() { return *this; } | |
80 | const _Head& _M_head() const { return *this; } | |
fe960d92 | 81 | |
094a14ef | 82 | void |
258e15e0 PC |
83 | _M_swap_impl(_Head& __h) |
84 | { | |
85 | using std::swap; | |
86 | swap(__h, _M_head()); | |
87 | } | |
894d0b15 CF |
88 | }; |
89 | ||
740508be | 90 | template<std::size_t _Idx, typename _Head> |
894d0b15 CF |
91 | struct _Head_base<_Idx, _Head, false> |
92 | { | |
0e6ac87e | 93 | constexpr _Head_base() |
894d0b15 CF |
94 | : _M_head_impl() { } |
95 | ||
094a14ef | 96 | constexpr _Head_base(const _Head& __h) |
894d0b15 CF |
97 | : _M_head_impl(__h) { } |
98 | ||
b5b5e640 | 99 | template<typename _UHead> |
fe960d92 CF |
100 | _Head_base(_UHead&& __h) |
101 | : _M_head_impl(std::forward<_UHead>(__h)) { } | |
894d0b15 CF |
102 | |
103 | _Head& _M_head() { return _M_head_impl; } | |
104 | const _Head& _M_head() const { return _M_head_impl; } | |
105 | ||
3e93b275 | 106 | void |
ff74fd13 | 107 | _M_swap_impl(_Head& __h) |
3e93b275 CF |
108 | { |
109 | using std::swap; | |
258e15e0 | 110 | swap(__h, _M_head()); |
3e93b275 CF |
111 | } |
112 | ||
894d0b15 CF |
113 | _Head _M_head_impl; |
114 | }; | |
115 | ||
116 | /** | |
894d0b15 CF |
117 | * Contains the actual implementation of the @c tuple template, stored |
118 | * as a recursive inheritance hierarchy from the first element (most | |
119 | * derived class) to the last (least derived class). The @c Idx | |
120 | * parameter gives the 0-based index of the element stored at this | |
121 | * point in the hierarchy; we use it to implement a constant-time | |
122 | * get() operation. | |
894d0b15 | 123 | */ |
740508be | 124 | template<std::size_t _Idx, typename... _Elements> |
894d0b15 CF |
125 | struct _Tuple_impl; |
126 | ||
127 | /** | |
894d0b15 CF |
128 | * Zero-element tuple implementation. This is the basis case for the |
129 | * inheritance recursion. | |
894d0b15 | 130 | */ |
740508be | 131 | template<std::size_t _Idx> |
3e93b275 CF |
132 | struct _Tuple_impl<_Idx> |
133 | { | |
fe960d92 | 134 | protected: |
ff74fd13 | 135 | void _M_swap_impl(_Tuple_impl&) { /* no-op */ } |
3e93b275 | 136 | }; |
894d0b15 CF |
137 | |
138 | /** | |
894d0b15 CF |
139 | * Recursive tuple implementation. Here we store the @c Head element |
140 | * and derive from a @c Tuple_impl containing the remaining elements | |
141 | * (which contains the @c Tail). | |
894d0b15 | 142 | */ |
740508be | 143 | template<std::size_t _Idx, typename _Head, typename... _Tail> |
894d0b15 CF |
144 | struct _Tuple_impl<_Idx, _Head, _Tail...> |
145 | : public _Tuple_impl<_Idx + 1, _Tail...>, | |
146 | private _Head_base<_Idx, _Head, std::is_empty<_Head>::value> | |
147 | { | |
148 | typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited; | |
149 | typedef _Head_base<_Idx, _Head, std::is_empty<_Head>::value> _Base; | |
150 | ||
151 | _Head& _M_head() { return _Base::_M_head(); } | |
152 | const _Head& _M_head() const { return _Base::_M_head(); } | |
153 | ||
154 | _Inherited& _M_tail() { return *this; } | |
155 | const _Inherited& _M_tail() const { return *this; } | |
156 | ||
0e6ac87e | 157 | constexpr _Tuple_impl() |
894d0b15 CF |
158 | : _Inherited(), _Base() { } |
159 | ||
160 | explicit | |
094a14ef | 161 | constexpr _Tuple_impl(const _Head& __head, const _Tail&... __tail) |
894d0b15 CF |
162 | : _Inherited(__tail...), _Base(__head) { } |
163 | ||
ba60f6f9 PC |
164 | template<typename _UHead, typename... _UTail> |
165 | explicit | |
b5b5e640 PC |
166 | _Tuple_impl(_UHead&& __head, _UTail&&... __tail) |
167 | : _Inherited(std::forward<_UTail>(__tail)...), | |
168 | _Base(std::forward<_UHead>(__head)) { } | |
894d0b15 | 169 | |
094a14ef | 170 | constexpr _Tuple_impl(const _Tuple_impl&) = default; |
894d0b15 | 171 | |
ba60f6f9 | 172 | _Tuple_impl(_Tuple_impl&& __in) |
094a14ef | 173 | : _Inherited(std::move(__in._M_tail())), |
b5b5e640 | 174 | _Base(std::forward<_Head>(__in._M_head())) { } |
ba60f6f9 | 175 | |
894d0b15 | 176 | template<typename... _UElements> |
ba60f6f9 PC |
177 | _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in) |
178 | : _Inherited(__in._M_tail()), _Base(__in._M_head()) { } | |
179 | ||
180 | template<typename... _UElements> | |
181 | _Tuple_impl(_Tuple_impl<_Idx, _UElements...>&& __in) | |
4c650853 | 182 | : _Inherited(std::move(__in._M_tail())), |
cadd2a9c | 183 | _Base(std::move(__in._M_head())) { } |
894d0b15 CF |
184 | |
185 | _Tuple_impl& | |
186 | operator=(const _Tuple_impl& __in) | |
187 | { | |
188 | _M_head() = __in._M_head(); | |
189 | _M_tail() = __in._M_tail(); | |
190 | return *this; | |
191 | } | |
ba60f6f9 PC |
192 | |
193 | _Tuple_impl& | |
194 | operator=(_Tuple_impl&& __in) | |
195 | { | |
196 | _M_head() = std::move(__in._M_head()); | |
197 | _M_tail() = std::move(__in._M_tail()); | |
198 | return *this; | |
199 | } | |
200 | ||
201 | template<typename... _UElements> | |
202 | _Tuple_impl& | |
203 | operator=(const _Tuple_impl<_Idx, _UElements...>& __in) | |
204 | { | |
205 | _M_head() = __in._M_head(); | |
206 | _M_tail() = __in._M_tail(); | |
207 | return *this; | |
208 | } | |
209 | ||
210 | template<typename... _UElements> | |
211 | _Tuple_impl& | |
212 | operator=(_Tuple_impl<_Idx, _UElements...>&& __in) | |
213 | { | |
214 | _M_head() = std::move(__in._M_head()); | |
215 | _M_tail() = std::move(__in._M_tail()); | |
216 | return *this; | |
217 | } | |
3e93b275 | 218 | |
fe960d92 | 219 | protected: |
3e93b275 | 220 | void |
ff74fd13 | 221 | _M_swap_impl(_Tuple_impl& __in) |
3e93b275 | 222 | { |
fe960d92 CF |
223 | _Base::_M_swap_impl(__in._M_head()); |
224 | _Inherited::_M_swap_impl(__in._M_tail()); | |
3e93b275 | 225 | } |
894d0b15 CF |
226 | }; |
227 | ||
939759fc | 228 | /// tuple |
894d0b15 CF |
229 | template<typename... _Elements> |
230 | class tuple : public _Tuple_impl<0, _Elements...> | |
231 | { | |
232 | typedef _Tuple_impl<0, _Elements...> _Inherited; | |
233 | ||
234 | public: | |
0e6ac87e | 235 | constexpr tuple() |
894d0b15 CF |
236 | : _Inherited() { } |
237 | ||
238 | explicit | |
094a14ef | 239 | constexpr tuple(const _Elements&... __elements) |
894d0b15 CF |
240 | : _Inherited(__elements...) { } |
241 | ||
0a5c2065 PC |
242 | template<typename... _UElements, typename = typename |
243 | std::enable_if<sizeof...(_UElements) | |
244 | == sizeof...(_Elements)>::type> | |
ba60f6f9 PC |
245 | explicit |
246 | tuple(_UElements&&... __elements) | |
b5b5e640 | 247 | : _Inherited(std::forward<_UElements>(__elements)...) { } |
894d0b15 | 248 | |
094a14ef | 249 | constexpr tuple(const tuple&) = default; |
894d0b15 | 250 | |
ba60f6f9 | 251 | tuple(tuple&& __in) |
4c650853 | 252 | : _Inherited(static_cast<_Inherited&&>(__in)) { } |
ba60f6f9 | 253 | |
0a5c2065 PC |
254 | template<typename... _UElements, typename = typename |
255 | std::enable_if<sizeof...(_UElements) | |
256 | == sizeof...(_Elements)>::type> | |
ba60f6f9 | 257 | tuple(const tuple<_UElements...>& __in) |
0a5c2065 PC |
258 | : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) |
259 | { } | |
ba60f6f9 | 260 | |
0a5c2065 PC |
261 | template<typename... _UElements, typename = typename |
262 | std::enable_if<sizeof...(_UElements) | |
263 | == sizeof...(_Elements)>::type> | |
ba60f6f9 | 264 | tuple(tuple<_UElements...>&& __in) |
0a5c2065 | 265 | : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } |
894d0b15 CF |
266 | |
267 | tuple& | |
268 | operator=(const tuple& __in) | |
269 | { | |
270 | static_cast<_Inherited&>(*this) = __in; | |
271 | return *this; | |
272 | } | |
ba60f6f9 PC |
273 | |
274 | tuple& | |
275 | operator=(tuple&& __in) | |
276 | { | |
277 | static_cast<_Inherited&>(*this) = std::move(__in); | |
278 | return *this; | |
279 | } | |
280 | ||
0a5c2065 PC |
281 | template<typename... _UElements, typename = typename |
282 | std::enable_if<sizeof...(_UElements) | |
283 | == sizeof...(_Elements)>::type> | |
ba60f6f9 PC |
284 | tuple& |
285 | operator=(const tuple<_UElements...>& __in) | |
286 | { | |
287 | static_cast<_Inherited&>(*this) = __in; | |
288 | return *this; | |
289 | } | |
290 | ||
0a5c2065 PC |
291 | template<typename... _UElements, typename = typename |
292 | std::enable_if<sizeof...(_UElements) | |
293 | == sizeof...(_Elements)>::type> | |
ba60f6f9 PC |
294 | tuple& |
295 | operator=(tuple<_UElements...>&& __in) | |
296 | { | |
297 | static_cast<_Inherited&>(*this) = std::move(__in); | |
298 | return *this; | |
299 | } | |
3e93b275 CF |
300 | |
301 | void | |
ff74fd13 | 302 | swap(tuple& __in) |
fe960d92 | 303 | { _Inherited::_M_swap_impl(__in); } |
894d0b15 CF |
304 | }; |
305 | ||
939759fc | 306 | template<> |
3e93b275 CF |
307 | class tuple<> |
308 | { | |
309 | public: | |
ff74fd13 | 310 | void swap(tuple&) { /* no-op */ } |
3e93b275 | 311 | }; |
939759fc BK |
312 | |
313 | /// tuple (2-element), with construction and assignment from a pair. | |
894d0b15 CF |
314 | template<typename _T1, typename _T2> |
315 | class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2> | |
316 | { | |
317 | typedef _Tuple_impl<0, _T1, _T2> _Inherited; | |
318 | ||
319 | public: | |
0e6ac87e | 320 | constexpr tuple() |
894d0b15 CF |
321 | : _Inherited() { } |
322 | ||
323 | explicit | |
094a14ef | 324 | constexpr tuple(const _T1& __a1, const _T2& __a2) |
894d0b15 CF |
325 | : _Inherited(__a1, __a2) { } |
326 | ||
327 | template<typename _U1, typename _U2> | |
ba60f6f9 PC |
328 | explicit |
329 | tuple(_U1&& __a1, _U2&& __a2) | |
330 | : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } | |
894d0b15 | 331 | |
094a14ef | 332 | constexpr tuple(const tuple&) = default; |
894d0b15 | 333 | |
ba60f6f9 | 334 | tuple(tuple&& __in) |
4c650853 | 335 | : _Inherited(static_cast<_Inherited&&>(__in)) { } |
ba60f6f9 PC |
336 | |
337 | template<typename _U1, typename _U2> | |
338 | tuple(const tuple<_U1, _U2>& __in) | |
b5b5e640 | 339 | : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { } |
ba60f6f9 PC |
340 | |
341 | template<typename _U1, typename _U2> | |
342 | tuple(tuple<_U1, _U2>&& __in) | |
4c650853 | 343 | : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } |
ba60f6f9 | 344 | |
894d0b15 CF |
345 | template<typename _U1, typename _U2> |
346 | tuple(const pair<_U1, _U2>& __in) | |
b5b5e640 | 347 | : _Inherited(__in.first, __in.second) { } |
ba60f6f9 | 348 | |
894d0b15 | 349 | template<typename _U1, typename _U2> |
ba60f6f9 | 350 | tuple(pair<_U1, _U2>&& __in) |
87b2e746 PC |
351 | : _Inherited(std::forward<_U1>(__in.first), |
352 | std::forward<_U2>(__in.second)) { } | |
894d0b15 CF |
353 | |
354 | tuple& | |
355 | operator=(const tuple& __in) | |
356 | { | |
357 | static_cast<_Inherited&>(*this) = __in; | |
358 | return *this; | |
359 | } | |
360 | ||
ba60f6f9 PC |
361 | tuple& |
362 | operator=(tuple&& __in) | |
363 | { | |
364 | static_cast<_Inherited&>(*this) = std::move(__in); | |
365 | return *this; | |
366 | } | |
367 | ||
368 | template<typename _U1, typename _U2> | |
369 | tuple& | |
370 | operator=(const tuple<_U1, _U2>& __in) | |
371 | { | |
372 | static_cast<_Inherited&>(*this) = __in; | |
373 | return *this; | |
374 | } | |
375 | ||
376 | template<typename _U1, typename _U2> | |
377 | tuple& | |
378 | operator=(tuple<_U1, _U2>&& __in) | |
379 | { | |
380 | static_cast<_Inherited&>(*this) = std::move(__in); | |
381 | return *this; | |
382 | } | |
383 | ||
894d0b15 CF |
384 | template<typename _U1, typename _U2> |
385 | tuple& | |
386 | operator=(const pair<_U1, _U2>& __in) | |
387 | { | |
388 | this->_M_head() = __in.first; | |
389 | this->_M_tail()._M_head() = __in.second; | |
390 | return *this; | |
391 | } | |
ba60f6f9 PC |
392 | |
393 | template<typename _U1, typename _U2> | |
394 | tuple& | |
395 | operator=(pair<_U1, _U2>&& __in) | |
396 | { | |
0a5c2065 PC |
397 | this->_M_head() = std::forward<_U1>(__in.first); |
398 | this->_M_tail()._M_head() = std::forward<_U2>(__in.second); | |
ba60f6f9 PC |
399 | return *this; |
400 | } | |
3e93b275 CF |
401 | |
402 | void | |
ff74fd13 | 403 | swap(tuple& __in) |
3e93b275 CF |
404 | { |
405 | using std::swap; | |
406 | swap(this->_M_head(), __in._M_head()); | |
407 | swap(this->_M_tail()._M_head(), __in._M_tail()._M_head()); | |
408 | } | |
894d0b15 CF |
409 | }; |
410 | ||
0a5c2065 PC |
411 | /// tuple (1-element). |
412 | template<typename _T1> | |
413 | class tuple<_T1> : public _Tuple_impl<0, _T1> | |
414 | { | |
415 | typedef _Tuple_impl<0, _T1> _Inherited; | |
416 | ||
417 | public: | |
0e6ac87e | 418 | constexpr tuple() |
0a5c2065 PC |
419 | : _Inherited() { } |
420 | ||
421 | explicit | |
094a14ef | 422 | constexpr tuple(const _T1& __a1) |
0a5c2065 PC |
423 | : _Inherited(__a1) { } |
424 | ||
425 | template<typename _U1, typename = typename | |
426 | std::enable_if<std::is_convertible<_U1, _T1>::value>::type> | |
427 | explicit | |
428 | tuple(_U1&& __a1) | |
429 | : _Inherited(std::forward<_U1>(__a1)) { } | |
430 | ||
094a14ef | 431 | constexpr tuple(const tuple&) = default; |
0a5c2065 PC |
432 | |
433 | tuple(tuple&& __in) | |
434 | : _Inherited(static_cast<_Inherited&&>(__in)) { } | |
435 | ||
436 | template<typename _U1> | |
437 | tuple(const tuple<_U1>& __in) | |
094a14ef | 438 | : _Inherited(static_cast<const _Tuple_impl<0, _U1>&>(__in)) { } |
0a5c2065 PC |
439 | |
440 | template<typename _U1> | |
441 | tuple(tuple<_U1>&& __in) | |
442 | : _Inherited(static_cast<_Tuple_impl<0, _U1>&&>(__in)) { } | |
443 | ||
444 | tuple& | |
445 | operator=(const tuple& __in) | |
446 | { | |
447 | static_cast<_Inherited&>(*this) = __in; | |
448 | return *this; | |
449 | } | |
450 | ||
451 | tuple& | |
452 | operator=(tuple&& __in) | |
453 | { | |
454 | static_cast<_Inherited&>(*this) = std::move(__in); | |
455 | return *this; | |
456 | } | |
457 | ||
458 | template<typename _U1> | |
459 | tuple& | |
460 | operator=(const tuple<_U1>& __in) | |
461 | { | |
462 | static_cast<_Inherited&>(*this) = __in; | |
463 | return *this; | |
464 | } | |
465 | ||
466 | template<typename _U1> | |
467 | tuple& | |
468 | operator=(tuple<_U1>&& __in) | |
469 | { | |
470 | static_cast<_Inherited&>(*this) = std::move(__in); | |
471 | return *this; | |
472 | } | |
473 | ||
474 | void | |
475 | swap(tuple& __in) | |
476 | { _Inherited::_M_swap_impl(__in); } | |
477 | }; | |
478 | ||
894d0b15 CF |
479 | |
480 | /// Gives the type of the ith element of a given tuple type. | |
740508be | 481 | template<std::size_t __i, typename _Tp> |
894d0b15 CF |
482 | struct tuple_element; |
483 | ||
484 | /** | |
894d0b15 CF |
485 | * Recursive case for tuple_element: strip off the first element in |
486 | * the tuple and retrieve the (i-1)th element of the remaining tuple. | |
894d0b15 | 487 | */ |
740508be | 488 | template<std::size_t __i, typename _Head, typename... _Tail> |
894d0b15 CF |
489 | struct tuple_element<__i, tuple<_Head, _Tail...> > |
490 | : tuple_element<__i - 1, tuple<_Tail...> > { }; | |
491 | ||
492 | /** | |
894d0b15 | 493 | * Basis case for tuple_element: The first element is the one we're seeking. |
894d0b15 CF |
494 | */ |
495 | template<typename _Head, typename... _Tail> | |
496 | struct tuple_element<0, tuple<_Head, _Tail...> > | |
497 | { | |
498 | typedef _Head type; | |
499 | }; | |
500 | ||
501 | /// Finds the size of a given tuple type. | |
502 | template<typename _Tp> | |
503 | struct tuple_size; | |
504 | ||
939759fc | 505 | /// class tuple_size |
894d0b15 CF |
506 | template<typename... _Elements> |
507 | struct tuple_size<tuple<_Elements...> > | |
508 | { | |
740508be | 509 | static const std::size_t value = sizeof...(_Elements); |
894d0b15 CF |
510 | }; |
511 | ||
512 | template<typename... _Elements> | |
740508be | 513 | const std::size_t tuple_size<tuple<_Elements...> >::value; |
894d0b15 | 514 | |
740508be | 515 | template<std::size_t __i, typename _Head, typename... _Tail> |
894d0b15 CF |
516 | inline typename __add_ref<_Head>::type |
517 | __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) | |
518 | { return __t._M_head(); } | |
519 | ||
740508be | 520 | template<std::size_t __i, typename _Head, typename... _Tail> |
894d0b15 CF |
521 | inline typename __add_c_ref<_Head>::type |
522 | __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) | |
523 | { return __t._M_head(); } | |
524 | ||
525 | // Return a reference (const reference) to the ith element of a tuple. | |
526 | // Any const or non-const ref elements are returned with their original type. | |
740508be | 527 | template<std::size_t __i, typename... _Elements> |
894d0b15 CF |
528 | inline typename __add_ref< |
529 | typename tuple_element<__i, tuple<_Elements...> >::type | |
530 | >::type | |
531 | get(tuple<_Elements...>& __t) | |
532 | { return __get_helper<__i>(__t); } | |
533 | ||
740508be | 534 | template<std::size_t __i, typename... _Elements> |
894d0b15 CF |
535 | inline typename __add_c_ref< |
536 | typename tuple_element<__i, tuple<_Elements...> >::type | |
537 | >::type | |
538 | get(const tuple<_Elements...>& __t) | |
539 | { return __get_helper<__i>(__t); } | |
540 | ||
541 | // This class helps construct the various comparison operations on tuples | |
740508be | 542 | template<std::size_t __check_equal_size, std::size_t __i, std::size_t __j, |
894d0b15 CF |
543 | typename _Tp, typename _Up> |
544 | struct __tuple_compare; | |
545 | ||
740508be | 546 | template<std::size_t __i, std::size_t __j, typename _Tp, typename _Up> |
894d0b15 CF |
547 | struct __tuple_compare<0, __i, __j, _Tp, _Up> |
548 | { | |
549 | static bool __eq(const _Tp& __t, const _Up& __u) | |
550 | { | |
551 | return (get<__i>(__t) == get<__i>(__u) && | |
740508be | 552 | __tuple_compare<0, __i + 1, __j, _Tp, _Up>::__eq(__t, __u)); |
894d0b15 CF |
553 | } |
554 | ||
555 | static bool __less(const _Tp& __t, const _Up& __u) | |
556 | { | |
557 | return ((get<__i>(__t) < get<__i>(__u)) | |
558 | || !(get<__i>(__u) < get<__i>(__t)) && | |
740508be | 559 | __tuple_compare<0, __i + 1, __j, _Tp, _Up>::__less(__t, __u)); |
894d0b15 CF |
560 | } |
561 | }; | |
562 | ||
740508be | 563 | template<std::size_t __i, typename _Tp, typename _Up> |
894d0b15 CF |
564 | struct __tuple_compare<0, __i, __i, _Tp, _Up> |
565 | { | |
566 | static bool __eq(const _Tp&, const _Up&) | |
567 | { return true; } | |
568 | ||
569 | static bool __less(const _Tp&, const _Up&) | |
570 | { return false; } | |
571 | }; | |
572 | ||
573 | template<typename... _TElements, typename... _UElements> | |
574 | bool | |
575 | operator==(const tuple<_TElements...>& __t, | |
576 | const tuple<_UElements...>& __u) | |
577 | { | |
578 | typedef tuple<_TElements...> _Tp; | |
579 | typedef tuple<_UElements...> _Up; | |
230636fe | 580 | return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value, |
894d0b15 CF |
581 | 0, tuple_size<_Tp>::value, _Tp, _Up>::__eq(__t, __u)); |
582 | } | |
583 | ||
584 | template<typename... _TElements, typename... _UElements> | |
585 | bool | |
586 | operator<(const tuple<_TElements...>& __t, | |
587 | const tuple<_UElements...>& __u) | |
588 | { | |
589 | typedef tuple<_TElements...> _Tp; | |
590 | typedef tuple<_UElements...> _Up; | |
230636fe | 591 | return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value, |
894d0b15 CF |
592 | 0, tuple_size<_Tp>::value, _Tp, _Up>::__less(__t, __u)); |
593 | } | |
594 | ||
595 | template<typename... _TElements, typename... _UElements> | |
596 | inline bool | |
597 | operator!=(const tuple<_TElements...>& __t, | |
598 | const tuple<_UElements...>& __u) | |
599 | { return !(__t == __u); } | |
600 | ||
601 | template<typename... _TElements, typename... _UElements> | |
602 | inline bool | |
603 | operator>(const tuple<_TElements...>& __t, | |
604 | const tuple<_UElements...>& __u) | |
605 | { return __u < __t; } | |
606 | ||
607 | template<typename... _TElements, typename... _UElements> | |
608 | inline bool | |
609 | operator<=(const tuple<_TElements...>& __t, | |
610 | const tuple<_UElements...>& __u) | |
611 | { return !(__u < __t); } | |
612 | ||
613 | template<typename... _TElements, typename... _UElements> | |
614 | inline bool | |
615 | operator>=(const tuple<_TElements...>& __t, | |
616 | const tuple<_UElements...>& __u) | |
617 | { return !(__t < __u); } | |
618 | ||
619 | // NB: DR 705. | |
620 | template<typename... _Elements> | |
621 | inline tuple<typename __decay_and_strip<_Elements>::__type...> | |
622 | make_tuple(_Elements&&... __args) | |
623 | { | |
624 | typedef tuple<typename __decay_and_strip<_Elements>::__type...> | |
625 | __result_type; | |
626 | return __result_type(std::forward<_Elements>(__args)...); | |
627 | } | |
628 | ||
5e108459 | 629 | template<typename... _Elements> |
00e9a944 PC |
630 | inline tuple<_Elements&&...> |
631 | forward_as_tuple(_Elements&&... __args) | |
632 | { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); } | |
5e108459 | 633 | |
740508be | 634 | template<std::size_t...> struct __index_holder { }; |
894d0b15 | 635 | |
740508be | 636 | template<std::size_t __i, typename _IdxHolder, typename... _Elements> |
894d0b15 CF |
637 | struct __index_holder_impl; |
638 | ||
740508be PC |
639 | template<std::size_t __i, std::size_t... _Indexes, typename _IdxHolder, |
640 | typename... _Elements> | |
894d0b15 CF |
641 | struct __index_holder_impl<__i, __index_holder<_Indexes...>, |
642 | _IdxHolder, _Elements...> | |
643 | { | |
644 | typedef typename __index_holder_impl<__i + 1, | |
645 | __index_holder<_Indexes..., __i>, | |
646 | _Elements...>::type type; | |
647 | }; | |
648 | ||
740508be | 649 | template<std::size_t __i, std::size_t... _Indexes> |
894d0b15 CF |
650 | struct __index_holder_impl<__i, __index_holder<_Indexes...> > |
651 | { typedef __index_holder<_Indexes...> type; }; | |
652 | ||
653 | template<typename... _Elements> | |
654 | struct __make_index_holder | |
655 | : __index_holder_impl<0, __index_holder<>, _Elements...> { }; | |
656 | ||
740508be PC |
657 | template<typename... _TElements, std::size_t... _TIdx, |
658 | typename... _UElements, std::size_t... _UIdx> | |
894d0b15 CF |
659 | inline tuple<_TElements..., _UElements...> |
660 | __tuple_cat_helper(const tuple<_TElements...>& __t, | |
661 | const __index_holder<_TIdx...>&, | |
662 | const tuple<_UElements...>& __u, | |
663 | const __index_holder<_UIdx...>&) | |
664 | { return tuple<_TElements..., _UElements...>(get<_TIdx>(__t)..., | |
665 | get<_UIdx>(__u)...); } | |
666 | ||
740508be PC |
667 | template<typename... _TElements, std::size_t... _TIdx, |
668 | typename... _UElements, std::size_t... _UIdx> | |
894d0b15 CF |
669 | inline tuple<_TElements..., _UElements...> |
670 | __tuple_cat_helper(tuple<_TElements...>&& __t, | |
671 | const __index_holder<_TIdx...>&, | |
672 | const tuple<_UElements...>& __u, | |
673 | const __index_holder<_UIdx...>&) | |
b5b5e640 PC |
674 | { return tuple<_TElements..., _UElements...> |
675 | (std::move(get<_TIdx>(__t))..., get<_UIdx>(__u)...); } | |
894d0b15 | 676 | |
740508be PC |
677 | template<typename... _TElements, std::size_t... _TIdx, |
678 | typename... _UElements, std::size_t... _UIdx> | |
894d0b15 CF |
679 | inline tuple<_TElements..., _UElements...> |
680 | __tuple_cat_helper(const tuple<_TElements...>& __t, | |
681 | const __index_holder<_TIdx...>&, | |
682 | tuple<_UElements...>&& __u, | |
683 | const __index_holder<_UIdx...>&) | |
b5b5e640 PC |
684 | { return tuple<_TElements..., _UElements...> |
685 | (get<_TIdx>(__t)..., std::move(get<_UIdx>(__u))...); } | |
894d0b15 | 686 | |
740508be PC |
687 | template<typename... _TElements, std::size_t... _TIdx, |
688 | typename... _UElements, std::size_t... _UIdx> | |
894d0b15 CF |
689 | inline tuple<_TElements..., _UElements...> |
690 | __tuple_cat_helper(tuple<_TElements...>&& __t, | |
691 | const __index_holder<_TIdx...>&, | |
692 | tuple<_UElements...>&& __u, | |
693 | const __index_holder<_UIdx...>&) | |
b5b5e640 PC |
694 | { return tuple<_TElements..., _UElements...> |
695 | (std::move(get<_TIdx>(__t))..., std::move(get<_UIdx>(__u))...); } | |
894d0b15 CF |
696 | |
697 | template<typename... _TElements, typename... _UElements> | |
698 | inline tuple<_TElements..., _UElements...> | |
699 | tuple_cat(const tuple<_TElements...>& __t, const tuple<_UElements...>& __u) | |
740508be | 700 | { |
894d0b15 CF |
701 | return __tuple_cat_helper(__t, typename |
702 | __make_index_holder<_TElements...>::type(), | |
703 | __u, typename | |
704 | __make_index_holder<_UElements...>::type()); | |
705 | } | |
706 | ||
707 | template<typename... _TElements, typename... _UElements> | |
708 | inline tuple<_TElements..., _UElements...> | |
709 | tuple_cat(tuple<_TElements...>&& __t, const tuple<_UElements...>& __u) | |
710 | { | |
711 | return __tuple_cat_helper(std::move(__t), typename | |
712 | __make_index_holder<_TElements...>::type(), | |
713 | __u, typename | |
714 | __make_index_holder<_UElements...>::type()); | |
715 | } | |
716 | ||
717 | template<typename... _TElements, typename... _UElements> | |
718 | inline tuple<_TElements..., _UElements...> | |
719 | tuple_cat(const tuple<_TElements...>& __t, tuple<_UElements...>&& __u) | |
720 | { | |
721 | return __tuple_cat_helper(__t, typename | |
722 | __make_index_holder<_TElements...>::type(), | |
723 | std::move(__u), typename | |
724 | __make_index_holder<_UElements...>::type()); | |
725 | } | |
726 | ||
727 | template<typename... _TElements, typename... _UElements> | |
728 | inline tuple<_TElements..., _UElements...> | |
729 | tuple_cat(tuple<_TElements...>&& __t, tuple<_UElements...>&& __u) | |
730 | { | |
731 | return __tuple_cat_helper(std::move(__t), typename | |
732 | __make_index_holder<_TElements...>::type(), | |
733 | std::move(__u), typename | |
734 | __make_index_holder<_UElements...>::type()); | |
735 | } | |
736 | ||
894d0b15 CF |
737 | template<typename... _Elements> |
738 | inline tuple<_Elements&...> | |
739 | tie(_Elements&... __args) | |
740 | { return tuple<_Elements&...>(__args...); } | |
741 | ||
3e93b275 CF |
742 | template<typename... _Elements> |
743 | inline void | |
744 | swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y) | |
745 | { __x.swap(__y); } | |
746 | ||
894d0b15 CF |
747 | // A class (and instance) which can be used in 'tie' when an element |
748 | // of a tuple is not required | |
749 | struct _Swallow_assign | |
750 | { | |
751 | template<class _Tp> | |
cff90044 JW |
752 | const _Swallow_assign& |
753 | operator=(const _Tp&) const | |
894d0b15 CF |
754 | { return *this; } |
755 | }; | |
756 | ||
cff90044 | 757 | const _Swallow_assign ignore{}; |
5e108459 PC |
758 | |
759 | /** | |
760 | * Stores a tuple of indices. Used by bind() to extract the elements | |
761 | * in a tuple. | |
762 | */ | |
763 | template<int... _Indexes> | |
764 | struct _Index_tuple | |
765 | { | |
766 | typedef _Index_tuple<_Indexes..., sizeof...(_Indexes)> __next; | |
767 | }; | |
768 | ||
769 | /// Builds an _Index_tuple<0, 1, 2, ..., _Num-1>. | |
770 | template<std::size_t _Num> | |
771 | struct _Build_index_tuple | |
772 | { | |
773 | typedef typename _Build_index_tuple<_Num-1>::__type::__next __type; | |
774 | }; | |
775 | ||
776 | template<> | |
777 | struct _Build_index_tuple<0> | |
778 | { | |
779 | typedef _Index_tuple<> __type; | |
780 | }; | |
781 | ||
782 | // See stl_pair.h... | |
783 | template<class _T1, class _T2> | |
784 | template<typename _Tp, typename... _Args> | |
785 | inline _Tp | |
786 | pair<_T1, _T2>:: | |
787 | __cons(tuple<_Args...>&& __tuple) | |
788 | { | |
789 | typedef typename _Build_index_tuple<sizeof...(_Args)>::__type | |
790 | _Indexes; | |
791 | return __do_cons<_Tp>(std::move(__tuple), _Indexes()); | |
792 | } | |
793 | ||
794 | template<class _T1, class _T2> | |
795 | template<typename _Tp, typename... _Args, int... _Indexes> | |
796 | inline _Tp | |
797 | pair<_T1, _T2>:: | |
798 | __do_cons(tuple<_Args...>&& __tuple, | |
799 | const _Index_tuple<_Indexes...>&) | |
800 | { return _Tp(std::forward<_Args>(get<_Indexes>(__tuple))...); } | |
53dc5044 | 801 | |
12ffa228 BK |
802 | _GLIBCXX_END_NAMESPACE_VERSION |
803 | } // namespace | |
af13a7a6 | 804 | |
57317d2a PC |
805 | #endif // __GXX_EXPERIMENTAL_CXX0X__ |
806 | ||
4514bed6 | 807 | #endif // _GLIBCXX_TUPLE |