OSDN Git Service

2011-05-31 Jonathan Wakely <jwakely.gcc@gmail.com>
[pf3gnuchains/gcc-fork.git] / libstdc++-v3 / include / std / tuple
1 // <tuple> -*- C++ -*-
2
3 // Copyright (C) 2007, 2008, 2009, 2010, 2011 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 include/tuple
26  *  This is a Standard C++ Library header.
27  */
28
29 #ifndef _GLIBCXX_TUPLE
30 #define _GLIBCXX_TUPLE 1
31
32 #pragma GCC system_header
33
34 #ifndef __GXX_EXPERIMENTAL_CXX0X__
35 # include <bits/c++0x_warning.h>
36 #else
37
38 #include <utility>
39 #include <bits/uses_allocator.h>
40
41 namespace std _GLIBCXX_VISIBILITY(default)
42 {
43 _GLIBCXX_BEGIN_NAMESPACE_VERSION
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   // Adds an rvalue reference to a non-reference type.
64   template<typename _Tp>
65     struct __add_r_ref
66     { typedef _Tp&& type; };
67
68   template<typename _Tp>
69     struct __add_r_ref<_Tp&>
70     { typedef _Tp& type; };
71
72   template<std::size_t _Idx, typename _Head, bool _IsEmpty>
73     struct _Head_base;
74
75   template<std::size_t _Idx, typename _Head>
76     struct _Head_base<_Idx, _Head, true>
77     : public _Head
78     {
79       constexpr _Head_base()
80       : _Head() { }
81
82       constexpr _Head_base(const _Head& __h)
83       : _Head(__h) { }
84
85       template<typename _UHead, typename = typename
86                enable_if<!is_convertible<_UHead,
87                                          __uses_alloc_base>::value>::type>
88         _Head_base(_UHead&& __h)
89         : _Head(std::forward<_UHead>(__h)) { }
90
91       _Head_base(__uses_alloc0)
92       : _Head() { }
93
94       template<typename _Alloc>
95         _Head_base(__uses_alloc1<_Alloc> __a)
96         : _Head(allocator_arg, *__a._M_a) { }
97
98       template<typename _Alloc>
99         _Head_base(__uses_alloc2<_Alloc> __a)
100         : _Head(*__a._M_a) { }
101
102       template<typename _UHead>
103         _Head_base(__uses_alloc0, _UHead&& __uhead)
104         : _Head(std::forward<_UHead>(__uhead)) { }
105
106       template<typename _Alloc, typename _UHead>
107         _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
108         : _Head(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { }
109
110       template<typename _Alloc, typename _UHead>
111         _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
112         : _Head(std::forward<_UHead>(__uhead), *__a._M_a) { }
113
114       _Head&       _M_head() noexcept       { return *this; }
115       const _Head& _M_head() const noexcept { return *this; }
116     };
117
118   template<std::size_t _Idx, typename _Head>
119     struct _Head_base<_Idx, _Head, false>
120     {
121       constexpr _Head_base()
122       : _M_head_impl() { }
123
124       constexpr _Head_base(const _Head& __h)
125       : _M_head_impl(__h) { }
126
127       template<typename _UHead, typename = typename
128                enable_if<!is_convertible<_UHead,
129                                          __uses_alloc_base>::value>::type>
130         _Head_base(_UHead&& __h)
131         : _M_head_impl(std::forward<_UHead>(__h)) { }
132
133       _Head_base(__uses_alloc0)
134       : _M_head_impl() { }
135
136       template<typename _Alloc>
137         _Head_base(__uses_alloc1<_Alloc> __a)
138         : _M_head_impl(allocator_arg, *__a._M_a) { }
139
140       template<typename _Alloc>
141         _Head_base(__uses_alloc2<_Alloc> __a)
142         : _M_head_impl(*__a._M_a) { }
143
144       template<typename _UHead>
145         _Head_base(__uses_alloc0, _UHead&& __uhead)
146         : _M_head_impl(std::forward<_UHead>(__uhead)) { }
147
148       template<typename _Alloc, typename _UHead>
149         _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
150         : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead))
151         { }
152
153       template<typename _Alloc, typename _UHead>
154         _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
155         : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { }
156
157       _Head&       _M_head() noexcept       { return _M_head_impl; }
158       const _Head& _M_head() const noexcept { return _M_head_impl; }        
159
160       _Head _M_head_impl; 
161     };
162
163   /**
164    * Contains the actual implementation of the @c tuple template, stored
165    * as a recursive inheritance hierarchy from the first element (most
166    * derived class) to the last (least derived class). The @c Idx
167    * parameter gives the 0-based index of the element stored at this
168    * point in the hierarchy; we use it to implement a constant-time
169    * get() operation.
170    */
171   template<std::size_t _Idx, typename... _Elements>
172     struct _Tuple_impl; 
173
174   /**
175    * Zero-element tuple implementation. This is the basis case for the 
176    * inheritance recursion.
177    */
178   template<std::size_t _Idx>
179     struct _Tuple_impl<_Idx>
180     {
181       template<std::size_t, typename...> friend class _Tuple_impl;
182
183       _Tuple_impl() = default;
184
185       template<typename _Alloc>
186         _Tuple_impl(allocator_arg_t, const _Alloc&) { }
187
188       template<typename _Alloc>
189         _Tuple_impl(allocator_arg_t, const _Alloc&, const _Tuple_impl&) { }
190
191       template<typename _Alloc>
192         _Tuple_impl(allocator_arg_t, const _Alloc&, _Tuple_impl&&) { }
193
194     protected:
195       void _M_swap(_Tuple_impl&) noexcept { /* no-op */ }
196     };
197
198   /**
199    * Recursive tuple implementation. Here we store the @c Head element
200    * and derive from a @c Tuple_impl containing the remaining elements
201    * (which contains the @c Tail).
202    */
203   template<std::size_t _Idx, typename _Head, typename... _Tail>
204     struct _Tuple_impl<_Idx, _Head, _Tail...>
205     : public _Tuple_impl<_Idx + 1, _Tail...>,
206       private _Head_base<_Idx, _Head, std::is_empty<_Head>::value>
207     {
208       template<std::size_t, typename...> friend class _Tuple_impl;
209
210       typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
211       typedef _Head_base<_Idx, _Head, std::is_empty<_Head>::value> _Base;
212
213       _Head&            _M_head() noexcept       { return _Base::_M_head(); }
214       const _Head&      _M_head() const noexcept { return _Base::_M_head(); }
215
216       _Inherited&       _M_tail() noexcept       { return *this; }
217       const _Inherited& _M_tail() const noexcept { return *this; }
218
219       constexpr _Tuple_impl()
220       : _Inherited(), _Base() { }
221
222       explicit 
223       constexpr _Tuple_impl(const _Head& __head, const _Tail&... __tail)
224       : _Inherited(__tail...), _Base(__head) { }
225
226       template<typename _UHead, typename... _UTail, typename = typename
227                std::enable_if<sizeof...(_Tail)==sizeof...(_UTail)>::type> 
228         explicit
229         _Tuple_impl(_UHead&& __head, _UTail&&... __tail)
230         : _Inherited(std::forward<_UTail>(__tail)...),
231           _Base(std::forward<_UHead>(__head)) { }
232
233       constexpr _Tuple_impl(const _Tuple_impl&) = default;
234
235       _Tuple_impl(_Tuple_impl&& __in)
236       noexcept(std::is_nothrow_move_constructible<_Head>::value
237                && std::is_nothrow_move_constructible<_Inherited>::value)
238       : _Inherited(std::move(__in._M_tail())), 
239         _Base(std::forward<_Head>(__in._M_head())) { }
240
241       template<typename... _UElements>
242         _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in)
243         : _Inherited(__in._M_tail()), _Base(__in._M_head()) { }
244
245       template<typename _UHead, typename... _UTails>
246         _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
247         : _Inherited(std::move(__in._M_tail())),
248           _Base(std::forward<_UHead>(__in._M_head())) { }
249
250       template<typename _Alloc>
251         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
252         : _Inherited(__tag, __a),
253           _Base(__use_alloc<_Head>(__a)) { }
254
255       template<typename _Alloc>
256         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
257             const _Head& __head, const _Tail&... __tail)
258         : _Inherited(__tag, __a, __tail...),
259           _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { }
260
261       template<typename _Alloc, typename _UHead, typename... _UTail,
262                typename = typename std::enable_if<sizeof...(_Tail)
263                                                   ==sizeof...(_UTail)>::type>
264         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
265                     _UHead&& __head, _UTail&&... __tail)
266         : _Inherited(__tag, __a, std::forward<_UTail>(__tail)...),
267           _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
268                 std::forward<_UHead>(__head)) { }
269
270       template<typename _Alloc>
271         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
272                     const _Tuple_impl& __in)
273         : _Inherited(__tag, __a, __in._M_tail()), 
274           _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __in._M_head()) { }
275
276       template<typename _Alloc>
277         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
278                     _Tuple_impl&& __in)
279         noexcept(std::is_nothrow_move_constructible<_Head>::value
280                  && std::is_nothrow_move_constructible<_Inherited>::value)
281         : _Inherited(__tag, __a, std::move(__in._M_tail())), 
282           _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
283                 std::forward<_Head>(__in._M_head())) { }
284
285       template<typename _Alloc, typename... _UElements>
286         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
287                     const _Tuple_impl<_Idx, _UElements...>& __in)
288         : _Inherited(__tag, __a, __in._M_tail()),
289           _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __in._M_head()) { }
290
291       template<typename _Alloc, typename _UHead, typename... _UTails>
292         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
293                     _Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
294         : _Inherited(__tag, __a, std::move(__in._M_tail())),
295           _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
296                 std::forward<_UHead>(__in._M_head())) { }
297
298       _Tuple_impl&
299       operator=(const _Tuple_impl& __in)
300       {
301         _M_head() = __in._M_head();
302         _M_tail() = __in._M_tail();
303         return *this;
304       }
305
306       _Tuple_impl&
307       operator=(_Tuple_impl&& __in)
308       noexcept(std::is_nothrow_move_assignable<_Head>::value
309                && std::is_nothrow_move_assignable<_Inherited>::value)
310       {
311         _M_head() = std::forward<_Head>(__in._M_head());
312         _M_tail() = std::move(__in._M_tail());
313         return *this;
314       }
315
316       template<typename... _UElements>
317         _Tuple_impl&
318         operator=(const _Tuple_impl<_Idx, _UElements...>& __in)
319         {
320           _M_head() = __in._M_head();
321           _M_tail() = __in._M_tail();
322           return *this;
323         }
324
325       template<typename _UHead, typename... _UTails>
326         _Tuple_impl&
327         operator=(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
328         {
329           _M_head() = std::forward<_UHead>(__in._M_head());
330           _M_tail() = std::move(__in._M_tail());
331           return *this;
332         }
333
334     protected:
335       void
336       _M_swap(_Tuple_impl& __in)
337       noexcept(noexcept(swap(std::declval<_Head&>(),
338                              std::declval<_Head&>()))
339                && noexcept(__in._M_tail()._M_swap(__in._M_tail())))
340       {
341         using std::swap;
342         swap(this->_M_head(), __in._M_head());
343         _Inherited::_M_swap(__in._M_tail());
344       }
345     };
346
347   /// tuple
348   template<typename... _Elements> 
349     class tuple : public _Tuple_impl<0, _Elements...>
350     {
351       typedef _Tuple_impl<0, _Elements...> _Inherited;
352
353     public:
354       constexpr tuple()
355       : _Inherited() { }
356
357       explicit
358       constexpr tuple(const _Elements&... __elements)
359       : _Inherited(__elements...) { }
360
361       template<typename... _UElements, typename = typename
362                std::enable_if<sizeof...(_UElements)
363                               == sizeof...(_Elements)>::type>
364         explicit
365         tuple(_UElements&&... __elements)
366         : _Inherited(std::forward<_UElements>(__elements)...) { }
367
368       constexpr tuple(const tuple&) = default;
369       tuple(tuple&&) = default;
370
371       template<typename... _UElements, typename = typename
372                std::enable_if<sizeof...(_UElements)
373                               == sizeof...(_Elements)>::type>
374         tuple(const tuple<_UElements...>& __in)
375         : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
376         { }
377
378       template<typename... _UElements, typename = typename
379                std::enable_if<sizeof...(_UElements)
380                               == sizeof...(_Elements)>::type>
381         tuple(tuple<_UElements...>&& __in)
382         : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
383
384       // allocator-extended constructors
385
386       template<typename _Alloc>
387         tuple(allocator_arg_t __tag, const _Alloc& __a)
388         : _Inherited(__tag, __a) { }
389
390       template<typename _Alloc>
391         tuple(allocator_arg_t __tag, const _Alloc& __a,
392               const _Elements&... __elements)
393         : _Inherited(__tag, __a, __elements...) { }
394
395       template<typename _Alloc, typename... _UElements, typename = typename
396                std::enable_if<sizeof...(_UElements)
397                               == sizeof...(_Elements)>::type>
398         tuple(allocator_arg_t __tag, const _Alloc& __a,
399               _UElements&&... __elements)
400         : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
401         { }
402
403       template<typename _Alloc>
404         tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
405         : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
406
407       template<typename _Alloc>
408         tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
409         : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
410
411       template<typename _Alloc, typename... _UElements, typename = typename
412                std::enable_if<sizeof...(_UElements)
413                               == sizeof...(_Elements)>::type>
414         tuple(allocator_arg_t __tag, const _Alloc& __a,
415               const tuple<_UElements...>& __in)
416         : _Inherited(__tag, __a,
417                      static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
418         { }
419
420       template<typename _Alloc, typename... _UElements, typename = typename
421                std::enable_if<sizeof...(_UElements)
422                               == sizeof...(_Elements)>::type>
423         tuple(allocator_arg_t __tag, const _Alloc& __a,
424               tuple<_UElements...>&& __in)
425         : _Inherited(__tag, __a,
426                      static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
427         { }
428
429       tuple&
430       operator=(const tuple& __in)
431       {
432         static_cast<_Inherited&>(*this) = __in;
433         return *this;
434       }
435
436       tuple&
437       operator=(tuple&& __in)
438       noexcept(std::is_nothrow_move_assignable<_Inherited>::value)
439       {
440         static_cast<_Inherited&>(*this) = std::move(__in);
441         return *this;
442       }
443
444       template<typename... _UElements, typename = typename
445                std::enable_if<sizeof...(_UElements)
446                               == sizeof...(_Elements)>::type>
447         tuple&
448         operator=(const tuple<_UElements...>& __in)
449         {
450           static_cast<_Inherited&>(*this) = __in;
451           return *this;
452         }
453
454       template<typename... _UElements, typename = typename
455                std::enable_if<sizeof...(_UElements)
456                               == sizeof...(_Elements)>::type>
457         tuple&
458         operator=(tuple<_UElements...>&& __in)
459         {
460           static_cast<_Inherited&>(*this) = std::move(__in);
461           return *this;
462         }
463
464       void
465       swap(tuple& __in)
466       noexcept(noexcept(__in._M_swap(__in)))
467       { _Inherited::_M_swap(__in); }
468     };
469
470   template<>  
471     class tuple<>
472     {
473     public:
474       void swap(tuple&) noexcept { /* no-op */ }
475     };
476
477   /// tuple (2-element), with construction and assignment from a pair.
478   template<typename _T1, typename _T2>
479     class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
480     {
481       typedef _Tuple_impl<0, _T1, _T2> _Inherited;
482
483     public:
484       constexpr tuple()
485       : _Inherited() { }
486
487       explicit
488       constexpr tuple(const _T1& __a1, const _T2& __a2)
489       : _Inherited(__a1, __a2) { }
490
491       template<typename _U1, typename _U2>
492         explicit
493         tuple(_U1&& __a1, _U2&& __a2)
494         : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
495
496       constexpr tuple(const tuple&) = default;
497       tuple(tuple&&) = default;
498
499       template<typename _U1, typename _U2>
500         tuple(const tuple<_U1, _U2>& __in)
501         : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
502
503       template<typename _U1, typename _U2>
504         tuple(tuple<_U1, _U2>&& __in)
505         : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
506
507       template<typename _U1, typename _U2>
508         tuple(const pair<_U1, _U2>& __in)
509         : _Inherited(__in.first, __in.second) { }
510
511       template<typename _U1, typename _U2>
512         tuple(pair<_U1, _U2>&& __in)
513         : _Inherited(std::forward<_U1>(__in.first),
514                      std::forward<_U2>(__in.second)) { }
515
516       // allocator-extended constructors
517
518       template<typename _Alloc>
519         tuple(allocator_arg_t __tag, const _Alloc& __a)
520         : _Inherited(__tag, __a) { }
521
522       template<typename _Alloc>
523         tuple(allocator_arg_t __tag, const _Alloc& __a,
524               const _T1& __a1, const _T2& __a2)
525         : _Inherited(__tag, __a, __a1, __a2) { }
526
527       template<typename _Alloc, typename _U1, typename _U2>
528         tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2)
529         : _Inherited(__tag, __a, std::forward<_U1>(__a1),
530                      std::forward<_U2>(__a2)) { }
531
532       template<typename _Alloc>
533         tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
534         : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
535
536       template<typename _Alloc>
537         tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
538         : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
539
540       template<typename _Alloc, typename _U1, typename _U2>
541         tuple(allocator_arg_t __tag, const _Alloc& __a,
542               const tuple<_U1, _U2>& __in)
543         : _Inherited(__tag, __a,
544                      static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
545         { }
546
547       template<typename _Alloc, typename _U1, typename _U2>
548         tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
549         : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
550         { }
551
552       template<typename _Alloc, typename _U1, typename _U2>
553         tuple(allocator_arg_t __tag, const _Alloc& __a,
554               const pair<_U1, _U2>& __in)
555         : _Inherited(__tag, __a, __in.first, __in.second) { }
556
557       template<typename _Alloc, typename _U1, typename _U2>
558         tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
559         : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
560                      std::forward<_U2>(__in.second)) { }
561
562       tuple&
563       operator=(const tuple& __in)
564       {
565         static_cast<_Inherited&>(*this) = __in;
566         return *this;
567       }
568
569       tuple&
570       operator=(tuple&& __in)
571       noexcept(std::is_nothrow_move_assignable<_Inherited>::value)
572       {
573         static_cast<_Inherited&>(*this) = std::move(__in);
574         return *this;
575       }
576
577       template<typename _U1, typename _U2>
578         tuple&
579         operator=(const tuple<_U1, _U2>& __in)
580         {
581           static_cast<_Inherited&>(*this) = __in;
582           return *this;
583         }
584
585       template<typename _U1, typename _U2>
586         tuple&
587         operator=(tuple<_U1, _U2>&& __in)
588         {
589           static_cast<_Inherited&>(*this) = std::move(__in);
590           return *this;
591         }
592
593       template<typename _U1, typename _U2>
594         tuple&
595         operator=(const pair<_U1, _U2>& __in)
596         {
597           this->_M_head() = __in.first;
598           this->_M_tail()._M_head() = __in.second;
599           return *this;
600         }
601
602       template<typename _U1, typename _U2>
603         tuple&
604         operator=(pair<_U1, _U2>&& __in)
605         {
606           this->_M_head() = std::forward<_U1>(__in.first);
607           this->_M_tail()._M_head() = std::forward<_U2>(__in.second);
608           return *this;
609         }
610
611       void
612       swap(tuple& __in)
613       noexcept(noexcept(__in._M_swap(__in)))
614       { _Inherited::_M_swap(__in); }
615     };
616
617   /// tuple (1-element).
618   template<typename _T1>
619     class tuple<_T1> : public _Tuple_impl<0, _T1>
620     {
621       typedef _Tuple_impl<0, _T1> _Inherited;
622
623     public:
624       constexpr tuple()
625       : _Inherited() { }
626
627       explicit
628       constexpr tuple(const _T1& __a1)
629       : _Inherited(__a1) { }
630
631       template<typename _U1, typename = typename
632                std::enable_if<std::is_convertible<_U1, _T1>::value>::type>
633         explicit
634         tuple(_U1&& __a1)
635         : _Inherited(std::forward<_U1>(__a1)) { }
636
637       constexpr tuple(const tuple&) = default;
638       tuple(tuple&&) = default;
639
640       template<typename _U1>
641         tuple(const tuple<_U1>& __in)
642         : _Inherited(static_cast<const _Tuple_impl<0, _U1>&>(__in)) { }
643
644       template<typename _U1>
645         tuple(tuple<_U1>&& __in)
646         : _Inherited(static_cast<_Tuple_impl<0, _U1>&&>(__in)) { }
647
648       // allocator-extended constructors
649
650       template<typename _Alloc>
651         tuple(allocator_arg_t __tag, const _Alloc& __a)
652         : _Inherited(__tag, __a) { }
653
654       template<typename _Alloc>
655         tuple(allocator_arg_t __tag, const _Alloc& __a, const _T1& __a1)
656         : _Inherited(__tag, __a, __a1) { }
657
658       // TODO: constrain for is_uses_allocator_constructible<_T1, _U1&&, _Alloc>
659       template<typename _Alloc, typename _U1>
660         tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1)
661         : _Inherited(__tag, __a, std::forward<_U1>(__a1)) { }
662
663       template<typename _Alloc>
664         tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
665         : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
666
667       template<typename _Alloc>
668         tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
669         : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
670
671       template<typename _Alloc, typename _U1>
672         tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple<_U1>& __in)
673         : _Inherited(__tag, __a, static_cast<const _Tuple_impl<0, _U1>&>(__in))
674         { }
675
676       template<typename _Alloc, typename _U1>
677         tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1>&& __in)
678         : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1>&&>(__in)) { }
679
680       tuple&
681       operator=(const tuple& __in)
682       {
683         static_cast<_Inherited&>(*this) = __in;
684         return *this;
685       }
686
687       tuple&
688       operator=(tuple&& __in)
689       noexcept(std::is_nothrow_move_assignable<_Inherited>::value)
690       {
691         static_cast<_Inherited&>(*this) = std::move(__in);
692         return *this;
693       }
694
695       template<typename _U1>
696         tuple&
697         operator=(const tuple<_U1>& __in)
698         {
699           static_cast<_Inherited&>(*this) = __in;
700           return *this;
701         }
702
703       template<typename _U1>
704         tuple&
705         operator=(tuple<_U1>&& __in)
706         {
707           static_cast<_Inherited&>(*this) = std::move(__in);
708           return *this;
709         }
710
711       void
712       swap(tuple& __in)
713       noexcept(noexcept(__in._M_swap(__in)))
714       { _Inherited::_M_swap(__in); }
715     };
716
717
718   /// Gives the type of the ith element of a given tuple type.
719   template<std::size_t __i, typename _Tp>
720     struct tuple_element;
721
722   /**
723    * Recursive case for tuple_element: strip off the first element in
724    * the tuple and retrieve the (i-1)th element of the remaining tuple.
725    */
726   template<std::size_t __i, typename _Head, typename... _Tail>
727     struct tuple_element<__i, tuple<_Head, _Tail...> >
728     : tuple_element<__i - 1, tuple<_Tail...> > { };
729
730   /**
731    * Basis case for tuple_element: The first element is the one we're seeking.
732    */
733   template<typename _Head, typename... _Tail>
734     struct tuple_element<0, tuple<_Head, _Tail...> >
735     {
736       typedef _Head type;
737     };
738
739   template<std::size_t __i, typename _Tp>
740     struct tuple_element<__i, const _Tp>
741     {
742       typedef typename
743       add_const<typename tuple_element<__i, _Tp>::type>::type type;
744     };
745
746   template<std::size_t __i, typename _Tp>
747     struct tuple_element<__i, volatile _Tp>
748     {
749       typedef typename
750       add_volatile<typename tuple_element<__i, _Tp>::type>::type type;
751     };
752
753   template<std::size_t __i, typename _Tp>
754     struct tuple_element<__i, const volatile _Tp>
755     {
756       typedef typename
757       add_cv<typename tuple_element<__i, _Tp>::type>::type type;
758     };
759
760   /// Finds the size of a given tuple type.
761   template<typename _Tp>
762     struct tuple_size;
763
764   template<typename _Tp>
765     struct tuple_size<const _Tp>
766     : public integral_constant<
767              typename remove_cv<decltype(tuple_size<_Tp>::value)>::type,
768              tuple_size<_Tp>::value> { };
769
770   template<typename _Tp>
771     struct tuple_size<volatile _Tp>
772     : public integral_constant<
773              typename remove_cv<decltype(tuple_size<_Tp>::value)>::type,
774              tuple_size<_Tp>::value> { };
775
776   template<typename _Tp>
777     struct tuple_size<const volatile _Tp>
778     : public integral_constant<
779              typename remove_cv<decltype(tuple_size<_Tp>::value)>::type,
780              tuple_size<_Tp>::value> { };
781
782   /// class tuple_size
783   template<typename... _Elements>
784     struct tuple_size<tuple<_Elements...>>
785     : public integral_constant<std::size_t, sizeof...(_Elements)> { };
786
787   template<std::size_t __i, typename _Head, typename... _Tail>
788     inline typename __add_ref<_Head>::type
789     __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
790     { return __t._M_head(); }
791
792   template<std::size_t __i, typename _Head, typename... _Tail>
793     inline typename __add_c_ref<_Head>::type
794     __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
795     { return __t._M_head(); }
796
797   // Return a reference (const reference, rvalue reference) to the ith element
798   // of a tuple.  Any const or non-const ref elements are returned with their
799   // original type.
800   template<std::size_t __i, typename... _Elements>
801     inline typename __add_ref<
802                       typename tuple_element<__i, tuple<_Elements...>>::type
803                     >::type
804     get(tuple<_Elements...>& __t) noexcept
805     { return __get_helper<__i>(__t); }
806
807   template<std::size_t __i, typename... _Elements>
808     inline typename __add_c_ref<
809                       typename tuple_element<__i, tuple<_Elements...>>::type
810                     >::type
811     get(const tuple<_Elements...>& __t) noexcept
812     { return __get_helper<__i>(__t); }
813
814   template<std::size_t __i, typename... _Elements>
815     inline typename __add_r_ref<
816                       typename tuple_element<__i, tuple<_Elements...>>::type
817                     >::type
818     get(tuple<_Elements...>&& __t) noexcept
819     { return std::forward<typename tuple_element<__i,
820         tuple<_Elements...>>::type&&>(get<__i>(__t)); }
821
822   // This class helps construct the various comparison operations on tuples
823   template<std::size_t __check_equal_size, std::size_t __i, std::size_t __j,
824            typename _Tp, typename _Up>
825     struct __tuple_compare;
826
827   template<std::size_t __i, std::size_t __j, typename _Tp, typename _Up>
828     struct __tuple_compare<0, __i, __j, _Tp, _Up>
829     {
830       static bool __eq(const _Tp& __t, const _Up& __u)
831       {
832         return (get<__i>(__t) == get<__i>(__u) &&
833                 __tuple_compare<0, __i + 1, __j, _Tp, _Up>::__eq(__t, __u));
834       }
835      
836       static bool __less(const _Tp& __t, const _Up& __u)
837       {
838         return ((get<__i>(__t) < get<__i>(__u))
839                 || !(get<__i>(__u) < get<__i>(__t)) &&
840                 __tuple_compare<0, __i + 1, __j, _Tp, _Up>::__less(__t, __u));
841       }
842     };
843
844   template<std::size_t __i, typename _Tp, typename _Up>
845     struct __tuple_compare<0, __i, __i, _Tp, _Up>
846     {
847       static bool __eq(const _Tp&, const _Up&)
848       { return true; }
849      
850       static bool __less(const _Tp&, const _Up&)
851       { return false; }
852     };
853
854   template<typename... _TElements, typename... _UElements>
855     bool
856     operator==(const tuple<_TElements...>& __t,
857                const tuple<_UElements...>& __u)
858     {
859       typedef tuple<_TElements...> _Tp;
860       typedef tuple<_UElements...> _Up;
861       return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value,
862               0, tuple_size<_Tp>::value, _Tp, _Up>::__eq(__t, __u));
863     }
864
865   template<typename... _TElements, typename... _UElements>
866     bool
867     operator<(const tuple<_TElements...>& __t,
868               const tuple<_UElements...>& __u)
869     {
870       typedef tuple<_TElements...> _Tp;
871       typedef tuple<_UElements...> _Up;
872       return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value,
873               0, tuple_size<_Tp>::value, _Tp, _Up>::__less(__t, __u));
874     }
875
876   template<typename... _TElements, typename... _UElements>
877     inline bool
878     operator!=(const tuple<_TElements...>& __t,
879                const tuple<_UElements...>& __u)
880     { return !(__t == __u); }
881
882   template<typename... _TElements, typename... _UElements>
883     inline bool
884     operator>(const tuple<_TElements...>& __t,
885               const tuple<_UElements...>& __u)
886     { return __u < __t; }
887
888   template<typename... _TElements, typename... _UElements>
889     inline bool
890     operator<=(const tuple<_TElements...>& __t,
891                const tuple<_UElements...>& __u)
892     { return !(__u < __t); }
893
894   template<typename... _TElements, typename... _UElements>
895     inline bool
896     operator>=(const tuple<_TElements...>& __t,
897                const tuple<_UElements...>& __u)
898     { return !(__t < __u); }
899
900   // NB: DR 705.
901   template<typename... _Elements>
902     inline tuple<typename __decay_and_strip<_Elements>::__type...>
903     make_tuple(_Elements&&... __args)
904     {
905       typedef tuple<typename __decay_and_strip<_Elements>::__type...>
906         __result_type;
907       return __result_type(std::forward<_Elements>(__args)...);
908     }
909
910   template<typename... _Elements>
911     inline tuple<_Elements&&...>
912     forward_as_tuple(_Elements&&... __args) noexcept
913     { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
914
915   template<std::size_t...> struct __index_holder { };    
916
917   template<std::size_t __i, typename _IdxHolder, typename... _Elements>
918     struct __index_holder_impl;
919
920   template<std::size_t __i, std::size_t... _Indexes, typename _IdxHolder,
921            typename... _Elements>
922     struct __index_holder_impl<__i, __index_holder<_Indexes...>,
923                                _IdxHolder, _Elements...> 
924     {
925       typedef typename __index_holder_impl<__i + 1,
926                                            __index_holder<_Indexes..., __i>,
927                                            _Elements...>::type type;
928     };
929  
930   template<std::size_t __i, std::size_t... _Indexes>
931     struct __index_holder_impl<__i, __index_holder<_Indexes...> >
932     { typedef __index_holder<_Indexes...> type; };
933
934   template<typename... _Elements>
935     struct __make_index_holder 
936     : __index_holder_impl<0, __index_holder<>, _Elements...> { };
937     
938   template<typename... _TElements, std::size_t... _TIdx,
939            typename... _UElements, std::size_t... _UIdx> 
940     inline tuple<_TElements..., _UElements...> 
941     __tuple_cat_helper(const tuple<_TElements...>& __t,
942                        const __index_holder<_TIdx...>&,
943                        const tuple<_UElements...>& __u,
944                        const __index_holder<_UIdx...>&)
945     { return tuple<_TElements..., _UElements...>(get<_TIdx>(__t)...,
946                                                  get<_UIdx>(__u)...); }
947
948   template<typename... _TElements, std::size_t... _TIdx,
949            typename... _UElements, std::size_t... _UIdx> 
950     inline tuple<_TElements..., _UElements...> 
951     __tuple_cat_helper(tuple<_TElements...>&& __t,
952                        const __index_holder<_TIdx...>&, 
953                        const tuple<_UElements...>& __u,
954                        const __index_holder<_UIdx...>&)
955     { return tuple<_TElements..., _UElements...>
956         (std::forward<_TElements>(get<_TIdx>(__t))..., get<_UIdx>(__u)...); }
957
958   template<typename... _TElements, std::size_t... _TIdx,
959            typename... _UElements, std::size_t... _UIdx>
960     inline tuple<_TElements..., _UElements...> 
961     __tuple_cat_helper(const tuple<_TElements...>& __t,
962                        const __index_holder<_TIdx...>&, 
963                        tuple<_UElements...>&& __u,
964                        const __index_holder<_UIdx...>&)
965     { return tuple<_TElements..., _UElements...>
966         (get<_TIdx>(__t)..., std::forward<_UElements>(get<_UIdx>(__u))...); }
967
968   template<typename... _TElements, std::size_t... _TIdx,
969            typename... _UElements, std::size_t... _UIdx> 
970     inline tuple<_TElements..., _UElements...> 
971     __tuple_cat_helper(tuple<_TElements...>&& __t,
972                        const __index_holder<_TIdx...>&, 
973                        tuple<_UElements...>&& __u,
974                        const __index_holder<_UIdx...>&)
975     { return tuple<_TElements..., _UElements...>
976         (std::forward<_TElements>(get<_TIdx>(__t))...,
977          std::forward<_UElements>(get<_UIdx>(__u))...); }
978
979   template<typename... _TElements, typename... _UElements>
980     inline tuple<_TElements..., _UElements...> 
981     tuple_cat(const tuple<_TElements...>& __t, const tuple<_UElements...>& __u)
982     {
983       return __tuple_cat_helper(__t, typename
984                                 __make_index_holder<_TElements...>::type(),
985                                 __u, typename
986                                 __make_index_holder<_UElements...>::type());
987     }
988
989   template<typename... _TElements, typename... _UElements>
990     inline tuple<_TElements..., _UElements...> 
991     tuple_cat(tuple<_TElements...>&& __t, const tuple<_UElements...>& __u)
992     {
993       return __tuple_cat_helper(std::move(__t), typename
994                                  __make_index_holder<_TElements...>::type(),
995                                  __u, typename
996                                  __make_index_holder<_UElements...>::type());
997     }
998
999   template<typename... _TElements, typename... _UElements>
1000     inline tuple<_TElements..., _UElements...> 
1001     tuple_cat(const tuple<_TElements...>& __t, tuple<_UElements...>&& __u)
1002     {
1003       return __tuple_cat_helper(__t, typename
1004                                 __make_index_holder<_TElements...>::type(),
1005                                 std::move(__u), typename
1006                                 __make_index_holder<_UElements...>::type());
1007     }
1008
1009   template<typename... _TElements, typename... _UElements>
1010     inline tuple<_TElements..., _UElements...>
1011     tuple_cat(tuple<_TElements...>&& __t, tuple<_UElements...>&& __u)
1012     {
1013       return __tuple_cat_helper(std::move(__t), typename
1014                                 __make_index_holder<_TElements...>::type(),
1015                                 std::move(__u), typename
1016                                 __make_index_holder<_UElements...>::type());
1017     }
1018
1019   template<typename... _Elements>
1020     inline tuple<_Elements&...>
1021     tie(_Elements&... __args) noexcept
1022     { return tuple<_Elements&...>(__args...); }
1023
1024   template<typename... _Elements>
1025     inline void 
1026     swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
1027     noexcept(noexcept(__x.swap(__y)))
1028     { __x.swap(__y); }
1029
1030   // A class (and instance) which can be used in 'tie' when an element
1031   // of a tuple is not required
1032   struct _Swallow_assign
1033   {
1034     template<class _Tp>
1035       const _Swallow_assign&
1036       operator=(const _Tp&) const
1037       { return *this; }
1038   };
1039
1040   const _Swallow_assign ignore{};
1041
1042   /// Partial specialization for tuples
1043   template<typename... _Types, typename _Alloc>
1044     struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { };
1045
1046   /**
1047    * Stores a tuple of indices. Used by bind() to extract the elements
1048    * in a tuple. 
1049    */
1050   template<int... _Indexes>
1051     struct _Index_tuple
1052     {
1053       typedef _Index_tuple<_Indexes..., sizeof...(_Indexes)> __next;
1054     };
1055
1056   /// Builds an _Index_tuple<0, 1, 2, ..., _Num-1>.
1057   template<std::size_t _Num>
1058     struct _Build_index_tuple
1059     {
1060       typedef typename _Build_index_tuple<_Num-1>::__type::__next __type;
1061     };
1062
1063   template<>
1064     struct _Build_index_tuple<0>
1065     {
1066       typedef _Index_tuple<> __type;
1067     };
1068
1069   // See stl_pair.h...
1070   template<class _T1, class _T2>
1071     template<typename _Tp, typename... _Args>
1072       inline _Tp
1073       pair<_T1, _T2>::
1074       __cons(tuple<_Args...>&& __tuple)
1075       {
1076         typedef typename _Build_index_tuple<sizeof...(_Args)>::__type
1077           _Indexes;
1078         return __do_cons<_Tp>(std::move(__tuple), _Indexes());
1079       }
1080
1081   template<class _T1, class _T2>
1082     template<typename _Tp, typename... _Args, int... _Indexes>
1083       inline _Tp
1084       pair<_T1, _T2>::
1085       __do_cons(tuple<_Args...>&& __tuple,
1086                 const _Index_tuple<_Indexes...>&)
1087       { return _Tp(std::forward<_Args>(get<_Indexes>(__tuple))...); }
1088
1089 _GLIBCXX_END_NAMESPACE_VERSION
1090 } // namespace
1091
1092 #endif // __GXX_EXPERIMENTAL_CXX0X__
1093
1094 #endif // _GLIBCXX_TUPLE