File Coverage

/usr/include/c++/5/tuple
Criterion Covered Total %
statement 22 22 100.0
branch n/a
condition n/a
subroutine n/a
pod n/a
total 22 22 100.0


line stmt bran cond sub pod time code
1             // -*- 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             // .
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
36             #else
37              
38             #include
39             #include
40             #include
41              
42             namespace std _GLIBCXX_VISIBILITY(default)
43             {
44             _GLIBCXX_BEGIN_NAMESPACE_VERSION
45              
46             /**
47             * @addtogroup utilities
48             * @{
49             */
50              
51             template
52             struct _Head_base;
53              
54             template
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
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
75             _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
76             : _Head(allocator_arg, *__a._M_a) { }
77              
78             template
79             _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
80             : _Head(*__a._M_a) { }
81              
82             template
83             _Head_base(__uses_alloc0, _UHead&& __uhead)
84             : _Head(std::forward<_UHead>(__uhead)) { }
85              
86             template
87             _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
88             : _Head(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { }
89              
90             template
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
102             struct _Head_base<_Idx, _Head, false>
103             {
104             constexpr _Head_base()
105             : _M_head_impl() { }
106              
107 156           constexpr _Head_base(const _Head& __h)
108 156           : _M_head_impl(__h) { }
109              
110             constexpr _Head_base(const _Head_base&) = default;
111             constexpr _Head_base(_Head_base&&) = default;
112              
113             template
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
121             _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
122             : _M_head_impl(allocator_arg, *__a._M_a) { }
123              
124             template
125             _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
126             : _M_head_impl(*__a._M_a) { }
127              
128             template
129             _Head_base(__uses_alloc0, _UHead&& __uhead)
130             : _M_head_impl(std::forward<_UHead>(__uhead)) { }
131              
132             template
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
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 312           _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
159             struct _Tuple_impl;
160              
161             template
162             struct __is_empty_non_tuple : is_empty<_Tp> { };
163              
164             // Using EBO for elements that are tuples causes ambiguous base errors.
165             template
166             struct __is_empty_non_tuple> : false_type { };
167              
168             // Use the Empty Base-class Optimization for empty, non-final types.
169             template
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
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 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
209             enable_if::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_,
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
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
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
237             _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
238             : _Inherited(__tag, __a),
239             _Base(__tag, __use_alloc<_Head>(__a)) { }
240              
241             template
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
248             typename = typename enable_if
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
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
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
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
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_,
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
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
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
339             struct _Tuple_impl<_Idx, _Head>
340             : private _Head_base<_Idx, _Head, __empty_not_final<_Head>::value>
341             {
342             template friend class _Tuple_impl;
343              
344             typedef _Head_base<_Idx, _Head, __empty_not_final<_Head>::value> _Base;
345              
346             static constexpr _Head&
347 312           _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 78           constexpr _Tuple_impl(const _Head& __head)
357 78           : _Base(__head) { }
358              
359             template
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 78           _Tuple_impl(_Tuple_impl&& __in)
368             noexcept(is_nothrow_move_constructible<_Head>::value)
369 78           : _Base(std::forward<_Head>(_M_head(__in))) { }
370              
371             template
372             constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in)
373             : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in)) { }
374              
375             template
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
381             _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
382             : _Base(__tag, __use_alloc<_Head>(__a)) { }
383              
384             template
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
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
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
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
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
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
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
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
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 78           constexpr tuple(const _Elements&... __elements)
473 78           : _Inherited(__elements...) { }
474              
475             template
476             enable_if<__and_
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 156           constexpr tuple(tuple&&) = default;
485              
486             template
487             enable_if<__and_
488             _Elements>...>::value>::type>
489             constexpr tuple(const tuple<_UElements...>& __in)
490             : _Inherited(static_cast&>(__in))
491             { }
492              
493             template
494             enable_if<__and_
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
502             tuple(allocator_arg_t __tag, const _Alloc& __a)
503             : _Inherited(__tag, __a) { }
504              
505             template
506             tuple(allocator_arg_t __tag, const _Alloc& __a,
507             const _Elements&... __elements)
508             : _Inherited(__tag, __a, __elements...) { }
509              
510             template
511             enable_if
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
519             tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
520             : _Inherited(__tag, __a, static_cast(__in)) { }
521              
522             template
523             tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
524             : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
525              
526             template
527             enable_if
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&>(__in))
533             { }
534              
535             template
536             enable_if
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
560             enable_if
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
570             enable_if
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
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
609             enable_if<__and_,
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
620             enable_if<__and_,
621             is_convertible>::value>::type>
622             constexpr tuple(const tuple<_U1, _U2>& __in)
623             : _Inherited(static_cast&>(__in)) { }
624              
625             template
626             enable_if<__and_,
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
632             enable_if<__and_,
633             is_convertible>::value>::type>
634             constexpr tuple(const pair<_U1, _U2>& __in)
635             : _Inherited(__in.first, __in.second) { }
636              
637             template
638             enable_if<__and_,
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
647             tuple(allocator_arg_t __tag, const _Alloc& __a)
648             : _Inherited(__tag, __a) { }
649              
650             template
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
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
661             tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
662             : _Inherited(__tag, __a, static_cast(__in)) { }
663              
664             template
665             tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
666             : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
667              
668             template
669             tuple(allocator_arg_t __tag, const _Alloc& __a,
670             const tuple<_U1, _U2>& __in)
671             : _Inherited(__tag, __a,
672             static_cast&>(__in))
673             { }
674              
675             template
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
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
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
706             tuple&
707             operator=(const tuple<_U1, _U2>& __in)
708             {
709             static_cast<_Inherited&>(*this) = __in;
710             return *this;
711             }
712              
713             template
714             tuple&
715             operator=(tuple<_U1, _U2>&& __in)
716             {
717             static_cast<_Inherited&>(*this) = std::move(__in);
718             return *this;
719             }
720              
721             template
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
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
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
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
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
769             using __tuple_element_t = typename tuple_element<__i, _Tp>::type;
770              
771             template
772             struct tuple_element<__i, const _Tp>
773             {
774             typedef typename add_const<__tuple_element_t<__i, _Tp>>::type type;
775             };
776              
777             template
778             struct tuple_element<__i, volatile _Tp>
779             {
780             typedef typename add_volatile<__tuple_element_t<__i, _Tp>>::type type;
781             };
782              
783             template
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
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
798             struct tuple_size;
799              
800             // _GLIBCXX_RESOLVE_LIB_DEFECTS
801             // 2313. tuple_size should always derive from integral_constant
802             template
803             struct tuple_size
804             : integral_constant::value> { };
805              
806             template
807             struct tuple_size
808             : integral_constant::value> { };
809              
810             template
811             struct tuple_size
812             : integral_constant::value> { };
813              
814             /// class tuple_size
815             template
816             struct tuple_size>
817             : public integral_constant { };
818              
819             template
820             constexpr _Head&
821 78           __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
822 78           { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
823              
824             template
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
831             constexpr __tuple_element_t<__i, tuple<_Elements...>>&
832 78           get(tuple<_Elements...>& __t) noexcept
833 78           { return std::__get_helper<__i>(__t); }
834              
835             /// Return a const reference to the ith element of a const tuple.
836             template
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
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
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
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
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
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
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
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
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
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,
921             tuple<_UElements...>,
922             0, sizeof...(_TElements)>;
923             return __compare::__eq(__t, __u);
924             }
925              
926             template
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,
934             tuple<_UElements...>,
935             0, sizeof...(_TElements)>;
936             return __compare::__less(__t, __u);
937             }
938              
939             template
940             constexpr bool
941             operator!=(const tuple<_TElements...>& __t,
942             const tuple<_UElements...>& __u)
943             { return !(__t == __u); }
944              
945             template
946             constexpr bool
947             operator>(const tuple<_TElements...>& __t,
948             const tuple<_UElements...>& __u)
949             { return __u < __t; }
950              
951             template
952             constexpr bool
953             operator<=(const tuple<_TElements...>& __t,
954             const tuple<_UElements...>& __u)
955             { return !(__u < __t); }
956              
957             template
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
965             constexpr tuple::__type...>
966             make_tuple(_Elements&&... __args)
967             {
968             typedef tuple::__type...>
969             __result_type;
970             return __result_type(std::forward<_Elements>(__args)...);
971             }
972              
973             template
974             tuple<_Elements&&...>
975             forward_as_tuple(_Elements&&... __args) noexcept
976             { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
977              
978             template
979             struct __is_tuple_like_impl : false_type
980             { };
981              
982             template
983             struct __is_tuple_like_impl> : true_type
984             { };
985              
986             template
987             struct __is_tuple_like_impl> : true_type
988             { };
989              
990             template
991             struct __is_tuple_like_impl> : true_type
992             { };
993              
994             // Internal type trait that allows us to sfinae-protect tuple_cat.
995             template
996             struct __is_tuple_like
997             : public __is_tuple_like_impl
998             ::type>::type>::type
999             { };
1000              
1001             template
1002             struct __make_tuple_impl;
1003              
1004             template
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
1012             struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm>
1013             {
1014             typedef tuple<_Tp...> __type;
1015             };
1016              
1017             template
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
1024             struct __make_tuple
1025             : public __do_make_tuple
1026             ::type>::type>
1027             { };
1028              
1029             // Combines several std::tuple's into a single one.
1030             template
1031             struct __combine_tuples;
1032              
1033             template<>
1034             struct __combine_tuples<>
1035             {
1036             typedef tuple<> __type;
1037             };
1038              
1039             template
1040             struct __combine_tuples>
1041             {
1042             typedef tuple<_Ts...> __type;
1043             };
1044              
1045             template
1046             struct __combine_tuples, tuple<_T2s...>, _Rem...>
1047             {
1048             typedef typename __combine_tuples,
1049             _Rem...>::__type __type;
1050             };
1051              
1052             // Computes the result type of tuple_cat given a set of tuple-like types.
1053             template
1054             struct __tuple_cat_result
1055             {
1056             typedef typename __combine_tuples
1057             ::__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
1063             struct __make_1st_indices;
1064              
1065             template<>
1066             struct __make_1st_indices<>
1067             {
1068             typedef std::_Index_tuple<> __type;
1069             };
1070              
1071             template
1072             struct __make_1st_indices<_Tp, _Tpls...>
1073             {
1074             typedef typename std::_Build_index_tuple
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
1082             struct __tuple_concater;
1083              
1084             template
1085             struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...>
1086             {
1087             template
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
1100             struct __tuple_concater<_Ret, std::_Index_tuple<>>
1101             {
1102             template
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
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
1125             inline tuple<_Elements&...>
1126             tie(_Elements&... __args) noexcept
1127             { return tuple<_Elements&...>(__args...); }
1128              
1129             /// swap
1130             template
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
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
1150             struct uses_allocator, _Alloc> : true_type { };
1151              
1152             // See stl_pair.h...
1153             template
1154             template
1155             inline
1156 78           pair<_T1, _T2>::
1157             pair(piecewise_construct_t,
1158             tuple<_Args1...> __first, tuple<_Args2...> __second)
1159             : pair(__first, __second,
1160             typename _Build_index_tuple::__type(),
1161 78           typename _Build_index_tuple::__type())
1162 78           { }
1163              
1164             template
1165             template
1166             typename... _Args2, std::size_t... _Indexes2>
1167             inline
1168 78           pair<_T1, _T2>::
1169             pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2,
1170             _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)
1171 78           : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...),
1172 78           second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
1173 78           { }
1174              
1175             /// @}
1176              
1177             _GLIBCXX_END_NAMESPACE_VERSION
1178             } // namespace std
1179              
1180             #endif // C++11
1181              
1182             #endif // _GLIBCXX_TUPLE