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