OSDN Git Service

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