]> git.ipfire.org Git - thirdparty/gcc.git/blame - libstdc++-v3/include/std/tuple
PR libstdc++/36104 part four
[thirdparty/gcc.git] / libstdc++-v3 / include / std / tuple
CommitLineData
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
40namespace 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