[gcc/testsuite]
[official-gcc.git] / libstdc++-v3 / include / std / tuple
blob1f5365ad02681ca7babc6b68dcea2cbfa63bcb47
1 // <tuple> -*- C++ -*-
3 // Copyright (C) 2007-2017 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.
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.
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.
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/>.
25 /** @file include/tuple
26  *  This is a Standard C++ Library header.
27  */
29 #ifndef _GLIBCXX_TUPLE
30 #define _GLIBCXX_TUPLE 1
32 #pragma GCC system_header
34 #if __cplusplus < 201103L
35 # include <bits/c++0x_warning.h>
36 #else
38 #include <utility>
39 #include <array>
40 #include <bits/uses_allocator.h>
41 #include <bits/invoke.h>
43 namespace std _GLIBCXX_VISIBILITY(default)
45 _GLIBCXX_BEGIN_NAMESPACE_VERSION
47   /**
48    *  @addtogroup utilities
49    *  @{
50    */
52   template<typename... _Elements>
53     class tuple;
55   template<typename _Tp>
56     struct __is_empty_non_tuple : is_empty<_Tp> { };
58   // Using EBO for elements that are tuples causes ambiguous base errors.
59   template<typename _El0, typename... _El>
60     struct __is_empty_non_tuple<tuple<_El0, _El...>> : false_type { };
62   // Use the Empty Base-class Optimization for empty, non-final types.
63   template<typename _Tp>
64     using __empty_not_final
65     = typename conditional<__is_final(_Tp), false_type,
66                            __is_empty_non_tuple<_Tp>>::type;
68   template<std::size_t _Idx, typename _Head,
69            bool = __empty_not_final<_Head>::value>
70     struct _Head_base;
72   template<std::size_t _Idx, typename _Head>
73     struct _Head_base<_Idx, _Head, true>
74     : public _Head
75     {
76       constexpr _Head_base()
77       : _Head() { }
79       constexpr _Head_base(const _Head& __h)
80       : _Head(__h) { }
82       constexpr _Head_base(const _Head_base&) = default;
83       constexpr _Head_base(_Head_base&&) = default;
85       template<typename _UHead>
86         constexpr _Head_base(_UHead&& __h)
87         : _Head(std::forward<_UHead>(__h)) { }
89       _Head_base(allocator_arg_t, __uses_alloc0)
90       : _Head() { }
92       template<typename _Alloc>
93         _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
94         : _Head(allocator_arg, *__a._M_a) { }
96       template<typename _Alloc>
97         _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
98         : _Head(*__a._M_a) { }
100       template<typename _UHead>
101         _Head_base(__uses_alloc0, _UHead&& __uhead)
102         : _Head(std::forward<_UHead>(__uhead)) { }
104       template<typename _Alloc, typename _UHead>
105         _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
106         : _Head(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { }
108       template<typename _Alloc, typename _UHead>
109         _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
110         : _Head(std::forward<_UHead>(__uhead), *__a._M_a) { }
112       static constexpr _Head&
113       _M_head(_Head_base& __b) noexcept { return __b; }
115       static constexpr const _Head&
116       _M_head(const _Head_base& __b) noexcept { return __b; }
117     };
119   template<std::size_t _Idx, typename _Head>
120     struct _Head_base<_Idx, _Head, false>
121     {
122       constexpr _Head_base()
123       : _M_head_impl() { }
125       constexpr _Head_base(const _Head& __h)
126       : _M_head_impl(__h) { }
128       constexpr _Head_base(const _Head_base&) = default;
129       constexpr _Head_base(_Head_base&&) = default;
131       template<typename _UHead>
132         constexpr _Head_base(_UHead&& __h)
133         : _M_head_impl(std::forward<_UHead>(__h)) { }
135       _Head_base(allocator_arg_t, __uses_alloc0)
136       : _M_head_impl() { }
138       template<typename _Alloc>
139         _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
140         : _M_head_impl(allocator_arg, *__a._M_a) { }
142       template<typename _Alloc>
143         _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
144         : _M_head_impl(*__a._M_a) { }
146       template<typename _UHead>
147         _Head_base(__uses_alloc0, _UHead&& __uhead)
148         : _M_head_impl(std::forward<_UHead>(__uhead)) { }
150       template<typename _Alloc, typename _UHead>
151         _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
152         : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead))
153         { }
155       template<typename _Alloc, typename _UHead>
156         _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
157         : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { }
159       static constexpr _Head&
160       _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; }
162       static constexpr const _Head&
163       _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; }
165       _Head _M_head_impl;
166     };
168   /**
169    * Contains the actual implementation of the @c tuple template, stored
170    * as a recursive inheritance hierarchy from the first element (most
171    * derived class) to the last (least derived class). The @c Idx
172    * parameter gives the 0-based index of the element stored at this
173    * point in the hierarchy; we use it to implement a constant-time
174    * get() operation.
175    */
176   template<std::size_t _Idx, typename... _Elements>
177     struct _Tuple_impl;
179   /**
180    * Recursive tuple implementation. Here we store the @c Head element
181    * and derive from a @c Tuple_impl containing the remaining elements
182    * (which contains the @c Tail).
183    */
184   template<std::size_t _Idx, typename _Head, typename... _Tail>
185     struct _Tuple_impl<_Idx, _Head, _Tail...>
186     : public _Tuple_impl<_Idx + 1, _Tail...>,
187       private _Head_base<_Idx, _Head>
188     {
189       template<std::size_t, typename...> friend class _Tuple_impl;
191       typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
192       typedef _Head_base<_Idx, _Head> _Base;
194       static constexpr _Head&
195       _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
197       static constexpr const _Head&
198       _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
200       static constexpr _Inherited&
201       _M_tail(_Tuple_impl& __t) noexcept { return __t; }
203       static constexpr const _Inherited&
204       _M_tail(const _Tuple_impl& __t) noexcept { return __t; }
206       constexpr _Tuple_impl()
207       : _Inherited(), _Base() { }
209       explicit
210       constexpr _Tuple_impl(const _Head& __head, const _Tail&... __tail)
211       : _Inherited(__tail...), _Base(__head) { }
213       template<typename _UHead, typename... _UTail, typename = typename
214                enable_if<sizeof...(_Tail) == sizeof...(_UTail)>::type>
215         explicit
216         constexpr _Tuple_impl(_UHead&& __head, _UTail&&... __tail)
217         : _Inherited(std::forward<_UTail>(__tail)...),
218           _Base(std::forward<_UHead>(__head)) { }
220       constexpr _Tuple_impl(const _Tuple_impl&) = default;
222       constexpr
223       _Tuple_impl(_Tuple_impl&& __in)
224       noexcept(__and_<is_nothrow_move_constructible<_Head>,
225                       is_nothrow_move_constructible<_Inherited>>::value)
226       : _Inherited(std::move(_M_tail(__in))),
227         _Base(std::forward<_Head>(_M_head(__in))) { }
229       template<typename... _UElements>
230         constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in)
231         : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
232           _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { }
234       template<typename _UHead, typename... _UTails>
235         constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
236         : _Inherited(std::move
237                      (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
238           _Base(std::forward<_UHead>
239                 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { }
241       template<typename _Alloc>
242         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
243         : _Inherited(__tag, __a),
244           _Base(__tag, __use_alloc<_Head>(__a)) { }
246       template<typename _Alloc>
247         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
248                     const _Head& __head, const _Tail&... __tail)
249         : _Inherited(__tag, __a, __tail...),
250           _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { }
252       template<typename _Alloc, typename _UHead, typename... _UTail,
253                typename = typename enable_if<sizeof...(_Tail)
254                                              == sizeof...(_UTail)>::type>
255         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
256                     _UHead&& __head, _UTail&&... __tail)
257         : _Inherited(__tag, __a, std::forward<_UTail>(__tail)...),
258           _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
259                 std::forward<_UHead>(__head)) { }
261       template<typename _Alloc>
262         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
263                     const _Tuple_impl& __in)
264         : _Inherited(__tag, __a, _M_tail(__in)),
265           _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { }
267       template<typename _Alloc>
268         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
269                     _Tuple_impl&& __in)
270         : _Inherited(__tag, __a, std::move(_M_tail(__in))),
271           _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
272                 std::forward<_Head>(_M_head(__in))) { }
274       template<typename _Alloc, typename... _UElements>
275         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
276                     const _Tuple_impl<_Idx, _UElements...>& __in)
277         : _Inherited(__tag, __a,
278                      _Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
279           _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
280                 _Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { }
282       template<typename _Alloc, typename _UHead, typename... _UTails>
283         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
284                     _Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
285         : _Inherited(__tag, __a, std::move
286                      (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
287           _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
288                 std::forward<_UHead>
289                 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { }
291       _Tuple_impl&
292       operator=(const _Tuple_impl& __in)
293       {
294         _M_head(*this) = _M_head(__in);
295         _M_tail(*this) = _M_tail(__in);
296         return *this;
297       }
299       _Tuple_impl&
300       operator=(_Tuple_impl&& __in)
301       noexcept(__and_<is_nothrow_move_assignable<_Head>,
302                       is_nothrow_move_assignable<_Inherited>>::value)
303       {
304         _M_head(*this) = std::forward<_Head>(_M_head(__in));
305         _M_tail(*this) = std::move(_M_tail(__in));
306         return *this;
307       }
309       template<typename... _UElements>
310         _Tuple_impl&
311         operator=(const _Tuple_impl<_Idx, _UElements...>& __in)
312         {
313           _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in);
314           _M_tail(*this) = _Tuple_impl<_Idx, _UElements...>::_M_tail(__in);
315           return *this;
316         }
318       template<typename _UHead, typename... _UTails>
319         _Tuple_impl&
320         operator=(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
321         {
322           _M_head(*this) = std::forward<_UHead>
323             (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in));
324           _M_tail(*this) = std::move
325             (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in));
326           return *this;
327         }
329     protected:
330       void
331       _M_swap(_Tuple_impl& __in)
332       noexcept(__is_nothrow_swappable<_Head>::value
333                && noexcept(_M_tail(__in)._M_swap(_M_tail(__in))))
334       {
335         using std::swap;
336         swap(_M_head(*this), _M_head(__in));
337         _Inherited::_M_swap(_M_tail(__in));
338       }
339     };
341   // Basis case of inheritance recursion.
342   template<std::size_t _Idx, typename _Head>
343     struct _Tuple_impl<_Idx, _Head>
344     : private _Head_base<_Idx, _Head>
345     {
346       template<std::size_t, typename...> friend class _Tuple_impl;
348       typedef _Head_base<_Idx, _Head> _Base;
350       static constexpr _Head&
351       _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
353       static constexpr const _Head&
354       _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
356       constexpr _Tuple_impl()
357       : _Base() { }
359       explicit
360       constexpr _Tuple_impl(const _Head& __head)
361       : _Base(__head) { }
363       template<typename _UHead>
364         explicit
365         constexpr _Tuple_impl(_UHead&& __head)
366         : _Base(std::forward<_UHead>(__head)) { }
368       constexpr _Tuple_impl(const _Tuple_impl&) = default;
370       constexpr
371       _Tuple_impl(_Tuple_impl&& __in)
372       noexcept(is_nothrow_move_constructible<_Head>::value)
373       : _Base(std::forward<_Head>(_M_head(__in))) { }
375       template<typename _UHead>
376         constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in)
377         : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in)) { }
379       template<typename _UHead>
380         constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in)
381         : _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
382         { }
384       template<typename _Alloc>
385         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
386         : _Base(__tag, __use_alloc<_Head>(__a)) { }
388       template<typename _Alloc>
389         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
390                     const _Head& __head)
391         : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { }
393       template<typename _Alloc, typename _UHead>
394         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
395                     _UHead&& __head)
396         : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
397                 std::forward<_UHead>(__head)) { }
399       template<typename _Alloc>
400         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
401                     const _Tuple_impl& __in)
402         : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { }
404       template<typename _Alloc>
405         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
406                     _Tuple_impl&& __in)
407         : _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
408                 std::forward<_Head>(_M_head(__in))) { }
410       template<typename _Alloc, typename _UHead>
411         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
412                     const _Tuple_impl<_Idx, _UHead>& __in)
413         : _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
414                 _Tuple_impl<_Idx, _UHead>::_M_head(__in)) { }
416       template<typename _Alloc, typename _UHead>
417         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
418                     _Tuple_impl<_Idx, _UHead>&& __in)
419         : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
420                 std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
421         { }
423       _Tuple_impl&
424       operator=(const _Tuple_impl& __in)
425       {
426         _M_head(*this) = _M_head(__in);
427         return *this;
428       }
430       _Tuple_impl&
431       operator=(_Tuple_impl&& __in)
432       noexcept(is_nothrow_move_assignable<_Head>::value)
433       {
434         _M_head(*this) = std::forward<_Head>(_M_head(__in));
435         return *this;
436       }
438       template<typename _UHead>
439         _Tuple_impl&
440         operator=(const _Tuple_impl<_Idx, _UHead>& __in)
441         {
442           _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in);
443           return *this;
444         }
446       template<typename _UHead>
447         _Tuple_impl&
448         operator=(_Tuple_impl<_Idx, _UHead>&& __in)
449         {
450           _M_head(*this)
451             = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in));
452           return *this;
453         }
455     protected:
456       void
457       _M_swap(_Tuple_impl& __in)
458       noexcept(__is_nothrow_swappable<_Head>::value)
459       {
460         using std::swap;
461         swap(_M_head(*this), _M_head(__in));
462       }
463     };
465   // Concept utility functions, reused in conditionally-explicit
466   // constructors.
467   template<bool, typename... _Elements>
468   struct _TC
469   {
470     template<typename... _UElements>
471     static constexpr bool _ConstructibleTuple()
472     {
473       return __and_<is_constructible<_Elements, const _UElements&>...>::value;
474     }
476     template<typename... _UElements>
477     static constexpr bool _ImplicitlyConvertibleTuple()
478     {
479       return __and_<is_convertible<const _UElements&, _Elements>...>::value;
480     }
482     template<typename... _UElements>
483     static constexpr bool _MoveConstructibleTuple()
484     {
485       return __and_<is_constructible<_Elements, _UElements&&>...>::value;
486     }
488     template<typename... _UElements>
489     static constexpr bool _ImplicitlyMoveConvertibleTuple()
490     {
491       return __and_<is_convertible<_UElements&&, _Elements>...>::value;
492     }
494     template<typename _SrcTuple>
495     static constexpr bool _NonNestedTuple()
496     {
497       return  __and_<__not_<is_same<tuple<_Elements...>,
498                                    typename remove_cv<
499                                      typename remove_reference<_SrcTuple>::type
500                                    >::type>>,
501                      __not_<is_convertible<_SrcTuple, _Elements...>>,
502                      __not_<is_constructible<_Elements..., _SrcTuple>>
503               >::value;
504     }
505     template<typename... _UElements>
506     static constexpr bool _NotSameTuple()
507     {
508       return  __not_<is_same<tuple<_Elements...>,
509                              typename remove_const<
510                                typename remove_reference<_UElements...>::type
511                                >::type>>::value;
512     }
513   };
515   template<typename... _Elements>
516   struct _TC<false, _Elements...>
517   {
518     template<typename... _UElements>
519     static constexpr bool _ConstructibleTuple()
520     {
521       return false;
522     }
524     template<typename... _UElements>
525     static constexpr bool _ImplicitlyConvertibleTuple()
526     {
527       return false;
528     }
530     template<typename... _UElements>
531     static constexpr bool _MoveConstructibleTuple()
532     {
533       return false;
534     }
536     template<typename... _UElements>
537     static constexpr bool _ImplicitlyMoveConvertibleTuple()
538     {
539       return false;
540     }
542     template<typename... _UElements>
543     static constexpr bool _NonNestedTuple()
544     {
545       return true;
546     }
547     template<typename... _UElements>
548     static constexpr bool _NotSameTuple()
549     {
550       return  true;
551     }
552   };
554   /// Primary class template, tuple
555   template<typename... _Elements>
556     class tuple : public _Tuple_impl<0, _Elements...>
557     {
558       typedef _Tuple_impl<0, _Elements...> _Inherited;
560       // Used for constraining the default constructor so
561       // that it becomes dependent on the constraints.
562       template<typename _Dummy>
563       struct _TC2
564       {
565         static constexpr bool _DefaultConstructibleTuple()
566         {
567           return __and_<is_default_constructible<_Elements>...>::value;
568         }
569         static constexpr bool _ImplicitlyDefaultConstructibleTuple()
570         {
571           return __and_<__is_implicitly_default_constructible<_Elements>...>
572             ::value;
573         }
574       };
576     public:
577       template<typename _Dummy = void,
578                typename enable_if<_TC2<_Dummy>::
579                                     _ImplicitlyDefaultConstructibleTuple(),
580                                   bool>::type = true>
581       constexpr tuple()
582       : _Inherited() { }
584       template<typename _Dummy = void,
585                typename enable_if<_TC2<_Dummy>::
586                                     _DefaultConstructibleTuple()
587                                   &&
588                                   !_TC2<_Dummy>::
589                                     _ImplicitlyDefaultConstructibleTuple(),
590                                   bool>::type = false>
591       explicit constexpr tuple()
592       : _Inherited() { }
594       // Shortcut for the cases where constructors taking _Elements...
595       // need to be constrained.
596       template<typename _Dummy> using _TCC =
597         _TC<is_same<_Dummy, void>::value,
598             _Elements...>;
600       template<typename _Dummy = void,
601                typename enable_if<
602                  _TCC<_Dummy>::template
603                    _ConstructibleTuple<_Elements...>()
604                  && _TCC<_Dummy>::template
605                    _ImplicitlyConvertibleTuple<_Elements...>()
606                  && (sizeof...(_Elements) >= 1),
607                bool>::type=true>
608         constexpr tuple(const _Elements&... __elements)
609       : _Inherited(__elements...) { }
611       template<typename _Dummy = void,
612                typename enable_if<
613                  _TCC<_Dummy>::template
614                    _ConstructibleTuple<_Elements...>()
615                  && !_TCC<_Dummy>::template
616                    _ImplicitlyConvertibleTuple<_Elements...>()
617                  && (sizeof...(_Elements) >= 1),
618                bool>::type=false>
619       explicit constexpr tuple(const _Elements&... __elements)
620       : _Inherited(__elements...) { }
622       // Shortcut for the cases where constructors taking _UElements...
623       // need to be constrained.
624       template<typename... _UElements> using _TMC =
625                   _TC<(sizeof...(_Elements) == sizeof...(_UElements))
626                       && (_TC<(sizeof...(_UElements)==1), _Elements...>::
627                           template _NotSameTuple<_UElements...>()),
628                       _Elements...>;
630       // Shortcut for the cases where constructors taking tuple<_UElements...>
631       // need to be constrained.
632       template<typename... _UElements> using _TMCT =
633                   _TC<(sizeof...(_Elements) == sizeof...(_UElements))
634                       && !is_same<tuple<_Elements...>,
635                                   tuple<_UElements...>>::value,
636                       _Elements...>;
638       template<typename... _UElements, typename
639                enable_if<
640                   _TMC<_UElements...>::template
641                     _MoveConstructibleTuple<_UElements...>()
642                   && _TMC<_UElements...>::template
643                     _ImplicitlyMoveConvertibleTuple<_UElements...>()
644                   && (sizeof...(_Elements) >= 1),
645         bool>::type=true>
646         constexpr tuple(_UElements&&... __elements)
647         : _Inherited(std::forward<_UElements>(__elements)...) { }
649       template<typename... _UElements, typename
650         enable_if<
651                   _TMC<_UElements...>::template
652                     _MoveConstructibleTuple<_UElements...>()
653                   && !_TMC<_UElements...>::template
654                     _ImplicitlyMoveConvertibleTuple<_UElements...>()
655                   && (sizeof...(_Elements) >= 1),
656         bool>::type=false>
657         explicit constexpr tuple(_UElements&&... __elements)
658         : _Inherited(std::forward<_UElements>(__elements)...) { }
660       constexpr tuple(const tuple&) = default;
662       constexpr tuple(tuple&&) = default;
664       // Shortcut for the cases where constructors taking tuples
665       // must avoid creating temporaries.
666       template<typename _Dummy> using _TNTC =
667         _TC<is_same<_Dummy, void>::value && sizeof...(_Elements) == 1,
668             _Elements...>;
670       template<typename... _UElements, typename _Dummy = void, typename
671         enable_if<_TMCT<_UElements...>::template
672                     _ConstructibleTuple<_UElements...>()
673                   && _TMCT<_UElements...>::template
674                     _ImplicitlyConvertibleTuple<_UElements...>()
675                   && _TNTC<_Dummy>::template
676                     _NonNestedTuple<const tuple<_UElements...>&>(),
677         bool>::type=true>
678         constexpr tuple(const tuple<_UElements...>& __in)
679         : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
680         { }
682       template<typename... _UElements, typename _Dummy = void, typename
683         enable_if<_TMCT<_UElements...>::template
684                     _ConstructibleTuple<_UElements...>()
685                   && !_TMCT<_UElements...>::template
686                     _ImplicitlyConvertibleTuple<_UElements...>()
687                   && _TNTC<_Dummy>::template
688                     _NonNestedTuple<const tuple<_UElements...>&>(),
689         bool>::type=false>
690         explicit constexpr tuple(const tuple<_UElements...>& __in)
691         : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
692         { }
694       template<typename... _UElements, typename _Dummy = void, typename
695         enable_if<_TMCT<_UElements...>::template
696                     _MoveConstructibleTuple<_UElements...>()
697                   && _TMCT<_UElements...>::template
698                     _ImplicitlyMoveConvertibleTuple<_UElements...>()
699                   && _TNTC<_Dummy>::template
700                     _NonNestedTuple<tuple<_UElements...>&&>(),
701         bool>::type=true>
702         constexpr tuple(tuple<_UElements...>&& __in)
703         : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
705       template<typename... _UElements, typename _Dummy = void, typename
706         enable_if<_TMCT<_UElements...>::template
707                     _MoveConstructibleTuple<_UElements...>()
708                   && !_TMCT<_UElements...>::template
709                     _ImplicitlyMoveConvertibleTuple<_UElements...>()
710                   && _TNTC<_Dummy>::template
711                     _NonNestedTuple<tuple<_UElements...>&&>(),
712         bool>::type=false>
713         explicit constexpr tuple(tuple<_UElements...>&& __in)
714         : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
716       // Allocator-extended constructors.
718       template<typename _Alloc>
719         tuple(allocator_arg_t __tag, const _Alloc& __a)
720         : _Inherited(__tag, __a) { }
722       template<typename _Alloc, typename _Dummy = void,
723                typename enable_if<
724                  _TCC<_Dummy>::template
725                    _ConstructibleTuple<_Elements...>()
726                  && _TCC<_Dummy>::template
727                    _ImplicitlyConvertibleTuple<_Elements...>(),
728                bool>::type=true>
729         tuple(allocator_arg_t __tag, const _Alloc& __a,
730               const _Elements&... __elements)
731         : _Inherited(__tag, __a, __elements...) { }
733       template<typename _Alloc, typename _Dummy = void,
734                typename enable_if<
735                  _TCC<_Dummy>::template
736                    _ConstructibleTuple<_Elements...>()
737                  && !_TCC<_Dummy>::template
738                    _ImplicitlyConvertibleTuple<_Elements...>(),
739                bool>::type=false>
740         explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
741                        const _Elements&... __elements)
742         : _Inherited(__tag, __a, __elements...) { }
744       template<typename _Alloc, typename... _UElements, typename
745         enable_if<_TMC<_UElements...>::template
746                     _MoveConstructibleTuple<_UElements...>()
747                   && _TMC<_UElements...>::template
748                     _ImplicitlyMoveConvertibleTuple<_UElements...>(),
749         bool>::type=true>
750         tuple(allocator_arg_t __tag, const _Alloc& __a,
751               _UElements&&... __elements)
752         : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
753         { }
755       template<typename _Alloc, typename... _UElements, typename
756         enable_if<_TMC<_UElements...>::template
757                     _MoveConstructibleTuple<_UElements...>()
758                   && !_TMC<_UElements...>::template
759                     _ImplicitlyMoveConvertibleTuple<_UElements...>(),
760         bool>::type=false>
761         explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
762               _UElements&&... __elements)
763         : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
764         { }
766       template<typename _Alloc>
767         tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
768         : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
770       template<typename _Alloc>
771         tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
772         : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
774       template<typename _Alloc, typename _Dummy = void,
775                typename... _UElements, typename
776         enable_if<_TMCT<_UElements...>::template
777                     _ConstructibleTuple<_UElements...>()
778                   && _TMCT<_UElements...>::template
779                     _ImplicitlyConvertibleTuple<_UElements...>()
780                   && _TNTC<_Dummy>::template
781                     _NonNestedTuple<tuple<_UElements...>&&>(),
782         bool>::type=true>
783         tuple(allocator_arg_t __tag, const _Alloc& __a,
784               const tuple<_UElements...>& __in)
785         : _Inherited(__tag, __a,
786                      static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
787         { }
789       template<typename _Alloc, typename _Dummy = void,
790                typename... _UElements, typename
791         enable_if<_TMCT<_UElements...>::template
792                     _ConstructibleTuple<_UElements...>()
793                   && !_TMCT<_UElements...>::template
794                     _ImplicitlyConvertibleTuple<_UElements...>()
795                   && _TNTC<_Dummy>::template
796                     _NonNestedTuple<tuple<_UElements...>&&>(),
797         bool>::type=false>
798         explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
799               const tuple<_UElements...>& __in)
800         : _Inherited(__tag, __a,
801                      static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
802         { }
804       template<typename _Alloc, typename _Dummy = void,
805                typename... _UElements, typename
806         enable_if<_TMCT<_UElements...>::template
807                     _MoveConstructibleTuple<_UElements...>()
808                   && _TMCT<_UElements...>::template
809                     _ImplicitlyMoveConvertibleTuple<_UElements...>()
810                   && _TNTC<_Dummy>::template
811                     _NonNestedTuple<tuple<_UElements...>&&>(),
812         bool>::type=true>
813         tuple(allocator_arg_t __tag, const _Alloc& __a,
814               tuple<_UElements...>&& __in)
815         : _Inherited(__tag, __a,
816                      static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
817         { }
819       template<typename _Alloc, typename _Dummy = void,
820                typename... _UElements, typename
821         enable_if<_TMCT<_UElements...>::template
822                     _MoveConstructibleTuple<_UElements...>()
823                   && !_TMCT<_UElements...>::template
824                     _ImplicitlyMoveConvertibleTuple<_UElements...>()
825                   && _TNTC<_Dummy>::template
826                     _NonNestedTuple<tuple<_UElements...>&&>(),
827         bool>::type=false>
828         explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
829               tuple<_UElements...>&& __in)
830         : _Inherited(__tag, __a,
831                      static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
832         { }
834       tuple&
835       operator=(const tuple& __in)
836       {
837         static_cast<_Inherited&>(*this) = __in;
838         return *this;
839       }
841       tuple&
842       operator=(tuple&& __in)
843       noexcept(is_nothrow_move_assignable<_Inherited>::value)
844       {
845         static_cast<_Inherited&>(*this) = std::move(__in);
846         return *this;
847       }
849       template<typename... _UElements>
850         typename
851                enable_if<sizeof...(_UElements)
852                          == sizeof...(_Elements), tuple&>::type
853         operator=(const tuple<_UElements...>& __in)
854         {
855           static_cast<_Inherited&>(*this) = __in;
856           return *this;
857         }
859       template<typename... _UElements>
860         typename
861                enable_if<sizeof...(_UElements)
862                          == sizeof...(_Elements), tuple&>::type
863         operator=(tuple<_UElements...>&& __in)
864         {
865           static_cast<_Inherited&>(*this) = std::move(__in);
866           return *this;
867         }
869       void
870       swap(tuple& __in)
871       noexcept(noexcept(__in._M_swap(__in)))
872       { _Inherited::_M_swap(__in); }
873     };
875 #if __cpp_deduction_guides >= 201606
876   template<typename... _UTypes>
877     tuple(_UTypes...) -> tuple<_UTypes...>;
878   template<typename _T1, typename _T2>
879     tuple(pair<_T1, _T2>) -> tuple<_T1, _T2>;
880   template<typename _Alloc, typename... _UTypes>
881     tuple(allocator_arg_t, _Alloc, _UTypes...) -> tuple<_UTypes...>;
882   template<typename _Alloc, typename _T1, typename _T2>
883     tuple(allocator_arg_t, _Alloc, pair<_T1, _T2>) -> tuple<_T1, _T2>;
884   template<typename _Alloc, typename... _UTypes>
885     tuple(allocator_arg_t, _Alloc, tuple<_UTypes...>) -> tuple<_UTypes...>;
886 #endif
888   // Explicit specialization, zero-element tuple.
889   template<>
890     class tuple<>
891     {
892     public:
893       void swap(tuple&) noexcept { /* no-op */ }
894       // We need the default since we're going to define no-op
895       // allocator constructors.
896       tuple() = default;
897       // No-op allocator constructors.
898       template<typename _Alloc>
899         tuple(allocator_arg_t, const _Alloc&) { }
900       template<typename _Alloc>
901         tuple(allocator_arg_t, const _Alloc&, const tuple&) { }
902     };
904   /// Partial specialization, 2-element tuple.
905   /// Includes construction and assignment from a pair.
906   template<typename _T1, typename _T2>
907     class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
908     {
909       typedef _Tuple_impl<0, _T1, _T2> _Inherited;
911     public:
912       template <typename _U1 = _T1,
913                 typename _U2 = _T2,
914                 typename enable_if<__and_<
915                                      __is_implicitly_default_constructible<_U1>,
916                                      __is_implicitly_default_constructible<_U2>>
917                                    ::value, bool>::type = true>
919       constexpr tuple()
920       : _Inherited() { }
922       template <typename _U1 = _T1,
923                 typename _U2 = _T2,
924                 typename enable_if<
925                   __and_<
926                     is_default_constructible<_U1>,
927                     is_default_constructible<_U2>,
928                     __not_<
929                       __and_<__is_implicitly_default_constructible<_U1>,
930                              __is_implicitly_default_constructible<_U2>>>>
931                   ::value, bool>::type = false>
933       explicit constexpr tuple()
934       : _Inherited() { }
936       // Shortcut for the cases where constructors taking _T1, _T2
937       // need to be constrained.
938       template<typename _Dummy> using _TCC =
939         _TC<is_same<_Dummy, void>::value, _T1, _T2>;
941       template<typename _Dummy = void, typename
942                enable_if<_TCC<_Dummy>::template
943                            _ConstructibleTuple<_T1, _T2>()
944                          && _TCC<_Dummy>::template
945                            _ImplicitlyConvertibleTuple<_T1, _T2>(),
946         bool>::type = true>
947         constexpr tuple(const _T1& __a1, const _T2& __a2)
948         : _Inherited(__a1, __a2) { }
950       template<typename _Dummy = void, typename
951                enable_if<_TCC<_Dummy>::template
952                            _ConstructibleTuple<_T1, _T2>()
953                          && !_TCC<_Dummy>::template
954                            _ImplicitlyConvertibleTuple<_T1, _T2>(),
955         bool>::type = false>
956         explicit constexpr tuple(const _T1& __a1, const _T2& __a2)
957         : _Inherited(__a1, __a2) { }
959       // Shortcut for the cases where constructors taking _U1, _U2
960       // need to be constrained.
961       using _TMC = _TC<true, _T1, _T2>;
963       template<typename _U1, typename _U2, typename
964         enable_if<_TMC::template
965                     _MoveConstructibleTuple<_U1, _U2>()
966                   && _TMC::template
967                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>()
968                   && !is_same<typename decay<_U1>::type,
969                               allocator_arg_t>::value,
970         bool>::type = true>
971         constexpr tuple(_U1&& __a1, _U2&& __a2)
972         : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
974       template<typename _U1, typename _U2, typename
975         enable_if<_TMC::template
976                     _MoveConstructibleTuple<_U1, _U2>()
977                   && !_TMC::template
978                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>()
979                   && !is_same<typename decay<_U1>::type,
980                               allocator_arg_t>::value,
981         bool>::type = false>
982         explicit constexpr tuple(_U1&& __a1, _U2&& __a2)
983         : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
985       constexpr tuple(const tuple&) = default;
987       constexpr tuple(tuple&&) = default;
989       template<typename _U1, typename _U2, typename
990         enable_if<_TMC::template
991                     _ConstructibleTuple<_U1, _U2>()
992                   && _TMC::template
993                     _ImplicitlyConvertibleTuple<_U1, _U2>(),
994         bool>::type = true>
995         constexpr tuple(const tuple<_U1, _U2>& __in)
996         : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
998       template<typename _U1, typename _U2, typename
999         enable_if<_TMC::template
1000                     _ConstructibleTuple<_U1, _U2>()
1001                   && !_TMC::template
1002                     _ImplicitlyConvertibleTuple<_U1, _U2>(),
1003         bool>::type = false>
1004         explicit constexpr tuple(const tuple<_U1, _U2>& __in)
1005         : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
1007       template<typename _U1, typename _U2, typename
1008         enable_if<_TMC::template
1009                     _MoveConstructibleTuple<_U1, _U2>()
1010                   && _TMC::template
1011                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1012         bool>::type = true>
1013         constexpr tuple(tuple<_U1, _U2>&& __in)
1014         : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
1016       template<typename _U1, typename _U2, typename
1017         enable_if<_TMC::template
1018                     _MoveConstructibleTuple<_U1, _U2>()
1019                   && !_TMC::template
1020                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1021         bool>::type = false>
1022         explicit constexpr tuple(tuple<_U1, _U2>&& __in)
1023         : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
1025       template<typename _U1, typename _U2, typename
1026         enable_if<_TMC::template
1027                     _ConstructibleTuple<_U1, _U2>()
1028                   && _TMC::template
1029                     _ImplicitlyConvertibleTuple<_U1, _U2>(),
1030         bool>::type = true>
1031         constexpr tuple(const pair<_U1, _U2>& __in)
1032         : _Inherited(__in.first, __in.second) { }
1034       template<typename _U1, typename _U2, typename
1035         enable_if<_TMC::template
1036                     _ConstructibleTuple<_U1, _U2>()
1037                   && !_TMC::template
1038                     _ImplicitlyConvertibleTuple<_U1, _U2>(),
1039         bool>::type = false>
1040         explicit constexpr tuple(const pair<_U1, _U2>& __in)
1041         : _Inherited(__in.first, __in.second) { }
1043       template<typename _U1, typename _U2, typename
1044         enable_if<_TMC::template
1045                     _MoveConstructibleTuple<_U1, _U2>()
1046                   && _TMC::template
1047                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1048         bool>::type = true>
1049         constexpr tuple(pair<_U1, _U2>&& __in)
1050         : _Inherited(std::forward<_U1>(__in.first),
1051                      std::forward<_U2>(__in.second)) { }
1053       template<typename _U1, typename _U2, typename
1054         enable_if<_TMC::template
1055                     _MoveConstructibleTuple<_U1, _U2>()
1056                   && !_TMC::template
1057                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1058         bool>::type = false>
1059         explicit constexpr tuple(pair<_U1, _U2>&& __in)
1060         : _Inherited(std::forward<_U1>(__in.first),
1061                      std::forward<_U2>(__in.second)) { }
1063       // Allocator-extended constructors.
1065       template<typename _Alloc>
1066         tuple(allocator_arg_t __tag, const _Alloc& __a)
1067         : _Inherited(__tag, __a) { }
1069       template<typename _Alloc, typename _Dummy = void,
1070                typename enable_if<
1071                  _TCC<_Dummy>::template
1072                    _ConstructibleTuple<_T1, _T2>()
1073                  && _TCC<_Dummy>::template
1074                    _ImplicitlyConvertibleTuple<_T1, _T2>(),
1075                bool>::type=true>
1077         tuple(allocator_arg_t __tag, const _Alloc& __a,
1078               const _T1& __a1, const _T2& __a2)
1079         : _Inherited(__tag, __a, __a1, __a2) { }
1081       template<typename _Alloc, typename _Dummy = void,
1082                typename enable_if<
1083                  _TCC<_Dummy>::template
1084                    _ConstructibleTuple<_T1, _T2>()
1085                  && !_TCC<_Dummy>::template
1086                    _ImplicitlyConvertibleTuple<_T1, _T2>(),
1087                bool>::type=false>
1089         explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1090               const _T1& __a1, const _T2& __a2)
1091         : _Inherited(__tag, __a, __a1, __a2) { }
1093       template<typename _Alloc, typename _U1, typename _U2, typename
1094         enable_if<_TMC::template
1095                     _MoveConstructibleTuple<_U1, _U2>()
1096                   && _TMC::template
1097                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1098         bool>::type = true>
1099         tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2)
1100         : _Inherited(__tag, __a, std::forward<_U1>(__a1),
1101                      std::forward<_U2>(__a2)) { }
1103       template<typename _Alloc, typename _U1, typename _U2, typename
1104         enable_if<_TMC::template
1105                     _MoveConstructibleTuple<_U1, _U2>()
1106                   && !_TMC::template
1107                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1108         bool>::type = false>
1109         explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1110                        _U1&& __a1, _U2&& __a2)
1111         : _Inherited(__tag, __a, std::forward<_U1>(__a1),
1112                      std::forward<_U2>(__a2)) { }
1114       template<typename _Alloc>
1115         tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
1116         : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
1118       template<typename _Alloc>
1119         tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
1120         : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
1122       template<typename _Alloc, typename _U1, typename _U2, typename
1123         enable_if<_TMC::template
1124                     _ConstructibleTuple<_U1, _U2>()
1125                   && _TMC::template
1126                     _ImplicitlyConvertibleTuple<_U1, _U2>(),
1127         bool>::type = true>
1128         tuple(allocator_arg_t __tag, const _Alloc& __a,
1129               const tuple<_U1, _U2>& __in)
1130         : _Inherited(__tag, __a,
1131                      static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
1132         { }
1134       template<typename _Alloc, typename _U1, typename _U2, typename
1135         enable_if<_TMC::template
1136                     _ConstructibleTuple<_U1, _U2>()
1137                   && !_TMC::template
1138                     _ImplicitlyConvertibleTuple<_U1, _U2>(),
1139         bool>::type = false>
1140         explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1141               const tuple<_U1, _U2>& __in)
1142         : _Inherited(__tag, __a,
1143                      static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
1144         { }
1146       template<typename _Alloc, typename _U1, typename _U2, typename
1147         enable_if<_TMC::template
1148                     _MoveConstructibleTuple<_U1, _U2>()
1149                   && _TMC::template
1150                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1151         bool>::type = true>
1152         tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
1153         : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
1154         { }
1156       template<typename _Alloc, typename _U1, typename _U2, typename
1157         enable_if<_TMC::template
1158                     _MoveConstructibleTuple<_U1, _U2>()
1159                   && !_TMC::template
1160                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1161         bool>::type = false>
1162         explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1163                        tuple<_U1, _U2>&& __in)
1164         : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
1165         { }
1167       template<typename _Alloc, typename _U1, typename _U2, typename
1168         enable_if<_TMC::template
1169                     _ConstructibleTuple<_U1, _U2>()
1170                   && _TMC::template
1171                     _ImplicitlyConvertibleTuple<_U1, _U2>(),
1172         bool>::type = true>
1173         tuple(allocator_arg_t __tag, const _Alloc& __a,
1174               const pair<_U1, _U2>& __in)
1175         : _Inherited(__tag, __a, __in.first, __in.second) { }
1177       template<typename _Alloc, typename _U1, typename _U2, typename
1178         enable_if<_TMC::template
1179                     _ConstructibleTuple<_U1, _U2>()
1180                   && !_TMC::template
1181                     _ImplicitlyConvertibleTuple<_U1, _U2>(),
1182         bool>::type = false>
1183         explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1184               const pair<_U1, _U2>& __in)
1185         : _Inherited(__tag, __a, __in.first, __in.second) { }
1187       template<typename _Alloc, typename _U1, typename _U2, typename
1188         enable_if<_TMC::template
1189                     _MoveConstructibleTuple<_U1, _U2>()
1190                   && _TMC::template
1191                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1192         bool>::type = true>
1193         tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
1194         : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
1195                      std::forward<_U2>(__in.second)) { }
1197       template<typename _Alloc, typename _U1, typename _U2, typename
1198         enable_if<_TMC::template
1199                     _MoveConstructibleTuple<_U1, _U2>()
1200                   && !_TMC::template
1201                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1202         bool>::type = false>
1203         explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1204                        pair<_U1, _U2>&& __in)
1205         : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
1206                      std::forward<_U2>(__in.second)) { }
1208       tuple&
1209       operator=(const tuple& __in)
1210       {
1211         static_cast<_Inherited&>(*this) = __in;
1212         return *this;
1213       }
1215       tuple&
1216       operator=(tuple&& __in)
1217       noexcept(is_nothrow_move_assignable<_Inherited>::value)
1218       {
1219         static_cast<_Inherited&>(*this) = std::move(__in);
1220         return *this;
1221       }
1223       template<typename _U1, typename _U2>
1224         tuple&
1225         operator=(const tuple<_U1, _U2>& __in)
1226         {
1227           static_cast<_Inherited&>(*this) = __in;
1228           return *this;
1229         }
1231       template<typename _U1, typename _U2>
1232         tuple&
1233         operator=(tuple<_U1, _U2>&& __in)
1234         {
1235           static_cast<_Inherited&>(*this) = std::move(__in);
1236           return *this;
1237         }
1239       template<typename _U1, typename _U2>
1240         tuple&
1241         operator=(const pair<_U1, _U2>& __in)
1242         {
1243           this->_M_head(*this) = __in.first;
1244           this->_M_tail(*this)._M_head(*this) = __in.second;
1245           return *this;
1246         }
1248       template<typename _U1, typename _U2>
1249         tuple&
1250         operator=(pair<_U1, _U2>&& __in)
1251         {
1252           this->_M_head(*this) = std::forward<_U1>(__in.first);
1253           this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second);
1254           return *this;
1255         }
1257       void
1258       swap(tuple& __in)
1259       noexcept(noexcept(__in._M_swap(__in)))
1260       { _Inherited::_M_swap(__in); }
1261     };
1264   /// class tuple_size
1265   template<typename... _Elements>
1266     struct tuple_size<tuple<_Elements...>>
1267     : public integral_constant<std::size_t, sizeof...(_Elements)> { };
1269 #if __cplusplus > 201402L
1270   template <typename _Tp>
1271     inline constexpr size_t tuple_size_v = tuple_size<_Tp>::value;
1272 #endif
1274   /**
1275    * Recursive case for tuple_element: strip off the first element in
1276    * the tuple and retrieve the (i-1)th element of the remaining tuple.
1277    */
1278   template<std::size_t __i, typename _Head, typename... _Tail>
1279     struct tuple_element<__i, tuple<_Head, _Tail...> >
1280     : tuple_element<__i - 1, tuple<_Tail...> > { };
1282   /**
1283    * Basis case for tuple_element: The first element is the one we're seeking.
1284    */
1285   template<typename _Head, typename... _Tail>
1286     struct tuple_element<0, tuple<_Head, _Tail...> >
1287     {
1288       typedef _Head type;
1289     };
1291   /**
1292    * Error case for tuple_element: invalid index.
1293    */
1294   template<size_t __i>
1295     struct tuple_element<__i, tuple<>>
1296     {
1297       static_assert(__i < tuple_size<tuple<>>::value,
1298           "tuple index is in range");
1299     };
1301   template<std::size_t __i, typename _Head, typename... _Tail>
1302     constexpr _Head&
1303     __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1304     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
1306   template<std::size_t __i, typename _Head, typename... _Tail>
1307     constexpr const _Head&
1308     __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1309     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
1311   /// Return a reference to the ith element of a tuple.
1312   template<std::size_t __i, typename... _Elements>
1313     constexpr __tuple_element_t<__i, tuple<_Elements...>>&
1314     get(tuple<_Elements...>& __t) noexcept
1315     { return std::__get_helper<__i>(__t); }
1317   /// Return a const reference to the ith element of a const tuple.
1318   template<std::size_t __i, typename... _Elements>
1319     constexpr const __tuple_element_t<__i, tuple<_Elements...>>&
1320     get(const tuple<_Elements...>& __t) noexcept
1321     { return std::__get_helper<__i>(__t); }
1323   /// Return an rvalue reference to the ith element of a tuple rvalue.
1324   template<std::size_t __i, typename... _Elements>
1325     constexpr __tuple_element_t<__i, tuple<_Elements...>>&&
1326     get(tuple<_Elements...>&& __t) noexcept
1327     {
1328       typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
1329       return std::forward<__element_type&&>(std::get<__i>(__t));
1330     }
1332 #if __cplusplus > 201103L
1334 #define __cpp_lib_tuples_by_type 201304
1336   template<typename _Head, size_t __i, typename... _Tail>
1337     constexpr _Head&
1338     __get_helper2(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1339     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
1341   template<typename _Head, size_t __i, typename... _Tail>
1342     constexpr const _Head&
1343     __get_helper2(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1344     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
1346   /// Return a reference to the unique element of type _Tp of a tuple.
1347   template <typename _Tp, typename... _Types>
1348     constexpr _Tp&
1349     get(tuple<_Types...>& __t) noexcept
1350     { return std::__get_helper2<_Tp>(__t); }
1352   /// Return a reference to the unique element of type _Tp of a tuple rvalue.
1353   template <typename _Tp, typename... _Types>
1354     constexpr _Tp&&
1355     get(tuple<_Types...>&& __t) noexcept
1356     { return std::forward<_Tp&&>(std::__get_helper2<_Tp>(__t)); }
1358   /// Return a const reference to the unique element of type _Tp of a tuple.
1359   template <typename _Tp, typename... _Types>
1360     constexpr const _Tp&
1361     get(const tuple<_Types...>& __t) noexcept
1362     { return std::__get_helper2<_Tp>(__t); }
1363 #endif
1365   // This class performs the comparison operations on tuples
1366   template<typename _Tp, typename _Up, size_t __i, size_t __size>
1367     struct __tuple_compare
1368     {
1369       static constexpr bool
1370       __eq(const _Tp& __t, const _Up& __u)
1371       {
1372         return bool(std::get<__i>(__t) == std::get<__i>(__u))
1373           && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u);
1374       }
1376       static constexpr bool
1377       __less(const _Tp& __t, const _Up& __u)
1378       {
1379         return bool(std::get<__i>(__t) < std::get<__i>(__u))
1380           || (!bool(std::get<__i>(__u) < std::get<__i>(__t))
1381               && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u));
1382       }
1383     };
1385   template<typename _Tp, typename _Up, size_t __size>
1386     struct __tuple_compare<_Tp, _Up, __size, __size>
1387     {
1388       static constexpr bool
1389       __eq(const _Tp&, const _Up&) { return true; }
1391       static constexpr bool
1392       __less(const _Tp&, const _Up&) { return false; }
1393     };
1395   template<typename... _TElements, typename... _UElements>
1396     constexpr bool
1397     operator==(const tuple<_TElements...>& __t,
1398                const tuple<_UElements...>& __u)
1399     {
1400       static_assert(sizeof...(_TElements) == sizeof...(_UElements),
1401           "tuple objects can only be compared if they have equal sizes.");
1402       using __compare = __tuple_compare<tuple<_TElements...>,
1403                                         tuple<_UElements...>,
1404                                         0, sizeof...(_TElements)>;
1405       return __compare::__eq(__t, __u);
1406     }
1408   template<typename... _TElements, typename... _UElements>
1409     constexpr bool
1410     operator<(const tuple<_TElements...>& __t,
1411               const tuple<_UElements...>& __u)
1412     {
1413       static_assert(sizeof...(_TElements) == sizeof...(_UElements),
1414           "tuple objects can only be compared if they have equal sizes.");
1415       using __compare = __tuple_compare<tuple<_TElements...>,
1416                                         tuple<_UElements...>,
1417                                         0, sizeof...(_TElements)>;
1418       return __compare::__less(__t, __u);
1419     }
1421   template<typename... _TElements, typename... _UElements>
1422     constexpr bool
1423     operator!=(const tuple<_TElements...>& __t,
1424                const tuple<_UElements...>& __u)
1425     { return !(__t == __u); }
1427   template<typename... _TElements, typename... _UElements>
1428     constexpr bool
1429     operator>(const tuple<_TElements...>& __t,
1430               const tuple<_UElements...>& __u)
1431     { return __u < __t; }
1433   template<typename... _TElements, typename... _UElements>
1434     constexpr bool
1435     operator<=(const tuple<_TElements...>& __t,
1436                const tuple<_UElements...>& __u)
1437     { return !(__u < __t); }
1439   template<typename... _TElements, typename... _UElements>
1440     constexpr bool
1441     operator>=(const tuple<_TElements...>& __t,
1442                const tuple<_UElements...>& __u)
1443     { return !(__t < __u); }
1445   // NB: DR 705.
1446   template<typename... _Elements>
1447     constexpr tuple<typename __decay_and_strip<_Elements>::__type...>
1448     make_tuple(_Elements&&... __args)
1449     {
1450       typedef tuple<typename __decay_and_strip<_Elements>::__type...>
1451         __result_type;
1452       return __result_type(std::forward<_Elements>(__args)...);
1453     }
1455   // _GLIBCXX_RESOLVE_LIB_DEFECTS
1456   // 2275. Why is forward_as_tuple not constexpr?
1457   template<typename... _Elements>
1458     constexpr tuple<_Elements&&...>
1459     forward_as_tuple(_Elements&&... __args) noexcept
1460     { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
1462   template<size_t, typename, typename, size_t>
1463     struct __make_tuple_impl;
1465   template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm>
1466     struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm>
1467     : __make_tuple_impl<_Idx + 1,
1468                         tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>,
1469                         _Tuple, _Nm>
1470     { };
1472   template<std::size_t _Nm, typename _Tuple, typename... _Tp>
1473     struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm>
1474     {
1475       typedef tuple<_Tp...> __type;
1476     };
1478   template<typename _Tuple>
1479     struct __do_make_tuple
1480     : __make_tuple_impl<0, tuple<>, _Tuple, std::tuple_size<_Tuple>::value>
1481     { };
1483   // Returns the std::tuple equivalent of a tuple-like type.
1484   template<typename _Tuple>
1485     struct __make_tuple
1486     : public __do_make_tuple<typename std::remove_cv
1487             <typename std::remove_reference<_Tuple>::type>::type>
1488     { };
1490   // Combines several std::tuple's into a single one.
1491   template<typename...>
1492     struct __combine_tuples;
1494   template<>
1495     struct __combine_tuples<>
1496     {
1497       typedef tuple<> __type;
1498     };
1500   template<typename... _Ts>
1501     struct __combine_tuples<tuple<_Ts...>>
1502     {
1503       typedef tuple<_Ts...> __type;
1504     };
1506   template<typename... _T1s, typename... _T2s, typename... _Rem>
1507     struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...>
1508     {
1509       typedef typename __combine_tuples<tuple<_T1s..., _T2s...>,
1510                                         _Rem...>::__type __type;
1511     };
1513   // Computes the result type of tuple_cat given a set of tuple-like types.
1514   template<typename... _Tpls>
1515     struct __tuple_cat_result
1516     {
1517       typedef typename __combine_tuples
1518         <typename __make_tuple<_Tpls>::__type...>::__type __type;
1519     };
1521   // Helper to determine the index set for the first tuple-like
1522   // type of a given set.
1523   template<typename...>
1524     struct __make_1st_indices;
1526   template<>
1527     struct __make_1st_indices<>
1528     {
1529       typedef std::_Index_tuple<> __type;
1530     };
1532   template<typename _Tp, typename... _Tpls>
1533     struct __make_1st_indices<_Tp, _Tpls...>
1534     {
1535       typedef typename std::_Build_index_tuple<std::tuple_size<
1536         typename std::remove_reference<_Tp>::type>::value>::__type __type;
1537     };
1539   // Performs the actual concatenation by step-wise expanding tuple-like
1540   // objects into the elements,  which are finally forwarded into the
1541   // result tuple.
1542   template<typename _Ret, typename _Indices, typename... _Tpls>
1543     struct __tuple_concater;
1545   template<typename _Ret, std::size_t... _Is, typename _Tp, typename... _Tpls>
1546     struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...>
1547     {
1548       template<typename... _Us>
1549         static constexpr _Ret
1550         _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us)
1551         {
1552           typedef typename __make_1st_indices<_Tpls...>::__type __idx;
1553           typedef __tuple_concater<_Ret, __idx, _Tpls...>      __next;
1554           return __next::_S_do(std::forward<_Tpls>(__tps)...,
1555                                std::forward<_Us>(__us)...,
1556                                std::get<_Is>(std::forward<_Tp>(__tp))...);
1557         }
1558     };
1560   template<typename _Ret>
1561     struct __tuple_concater<_Ret, std::_Index_tuple<>>
1562     {
1563       template<typename... _Us>
1564         static constexpr _Ret
1565         _S_do(_Us&&... __us)
1566         {
1567           return _Ret(std::forward<_Us>(__us)...);
1568         }
1569     };
1571   /// tuple_cat
1572   template<typename... _Tpls, typename = typename
1573            enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type>
1574     constexpr auto
1575     tuple_cat(_Tpls&&... __tpls)
1576     -> typename __tuple_cat_result<_Tpls...>::__type
1577     {
1578       typedef typename __tuple_cat_result<_Tpls...>::__type __ret;
1579       typedef typename __make_1st_indices<_Tpls...>::__type __idx;
1580       typedef __tuple_concater<__ret, __idx, _Tpls...> __concater;
1581       return __concater::_S_do(std::forward<_Tpls>(__tpls)...);
1582     }
1584   // _GLIBCXX_RESOLVE_LIB_DEFECTS
1585   // 2301. Why is tie not constexpr?
1586   /// tie
1587   template<typename... _Elements>
1588     constexpr tuple<_Elements&...>
1589     tie(_Elements&... __args) noexcept
1590     { return tuple<_Elements&...>(__args...); }
1592   /// swap
1593   template<typename... _Elements>
1594     inline
1595 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
1596     // Constrained free swap overload, see p0185r1
1597     typename enable_if<__and_<__is_swappable<_Elements>...>::value
1598       >::type
1599 #else
1600     void
1601 #endif
1602     swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
1603     noexcept(noexcept(__x.swap(__y)))
1604     { __x.swap(__y); }
1606 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
1607   template<typename... _Elements>
1608     typename enable_if<!__and_<__is_swappable<_Elements>...>::value>::type
1609     swap(tuple<_Elements...>&, tuple<_Elements...>&) = delete;
1610 #endif
1612   // A class (and instance) which can be used in 'tie' when an element
1613   // of a tuple is not required.
1614   // _GLIBCXX14_CONSTEXPR
1615   // 2933. PR for LWG 2773 could be clearer
1616   struct _Swallow_assign
1617   {
1618     template<class _Tp>
1619       _GLIBCXX14_CONSTEXPR const _Swallow_assign&
1620       operator=(const _Tp&) const
1621       { return *this; }
1622   };
1624   // _GLIBCXX_RESOLVE_LIB_DEFECTS
1625   // 2773. Making std::ignore constexpr
1626   _GLIBCXX17_INLINE constexpr _Swallow_assign ignore{};
1628   /// Partial specialization for tuples
1629   template<typename... _Types, typename _Alloc>
1630     struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { };
1632   // See stl_pair.h...
1633   template<class _T1, class _T2>
1634     template<typename... _Args1, typename... _Args2>
1635       inline
1636       pair<_T1, _T2>::
1637       pair(piecewise_construct_t,
1638            tuple<_Args1...> __first, tuple<_Args2...> __second)
1639       : pair(__first, __second,
1640              typename _Build_index_tuple<sizeof...(_Args1)>::__type(),
1641              typename _Build_index_tuple<sizeof...(_Args2)>::__type())
1642       { }
1644   template<class _T1, class _T2>
1645     template<typename... _Args1, std::size_t... _Indexes1,
1646              typename... _Args2, std::size_t... _Indexes2>
1647       inline
1648       pair<_T1, _T2>::
1649       pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2,
1650            _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)
1651       : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...),
1652         second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
1653       { }
1655 #if __cplusplus > 201402L
1656 # define __cpp_lib_apply 201603
1658   template <typename _Fn, typename _Tuple, size_t... _Idx>
1659     constexpr decltype(auto)
1660     __apply_impl(_Fn&& __f, _Tuple&& __t, index_sequence<_Idx...>)
1661     {
1662       return std::__invoke(std::forward<_Fn>(__f),
1663                            std::get<_Idx>(std::forward<_Tuple>(__t))...);
1664     }
1666   template <typename _Fn, typename _Tuple>
1667     constexpr decltype(auto)
1668     apply(_Fn&& __f, _Tuple&& __t)
1669     {
1670       using _Indices = make_index_sequence<tuple_size_v<decay_t<_Tuple>>>;
1671       return std::__apply_impl(std::forward<_Fn>(__f),
1672                                std::forward<_Tuple>(__t),
1673                                _Indices{});
1674     }
1676 #define __cpp_lib_make_from_tuple  201606
1678   template <typename _Tp, typename _Tuple, size_t... _Idx>
1679     constexpr _Tp
1680     __make_from_tuple_impl(_Tuple&& __t, index_sequence<_Idx...>)
1681     { return _Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...); }
1683   template <typename _Tp, typename _Tuple>
1684     constexpr _Tp
1685     make_from_tuple(_Tuple&& __t)
1686     {
1687       return __make_from_tuple_impl<_Tp>(
1688         std::forward<_Tuple>(__t),
1689         make_index_sequence<tuple_size_v<decay_t<_Tuple>>>{});
1690     }
1691 #endif // C++17
1693   /// @}
1695 _GLIBCXX_END_NAMESPACE_VERSION
1696 } // namespace std
1698 #endif // C++11
1700 #endif // _GLIBCXX_TUPLE