1// <tuple> -*- C++ -*-
2
3// Copyright (C) 2007-2022 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library.  This library is free
6// software; you can redistribute it and/or modify it under the
7// terms of the GNU General Public License as published by the
8// Free Software Foundation; either version 3, or (at your option)
9// any later version.
10
11// This library is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14// GNU General Public License for more details.
15
16// Under Section 7 of GPL version 3, you are granted additional
17// permissions described in the GCC Runtime Library Exception, version
18// 3.1, as published by the Free Software Foundation.
19
20// You should have received a copy of the GNU General Public License and
21// a copy of the GCC Runtime Library Exception along with this program;
22// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23// <http://www.gnu.org/licenses/>.
24
25/** @file include/tuple
26 *  This is a Standard C++ Library header.
27 */
28
29#ifndef _GLIBCXX_TUPLE
30#define _GLIBCXX_TUPLE 1
31
32#pragma GCC system_header
33
34#if __cplusplus < 201103L
35# include <bits/c++0x_warning.h>
36#else
37
38#include <bits/stl_pair.h>              // for std::pair
39#include <bits/uses_allocator.h>        // for std::allocator_arg_t
40#include <bits/utility.h>               // for std::get, std::tuple_size etc.
41#include <bits/invoke.h>                // for std::__invoke
42#if __cplusplus > 201703L
43# include <compare>
44# define __cpp_lib_constexpr_tuple 201811L
45#endif
46
47namespace std _GLIBCXX_VISIBILITY(default)
48{
49_GLIBCXX_BEGIN_NAMESPACE_VERSION
50
51  /**
52   *  @addtogroup utilities
53   *  @{
54   */
55
56  template<typename... _Elements>
57    class tuple;
58
59  template<typename _Tp>
60    struct __is_empty_non_tuple : is_empty<_Tp> { };
61
62  // Using EBO for elements that are tuples causes ambiguous base errors.
63  template<typename _El0, typename... _El>
64    struct __is_empty_non_tuple<tuple<_El0, _El...>> : false_type { };
65
66  // Use the Empty Base-class Optimization for empty, non-final types.
67  template<typename _Tp>
68    using __empty_not_final
69    = __conditional_t<__is_final(_Tp), false_type,
70                          __is_empty_non_tuple<_Tp>>;
71
72  template<size_t _Idx, typename _Head,
73             bool = __empty_not_final<_Head>::value>
74    struct _Head_base;
75
76#if __has_cpp_attribute(__no_unique_address__)
77  template<size_t _Idx, typename _Head>
78    struct _Head_base<_Idx, _Head, true>
79    {
80      constexpr _Head_base()
81      : _M_head_impl() { }
82
83      constexpr _Head_base(const _Head& __h)
84      : _M_head_impl(__h) { }
85
86      constexpr _Head_base(const _Head_base&) = default;
87      constexpr _Head_base(_Head_base&&) = default;
88
89      template<typename _UHead>
90          constexpr _Head_base(_UHead&& __h)
91          : _M_head_impl(std::forward<_UHead>(__h)) { }
92
93      _GLIBCXX20_CONSTEXPR
94      _Head_base(allocator_arg_t, __uses_alloc0)
95      : _M_head_impl() { }
96
97      template<typename _Alloc>
98          _GLIBCXX20_CONSTEXPR
99          _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
100          : _M_head_impl(allocator_arg, *__a._M_a) { }
101
102      template<typename _Alloc>
103          _GLIBCXX20_CONSTEXPR
104          _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
105          : _M_head_impl(*__a._M_a) { }
106
107      template<typename _UHead>
108          _GLIBCXX20_CONSTEXPR
109          _Head_base(__uses_alloc0, _UHead&& __uhead)
110          : _M_head_impl(std::forward<_UHead>(__uhead)) { }
111
112      template<typename _Alloc, typename _UHead>
113          _GLIBCXX20_CONSTEXPR
114          _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
115          : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead))
116          { }
117
118      template<typename _Alloc, typename _UHead>
119          _GLIBCXX20_CONSTEXPR
120          _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
121          : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { }
122
123      static constexpr _Head&
124      _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; }
125
126      static constexpr const _Head&
127      _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; }
128
129      [[__no_unique_address__]] _Head _M_head_impl;
130    };
131#else
132  template<size_t _Idx, typename _Head>
133    struct _Head_base<_Idx, _Head, true>
134    : public _Head
135    {
136      constexpr _Head_base()
137      : _Head() { }
138
139      constexpr _Head_base(const _Head& __h)
140      : _Head(__h) { }
141
142      constexpr _Head_base(const _Head_base&) = default;
143      constexpr _Head_base(_Head_base&&) = default;
144
145      template<typename _UHead>
146        constexpr _Head_base(_UHead&& __h)
147          : _Head(std::forward<_UHead>(__h)) { }
148
149      _GLIBCXX20_CONSTEXPR
150      _Head_base(allocator_arg_t, __uses_alloc0)
151      : _Head() { }
152
153      template<typename _Alloc>
154          _GLIBCXX20_CONSTEXPR
155          _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
156          : _Head(allocator_arg, *__a._M_a) { }
157
158      template<typename _Alloc>
159          _GLIBCXX20_CONSTEXPR
160          _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
161          : _Head(*__a._M_a) { }
162
163      template<typename _UHead>
164          _GLIBCXX20_CONSTEXPR
165          _Head_base(__uses_alloc0, _UHead&& __uhead)
166          : _Head(std::forward<_UHead>(__uhead)) { }
167
168      template<typename _Alloc, typename _UHead>
169          _GLIBCXX20_CONSTEXPR
170          _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
171          : _Head(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { }
172
173      template<typename _Alloc, typename _UHead>
174          _GLIBCXX20_CONSTEXPR
175          _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
176          : _Head(std::forward<_UHead>(__uhead), *__a._M_a) { }
177
178      static constexpr _Head&
179      _M_head(_Head_base& __b) noexcept { return __b; }
180
181      static constexpr const _Head&
182      _M_head(const _Head_base& __b) noexcept { return __b; }
183    };
184#endif
185
186  template<size_t _Idx, typename _Head>
187    struct _Head_base<_Idx, _Head, false>
188    {
189      constexpr _Head_base()
190      : _M_head_impl() { }
191
192      constexpr _Head_base(const _Head& __h)
193      : _M_head_impl(__h) { }
194
195      constexpr _Head_base(const _Head_base&) = default;
196      constexpr _Head_base(_Head_base&&) = default;
197
198      template<typename _UHead>
199        constexpr _Head_base(_UHead&& __h)
200          : _M_head_impl(std::forward<_UHead>(__h)) { }
201
202      _GLIBCXX20_CONSTEXPR
203      _Head_base(allocator_arg_t, __uses_alloc0)
204      : _M_head_impl() { }
205
206      template<typename _Alloc>
207          _GLIBCXX20_CONSTEXPR
208          _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
209          : _M_head_impl(allocator_arg, *__a._M_a) { }
210
211      template<typename _Alloc>
212          _GLIBCXX20_CONSTEXPR
213          _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
214          : _M_head_impl(*__a._M_a) { }
215
216      template<typename _UHead>
217          _GLIBCXX20_CONSTEXPR
218          _Head_base(__uses_alloc0, _UHead&& __uhead)
219          : _M_head_impl(std::forward<_UHead>(__uhead)) { }
220
221      template<typename _Alloc, typename _UHead>
222          _GLIBCXX20_CONSTEXPR
223          _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
224          : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead))
225          { }
226
227      template<typename _Alloc, typename _UHead>
228          _GLIBCXX20_CONSTEXPR
229          _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
230          : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { }
231
232      static constexpr _Head&
233      _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; }
234
235      static constexpr const _Head&
236      _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; }
237
238      _Head _M_head_impl;
239    };
240
241  /**
242   * Contains the actual implementation of the @c tuple template, stored
243   * as a recursive inheritance hierarchy from the first element (most
244   * derived class) to the last (least derived class). The @c Idx
245   * parameter gives the 0-based index of the element stored at this
246   * point in the hierarchy; we use it to implement a constant-time
247   * get() operation.
248   */
249  template<size_t _Idx, typename... _Elements>
250    struct _Tuple_impl;
251
252  /**
253   * Recursive tuple implementation. Here we store the @c Head element
254   * and derive from a @c Tuple_impl containing the remaining elements
255   * (which contains the @c Tail).
256   */
257  template<size_t _Idx, typename _Head, typename... _Tail>
258    struct _Tuple_impl<_Idx, _Head, _Tail...>
259    : public _Tuple_impl<_Idx + 1, _Tail...>,
260      private _Head_base<_Idx, _Head>
261    {
262      template<size_t, typename...> friend struct _Tuple_impl;
263
264      typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
265      typedef _Head_base<_Idx, _Head> _Base;
266
267      static constexpr _Head&
268      _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
269
270      static constexpr const _Head&
271      _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
272
273      static constexpr _Inherited&
274      _M_tail(_Tuple_impl& __t) noexcept { return __t; }
275
276      static constexpr const _Inherited&
277      _M_tail(const _Tuple_impl& __t) noexcept { return __t; }
278
279      constexpr _Tuple_impl()
280      : _Inherited(), _Base() { }
281
282      explicit constexpr
283      _Tuple_impl(const _Head& __head, const _Tail&... __tail)
284      : _Inherited(__tail...), _Base(__head)
285      { }
286
287      template<typename _UHead, typename... _UTail,
288                 typename = __enable_if_t<sizeof...(_Tail) == sizeof...(_UTail)>>
289          explicit constexpr
290          _Tuple_impl(_UHead&& __head, _UTail&&... __tail)
291          : _Inherited(std::forward<_UTail>(__tail)...),
292            _Base(std::forward<_UHead>(__head))
293          { }
294
295      constexpr _Tuple_impl(const _Tuple_impl&) = default;
296
297      // _GLIBCXX_RESOLVE_LIB_DEFECTS
298      // 2729. Missing SFINAE on std::pair::operator=
299      _Tuple_impl& operator=(const _Tuple_impl&) = delete;
300
301      _Tuple_impl(_Tuple_impl&&) = default;
302
303      template<typename... _UElements>
304          constexpr
305          _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in)
306          : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
307            _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in))
308          { }
309
310      template<typename _UHead, typename... _UTails>
311          constexpr
312          _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
313          : _Inherited(std::move
314                         (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
315            _Base(std::forward<_UHead>
316                    (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)))
317          { }
318
319      template<typename _Alloc>
320          _GLIBCXX20_CONSTEXPR
321          _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
322          : _Inherited(__tag, __a),
323            _Base(__tag, __use_alloc<_Head>(__a))
324          { }
325
326      template<typename _Alloc>
327          _GLIBCXX20_CONSTEXPR
328          _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
329                        const _Head& __head, const _Tail&... __tail)
330          : _Inherited(__tag, __a, __tail...),
331            _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head)
332          { }
333
334      template<typename _Alloc, typename _UHead, typename... _UTail,
335                 typename = __enable_if_t<sizeof...(_Tail) == sizeof...(_UTail)>>
336          _GLIBCXX20_CONSTEXPR
337          _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
338                        _UHead&& __head, _UTail&&... __tail)
339          : _Inherited(__tag, __a, std::forward<_UTail>(__tail)...),
340            _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
341                    std::forward<_UHead>(__head))
342          { }
343
344      template<typename _Alloc>
345          _GLIBCXX20_CONSTEXPR
346          _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
347                        const _Tuple_impl& __in)
348          : _Inherited(__tag, __a, _M_tail(__in)),
349            _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in))
350          { }
351
352      template<typename _Alloc>
353          _GLIBCXX20_CONSTEXPR
354          _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
355                        _Tuple_impl&& __in)
356          : _Inherited(__tag, __a, std::move(_M_tail(__in))),
357            _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
358                    std::forward<_Head>(_M_head(__in)))
359          { }
360
361      template<typename _Alloc, typename _UHead, typename... _UTails>
362          _GLIBCXX20_CONSTEXPR
363          _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
364                        const _Tuple_impl<_Idx, _UHead, _UTails...>& __in)
365          : _Inherited(__tag, __a,
366                         _Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)),
367            _Base(__use_alloc<_Head, _Alloc, const _UHead&>(__a),
368                    _Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))
369          { }
370
371      template<typename _Alloc, typename _UHead, typename... _UTails>
372          _GLIBCXX20_CONSTEXPR
373          _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
374                        _Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
375          : _Inherited(__tag, __a, std::move
376                         (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
377            _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
378                    std::forward<_UHead>
379                    (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)))
380          { }
381
382      template<typename... _UElements>
383          _GLIBCXX20_CONSTEXPR
384          void
385          _M_assign(const _Tuple_impl<_Idx, _UElements...>& __in)
386          {
387            _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in);
388            _M_tail(*this)._M_assign(
389                _Tuple_impl<_Idx, _UElements...>::_M_tail(__in));
390          }
391
392      template<typename _UHead, typename... _UTails>
393          _GLIBCXX20_CONSTEXPR
394          void
395          _M_assign(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
396          {
397            _M_head(*this) = std::forward<_UHead>
398              (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in));
399            _M_tail(*this)._M_assign(
400                std::move(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)));
401          }
402
403    protected:
404      _GLIBCXX20_CONSTEXPR
405      void
406      _M_swap(_Tuple_impl& __in)
407      {
408          using std::swap;
409          swap(_M_head(*this), _M_head(__in));
410          _Inherited::_M_swap(_M_tail(__in));
411      }
412    };
413
414  // Basis case of inheritance recursion.
415  template<size_t _Idx, typename _Head>
416    struct _Tuple_impl<_Idx, _Head>
417    : private _Head_base<_Idx, _Head>
418    {
419      template<size_t, typename...> friend struct _Tuple_impl;
420
421      typedef _Head_base<_Idx, _Head> _Base;
422
423      static constexpr _Head&
424      _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
425
426      static constexpr const _Head&
427      _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
428
429      constexpr
430      _Tuple_impl()
431      : _Base() { }
432
433      explicit constexpr
434      _Tuple_impl(const _Head& __head)
435      : _Base(__head)
436      { }
437
438      template<typename _UHead>
439          explicit constexpr
440          _Tuple_impl(_UHead&& __head)
441          : _Base(std::forward<_UHead>(__head))
442          { }
443
444      constexpr _Tuple_impl(const _Tuple_impl&) = default;
445
446      // _GLIBCXX_RESOLVE_LIB_DEFECTS
447      // 2729. Missing SFINAE on std::pair::operator=
448      _Tuple_impl& operator=(const _Tuple_impl&) = delete;
449
450#if _GLIBCXX_INLINE_VERSION
451      _Tuple_impl(_Tuple_impl&&) = default;
452#else
453      constexpr
454      _Tuple_impl(_Tuple_impl&& __in)
455      noexcept(is_nothrow_move_constructible<_Head>::value)
456      : _Base(static_cast<_Base&&>(__in))
457      { }
458#endif
459
460      template<typename _UHead>
461          constexpr
462          _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in)
463          : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in))
464          { }
465
466      template<typename _UHead>
467          constexpr
468          _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in)
469          : _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
470          { }
471
472      template<typename _Alloc>
473          _GLIBCXX20_CONSTEXPR
474          _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
475          : _Base(__tag, __use_alloc<_Head>(__a))
476          { }
477
478      template<typename _Alloc>
479          _GLIBCXX20_CONSTEXPR
480          _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
481                        const _Head& __head)
482          : _Base(__use_alloc<_Head, _Alloc, const _Head&>(__a), __head)
483          { }
484
485      template<typename _Alloc, typename _UHead>
486          _GLIBCXX20_CONSTEXPR
487          _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
488                        _UHead&& __head)
489          : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
490                    std::forward<_UHead>(__head))
491          { }
492
493      template<typename _Alloc>
494          _GLIBCXX20_CONSTEXPR
495          _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
496                        const _Tuple_impl& __in)
497          : _Base(__use_alloc<_Head, _Alloc, const _Head&>(__a), _M_head(__in))
498          { }
499
500      template<typename _Alloc>
501          _GLIBCXX20_CONSTEXPR
502          _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
503                        _Tuple_impl&& __in)
504          : _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
505                    std::forward<_Head>(_M_head(__in)))
506          { }
507
508      template<typename _Alloc, typename _UHead>
509          _GLIBCXX20_CONSTEXPR
510          _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
511                        const _Tuple_impl<_Idx, _UHead>& __in)
512          : _Base(__use_alloc<_Head, _Alloc, const _UHead&>(__a),
513                    _Tuple_impl<_Idx, _UHead>::_M_head(__in))
514          { }
515
516      template<typename _Alloc, typename _UHead>
517          _GLIBCXX20_CONSTEXPR
518          _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
519                        _Tuple_impl<_Idx, _UHead>&& __in)
520          : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
521                    std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
522          { }
523
524      template<typename _UHead>
525          _GLIBCXX20_CONSTEXPR
526          void
527          _M_assign(const _Tuple_impl<_Idx, _UHead>& __in)
528          {
529            _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in);
530          }
531
532      template<typename _UHead>
533          _GLIBCXX20_CONSTEXPR
534          void
535          _M_assign(_Tuple_impl<_Idx, _UHead>&& __in)
536          {
537            _M_head(*this)
538              = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in));
539          }
540
541    protected:
542      _GLIBCXX20_CONSTEXPR
543      void
544      _M_swap(_Tuple_impl& __in)
545      {
546          using std::swap;
547          swap(_M_head(*this), _M_head(__in));
548      }
549    };
550
551  // Concept utility functions, reused in conditionally-explicit
552  // constructors.
553  template<bool, typename... _Types>
554    struct _TupleConstraints
555    {
556      // Constraint for a non-explicit constructor.
557      // True iff each Ti in _Types... can be constructed from Ui in _UTypes...
558      // and every Ui is implicitly convertible to Ti.
559      template<typename... _UTypes>
560          static constexpr bool __is_implicitly_constructible()
561          {
562            return __and_<is_constructible<_Types, _UTypes>...,
563                              is_convertible<_UTypes, _Types>...
564                              >::value;
565          }
566
567      // Constraint for a non-explicit constructor.
568      // True iff each Ti in _Types... can be constructed from Ui in _UTypes...
569      // but not every Ui is implicitly convertible to Ti.
570      template<typename... _UTypes>
571          static constexpr bool __is_explicitly_constructible()
572          {
573            return __and_<is_constructible<_Types, _UTypes>...,
574                              __not_<__and_<is_convertible<_UTypes, _Types>...>>
575                              >::value;
576          }
577
578      static constexpr bool __is_implicitly_default_constructible()
579      {
580          return __and_<std::__is_implicitly_default_constructible<_Types>...
581                          >::value;
582      }
583
584      static constexpr bool __is_explicitly_default_constructible()
585      {
586          return __and_<is_default_constructible<_Types>...,
587                          __not_<__and_<
588                              std::__is_implicitly_default_constructible<_Types>...>
589                          >>::value;
590      }
591    };
592
593  // Partial specialization used when a required precondition isn't met,
594  // e.g. when sizeof...(_Types) != sizeof...(_UTypes).
595  template<typename... _Types>
596    struct _TupleConstraints<false, _Types...>
597    {
598      template<typename... _UTypes>
599          static constexpr bool __is_implicitly_constructible()
600          { return false; }
601
602      template<typename... _UTypes>
603          static constexpr bool __is_explicitly_constructible()
604          { return false; }
605    };
606
607  /// Primary class template, tuple
608  template<typename... _Elements>
609    class tuple : public _Tuple_impl<0, _Elements...>
610    {
611      typedef _Tuple_impl<0, _Elements...> _Inherited;
612
613      template<bool _Cond>
614          using _TCC = _TupleConstraints<_Cond, _Elements...>;
615
616      // Constraint for non-explicit default constructor
617      template<bool _Dummy>
618          using _ImplicitDefaultCtor = __enable_if_t<
619            _TCC<_Dummy>::__is_implicitly_default_constructible(),
620            bool>;
621
622      // Constraint for explicit default constructor
623      template<bool _Dummy>
624          using _ExplicitDefaultCtor = __enable_if_t<
625            _TCC<_Dummy>::__is_explicitly_default_constructible(),
626            bool>;
627
628      // Constraint for non-explicit constructors
629      template<bool _Cond, typename... _Args>
630          using _ImplicitCtor = __enable_if_t<
631            _TCC<_Cond>::template __is_implicitly_constructible<_Args...>(),
632            bool>;
633
634      // Constraint for non-explicit constructors
635      template<bool _Cond, typename... _Args>
636          using _ExplicitCtor = __enable_if_t<
637            _TCC<_Cond>::template __is_explicitly_constructible<_Args...>(),
638            bool>;
639
640      template<typename... _UElements>
641          static constexpr
642          __enable_if_t<sizeof...(_UElements) == sizeof...(_Elements), bool>
643          __assignable()
644          { return __and_<is_assignable<_Elements&, _UElements>...>::value; }
645
646      // Condition for noexcept-specifier of an assignment operator.
647      template<typename... _UElements>
648          static constexpr bool __nothrow_assignable()
649          {
650            return
651              __and_<is_nothrow_assignable<_Elements&, _UElements>...>::value;
652          }
653
654      // Condition for noexcept-specifier of a constructor.
655      template<typename... _UElements>
656          static constexpr bool __nothrow_constructible()
657          {
658            return
659              __and_<is_nothrow_constructible<_Elements, _UElements>...>::value;
660          }
661
662      // Constraint for tuple(_UTypes&&...) where sizeof...(_UTypes) == 1.
663      template<typename _Up>
664          static constexpr bool __valid_args()
665          {
666            return sizeof...(_Elements) == 1
667              && !is_same<tuple, __remove_cvref_t<_Up>>::value;
668          }
669
670      // Constraint for tuple(_UTypes&&...) where sizeof...(_UTypes) > 1.
671      template<typename, typename, typename... _Tail>
672          static constexpr bool __valid_args()
673          { return (sizeof...(_Tail) + 2) == sizeof...(_Elements); }
674
675      /* Constraint for constructors with a tuple<UTypes...> parameter ensures
676       * that the constructor is only viable when it would not interfere with
677       * tuple(UTypes&&...) or tuple(const tuple&) or tuple(tuple&&).
678       * Such constructors are only viable if:
679       * either sizeof...(Types) != 1,
680       * or (when Types... expands to T and UTypes... expands to U)
681       * is_convertible_v<TUPLE, T>, is_constructible_v<T, TUPLE>,
682       * and is_same_v<T, U> are all false.
683       */
684      template<typename _Tuple, typename = tuple,
685                 typename = __remove_cvref_t<_Tuple>>
686          struct _UseOtherCtor
687          : false_type
688          { };
689      // If TUPLE is convertible to the single element in *this,
690      // then TUPLE should match tuple(UTypes&&...) instead.
691      template<typename _Tuple, typename _Tp, typename _Up>
692          struct _UseOtherCtor<_Tuple, tuple<_Tp>, tuple<_Up>>
693          : __or_<is_convertible<_Tuple, _Tp>, is_constructible<_Tp, _Tuple>>
694          { };
695      // If TUPLE and *this each have a single element of the same type,
696      // then TUPLE should match a copy/move constructor instead.
697      template<typename _Tuple, typename _Tp>
698          struct _UseOtherCtor<_Tuple, tuple<_Tp>, tuple<_Tp>>
699          : true_type
700          { };
701
702      // Return true iff sizeof...(Types) == 1 && tuple_size_v<TUPLE> == 1
703      // and the single element in Types can be initialized from TUPLE,
704      // or is the same type as tuple_element_t<0, TUPLE>.
705      template<typename _Tuple>
706          static constexpr bool __use_other_ctor()
707          { return _UseOtherCtor<_Tuple>::value; }
708
709    public:
710      template<typename _Dummy = void,
711                 _ImplicitDefaultCtor<is_void<_Dummy>::value> = true>
712          constexpr
713          tuple()
714          noexcept(__and_<is_nothrow_default_constructible<_Elements>...>::value)
715          : _Inherited() { }
716
717      template<typename _Dummy = void,
718                 _ExplicitDefaultCtor<is_void<_Dummy>::value> = false>
719          explicit constexpr
720          tuple()
721          noexcept(__and_<is_nothrow_default_constructible<_Elements>...>::value)
722          : _Inherited() { }
723
724      template<bool _NotEmpty = (sizeof...(_Elements) >= 1),
725                 _ImplicitCtor<_NotEmpty, const _Elements&...> = true>
726          constexpr
727          tuple(const _Elements&... __elements)
728          noexcept(__nothrow_constructible<const _Elements&...>())
729          : _Inherited(__elements...) { }
730
731      template<bool _NotEmpty = (sizeof...(_Elements) >= 1),
732                 _ExplicitCtor<_NotEmpty, const _Elements&...> = false>
733          explicit constexpr
734          tuple(const _Elements&... __elements)
735          noexcept(__nothrow_constructible<const _Elements&...>())
736          : _Inherited(__elements...) { }
737
738      template<typename... _UElements,
739                 bool _Valid = __valid_args<_UElements...>(),
740                 _ImplicitCtor<_Valid, _UElements...> = true>
741          constexpr
742          tuple(_UElements&&... __elements)
743          noexcept(__nothrow_constructible<_UElements...>())
744          : _Inherited(std::forward<_UElements>(__elements)...) { }
745
746      template<typename... _UElements,
747                 bool _Valid = __valid_args<_UElements...>(),
748                 _ExplicitCtor<_Valid, _UElements...> = false>
749          explicit constexpr
750          tuple(_UElements&&... __elements)
751          noexcept(__nothrow_constructible<_UElements...>())
752          : _Inherited(std::forward<_UElements>(__elements)...) {     }
753
754      constexpr tuple(const tuple&) = default;
755
756      constexpr tuple(tuple&&) = default;
757
758      template<typename... _UElements,
759                 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
760                                 && !__use_other_ctor<const tuple<_UElements...>&>(),
761                 _ImplicitCtor<_Valid, const _UElements&...> = true>
762          constexpr
763          tuple(const tuple<_UElements...>& __in)
764          noexcept(__nothrow_constructible<const _UElements&...>())
765          : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
766          { }
767
768      template<typename... _UElements,
769                 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
770                                 && !__use_other_ctor<const tuple<_UElements...>&>(),
771                 _ExplicitCtor<_Valid, const _UElements&...> = false>
772          explicit constexpr
773          tuple(const tuple<_UElements...>& __in)
774          noexcept(__nothrow_constructible<const _UElements&...>())
775          : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
776          { }
777
778      template<typename... _UElements,
779                 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
780                                   && !__use_other_ctor<tuple<_UElements...>&&>(),
781                 _ImplicitCtor<_Valid, _UElements...> = true>
782          constexpr
783          tuple(tuple<_UElements...>&& __in)
784          noexcept(__nothrow_constructible<_UElements...>())
785          : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
786
787      template<typename... _UElements,
788                 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
789                                   && !__use_other_ctor<tuple<_UElements...>&&>(),
790                 _ExplicitCtor<_Valid, _UElements...> = false>
791          explicit constexpr
792          tuple(tuple<_UElements...>&& __in)
793          noexcept(__nothrow_constructible<_UElements...>())
794          : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
795
796      // Allocator-extended constructors.
797
798      template<typename _Alloc,
799                 _ImplicitDefaultCtor<is_object<_Alloc>::value> = true>
800          _GLIBCXX20_CONSTEXPR
801          tuple(allocator_arg_t __tag, const _Alloc& __a)
802          : _Inherited(__tag, __a) { }
803
804      template<typename _Alloc,
805                 _ExplicitDefaultCtor<is_object<_Alloc>::value> = false>
806          _GLIBCXX20_CONSTEXPR
807          explicit
808          tuple(allocator_arg_t __tag, const _Alloc& __a)
809          : _Inherited(__tag, __a) { }
810
811      template<typename _Alloc, bool _NotEmpty = (sizeof...(_Elements) >= 1),
812                 _ImplicitCtor<_NotEmpty, const _Elements&...> = true>
813          _GLIBCXX20_CONSTEXPR
814          tuple(allocator_arg_t __tag, const _Alloc& __a,
815                const _Elements&... __elements)
816          : _Inherited(__tag, __a, __elements...) { }
817
818      template<typename _Alloc, bool _NotEmpty = (sizeof...(_Elements) >= 1),
819                 _ExplicitCtor<_NotEmpty, const _Elements&...> = false>
820          _GLIBCXX20_CONSTEXPR
821          explicit
822          tuple(allocator_arg_t __tag, const _Alloc& __a,
823                const _Elements&... __elements)
824          : _Inherited(__tag, __a, __elements...) { }
825
826      template<typename _Alloc, typename... _UElements,
827                 bool _Valid = __valid_args<_UElements...>(),
828                 _ImplicitCtor<_Valid, _UElements...> = true>
829          _GLIBCXX20_CONSTEXPR
830          tuple(allocator_arg_t __tag, const _Alloc& __a,
831                _UElements&&... __elements)
832          : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
833          { }
834
835      template<typename _Alloc, typename... _UElements,
836                     bool _Valid = __valid_args<_UElements...>(),
837                 _ExplicitCtor<_Valid, _UElements...> = false>
838          _GLIBCXX20_CONSTEXPR
839          explicit
840          tuple(allocator_arg_t __tag, const _Alloc& __a,
841                _UElements&&... __elements)
842          : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
843          { }
844
845      template<typename _Alloc>
846          _GLIBCXX20_CONSTEXPR
847          tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
848          : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
849
850      template<typename _Alloc>
851          _GLIBCXX20_CONSTEXPR
852          tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
853          : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
854
855      template<typename _Alloc, typename... _UElements,
856                 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
857                                   && !__use_other_ctor<const tuple<_UElements...>&>(),
858                 _ImplicitCtor<_Valid, const _UElements&...> = true>
859          _GLIBCXX20_CONSTEXPR
860          tuple(allocator_arg_t __tag, const _Alloc& __a,
861                const tuple<_UElements...>& __in)
862          : _Inherited(__tag, __a,
863                       static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
864          { }
865
866      template<typename _Alloc, typename... _UElements,
867                 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
868                                   && !__use_other_ctor<const tuple<_UElements...>&>(),
869                 _ExplicitCtor<_Valid, const _UElements&...> = false>
870          _GLIBCXX20_CONSTEXPR
871          explicit
872          tuple(allocator_arg_t __tag, const _Alloc& __a,
873                const tuple<_UElements...>& __in)
874          : _Inherited(__tag, __a,
875                       static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
876          { }
877
878      template<typename _Alloc, typename... _UElements,
879                 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
880                                   && !__use_other_ctor<tuple<_UElements...>&&>(),
881                 _ImplicitCtor<_Valid, _UElements...> = true>
882          _GLIBCXX20_CONSTEXPR
883          tuple(allocator_arg_t __tag, const _Alloc& __a,
884                tuple<_UElements...>&& __in)
885          : _Inherited(__tag, __a,
886                       static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
887          { }
888
889      template<typename _Alloc, typename... _UElements,
890                 bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
891                                   && !__use_other_ctor<tuple<_UElements...>&&>(),
892                 _ExplicitCtor<_Valid, _UElements...> = false>
893          _GLIBCXX20_CONSTEXPR
894          explicit
895          tuple(allocator_arg_t __tag, const _Alloc& __a,
896                tuple<_UElements...>&& __in)
897          : _Inherited(__tag, __a,
898                       static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
899          { }
900
901      // tuple assignment
902
903      _GLIBCXX20_CONSTEXPR
904      tuple&
905      operator=(__conditional_t<__assignable<const _Elements&...>(),
906                                        const tuple&,
907                                        const __nonesuch&> __in)
908      noexcept(__nothrow_assignable<const _Elements&...>())
909      {
910          this->_M_assign(__in);
911          return *this;
912      }
913
914      _GLIBCXX20_CONSTEXPR
915      tuple&
916      operator=(__conditional_t<__assignable<_Elements...>(),
917                                        tuple&&,
918                                        __nonesuch&&> __in)
919      noexcept(__nothrow_assignable<_Elements...>())
920      {
921          this->_M_assign(std::move(__in));
922          return *this;
923      }
924
925      template<typename... _UElements>
926          _GLIBCXX20_CONSTEXPR
927          __enable_if_t<__assignable<const _UElements&...>(), tuple&>
928          operator=(const tuple<_UElements...>& __in)
929          noexcept(__nothrow_assignable<const _UElements&...>())
930          {
931            this->_M_assign(__in);
932            return *this;
933          }
934
935      template<typename... _UElements>
936          _GLIBCXX20_CONSTEXPR
937          __enable_if_t<__assignable<_UElements...>(), tuple&>
938          operator=(tuple<_UElements...>&& __in)
939          noexcept(__nothrow_assignable<_UElements...>())
940          {
941            this->_M_assign(std::move(__in));
942            return *this;
943          }
944
945      // tuple swap
946      _GLIBCXX20_CONSTEXPR
947      void
948      swap(tuple& __in)
949      noexcept(__and_<__is_nothrow_swappable<_Elements>...>::value)
950      { _Inherited::_M_swap(__in); }
951    };
952
953#if __cpp_deduction_guides >= 201606
954  template<typename... _UTypes>
955    tuple(_UTypes...) -> tuple<_UTypes...>;
956  template<typename _T1, typename _T2>
957    tuple(pair<_T1, _T2>) -> tuple<_T1, _T2>;
958  template<typename _Alloc, typename... _UTypes>
959    tuple(allocator_arg_t, _Alloc, _UTypes...) -> tuple<_UTypes...>;
960  template<typename _Alloc, typename _T1, typename _T2>
961    tuple(allocator_arg_t, _Alloc, pair<_T1, _T2>) -> tuple<_T1, _T2>;
962  template<typename _Alloc, typename... _UTypes>
963    tuple(allocator_arg_t, _Alloc, tuple<_UTypes...>) -> tuple<_UTypes...>;
964#endif
965
966  // Explicit specialization, zero-element tuple.
967  template<>
968    class tuple<>
969    {
970    public:
971      _GLIBCXX20_CONSTEXPR
972      void swap(tuple&) noexcept { /* no-op */ }
973      // We need the default since we're going to define no-op
974      // allocator constructors.
975      tuple() = default;
976      // No-op allocator constructors.
977      template<typename _Alloc>
978          _GLIBCXX20_CONSTEXPR
979          tuple(allocator_arg_t, const _Alloc&) noexcept { }
980      template<typename _Alloc>
981          _GLIBCXX20_CONSTEXPR
982          tuple(allocator_arg_t, const _Alloc&, const tuple&) noexcept { }
983    };
984
985  /// Partial specialization, 2-element tuple.
986  /// Includes construction and assignment from a pair.
987  template<typename _T1, typename _T2>
988    class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
989    {
990      typedef _Tuple_impl<0, _T1, _T2> _Inherited;
991
992      // Constraint for non-explicit default constructor
993      template<bool _Dummy, typename _U1, typename _U2>
994          using _ImplicitDefaultCtor = __enable_if_t<
995            _TupleConstraints<_Dummy, _U1, _U2>::
996              __is_implicitly_default_constructible(),
997            bool>;
998
999      // Constraint for explicit default constructor
1000      template<bool _Dummy, typename _U1, typename _U2>
1001          using _ExplicitDefaultCtor = __enable_if_t<
1002            _TupleConstraints<_Dummy, _U1, _U2>::
1003              __is_explicitly_default_constructible(),
1004            bool>;
1005
1006      template<bool _Dummy>
1007          using _TCC = _TupleConstraints<_Dummy, _T1, _T2>;
1008
1009      // Constraint for non-explicit constructors
1010      template<bool _Cond, typename _U1, typename _U2>
1011          using _ImplicitCtor = __enable_if_t<
1012            _TCC<_Cond>::template __is_implicitly_constructible<_U1, _U2>(),
1013            bool>;
1014
1015      // Constraint for non-explicit constructors
1016      template<bool _Cond, typename _U1, typename _U2>
1017          using _ExplicitCtor = __enable_if_t<
1018            _TCC<_Cond>::template __is_explicitly_constructible<_U1, _U2>(),
1019            bool>;
1020
1021      template<typename _U1, typename _U2>
1022          static constexpr bool __assignable()
1023          {
1024            return __and_<is_assignable<_T1&, _U1>,
1025                              is_assignable<_T2&, _U2>>::value;
1026          }
1027
1028      template<typename _U1, typename _U2>
1029          static constexpr bool __nothrow_assignable()
1030          {
1031            return __and_<is_nothrow_assignable<_T1&, _U1>,
1032                              is_nothrow_assignable<_T2&, _U2>>::value;
1033          }
1034
1035      template<typename _U1, typename _U2>
1036          static constexpr bool __nothrow_constructible()
1037          {
1038            return __and_<is_nothrow_constructible<_T1, _U1>,
1039                                  is_nothrow_constructible<_T2, _U2>>::value;
1040          }
1041
1042      static constexpr bool __nothrow_default_constructible()
1043      {
1044          return __and_<is_nothrow_default_constructible<_T1>,
1045                          is_nothrow_default_constructible<_T2>>::value;
1046      }
1047
1048      template<typename _U1>
1049          static constexpr bool __is_alloc_arg()
1050          { return is_same<__remove_cvref_t<_U1>, allocator_arg_t>::value; }
1051
1052    public:
1053      template<bool _Dummy = true,
1054                 _ImplicitDefaultCtor<_Dummy, _T1, _T2> = true>
1055          constexpr
1056          tuple()
1057          noexcept(__nothrow_default_constructible())
1058          : _Inherited() { }
1059
1060      template<bool _Dummy = true,
1061                 _ExplicitDefaultCtor<_Dummy, _T1, _T2> = false>
1062          explicit constexpr
1063          tuple()
1064          noexcept(__nothrow_default_constructible())
1065          : _Inherited() { }
1066
1067      template<bool _Dummy = true,
1068                 _ImplicitCtor<_Dummy, const _T1&, const _T2&> = true>
1069          constexpr
1070          tuple(const _T1& __a1, const _T2& __a2)
1071          noexcept(__nothrow_constructible<const _T1&, const _T2&>())
1072          : _Inherited(__a1, __a2) { }
1073
1074      template<bool _Dummy = true,
1075                 _ExplicitCtor<_Dummy, const _T1&, const _T2&> = false>
1076          explicit constexpr
1077          tuple(const _T1& __a1, const _T2& __a2)
1078          noexcept(__nothrow_constructible<const _T1&, const _T2&>())
1079          : _Inherited(__a1, __a2) { }
1080
1081      template<typename _U1, typename _U2,
1082                 _ImplicitCtor<!__is_alloc_arg<_U1>(), _U1, _U2> = true>
1083          constexpr
1084          tuple(_U1&& __a1, _U2&& __a2)
1085          noexcept(__nothrow_constructible<_U1, _U2>())
1086          : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
1087
1088      template<typename _U1, typename _U2,
1089                 _ExplicitCtor<!__is_alloc_arg<_U1>(), _U1, _U2> = false>
1090          explicit constexpr
1091          tuple(_U1&& __a1, _U2&& __a2)
1092          noexcept(__nothrow_constructible<_U1, _U2>())
1093          : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
1094
1095      constexpr tuple(const tuple&) = default;
1096
1097      constexpr tuple(tuple&&) = default;
1098
1099      template<typename _U1, typename _U2,
1100                 _ImplicitCtor<true, const _U1&, const _U2&> = true>
1101          constexpr
1102          tuple(const tuple<_U1, _U2>& __in)
1103          noexcept(__nothrow_constructible<const _U1&, const _U2&>())
1104          : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
1105
1106      template<typename _U1, typename _U2,
1107                 _ExplicitCtor<true, const _U1&, const _U2&> = false>
1108          explicit constexpr
1109          tuple(const tuple<_U1, _U2>& __in)
1110          noexcept(__nothrow_constructible<const _U1&, const _U2&>())
1111          : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
1112
1113      template<typename _U1, typename _U2,
1114                 _ImplicitCtor<true, _U1, _U2> = true>
1115          constexpr
1116          tuple(tuple<_U1, _U2>&& __in)
1117          noexcept(__nothrow_constructible<_U1, _U2>())
1118          : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
1119
1120      template<typename _U1, typename _U2,
1121                 _ExplicitCtor<true, _U1, _U2> = false>
1122          explicit constexpr
1123          tuple(tuple<_U1, _U2>&& __in)
1124          noexcept(__nothrow_constructible<_U1, _U2>())
1125          : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
1126
1127      template<typename _U1, typename _U2,
1128                 _ImplicitCtor<true, const _U1&, const _U2&> = true>
1129          constexpr
1130          tuple(const pair<_U1, _U2>& __in)
1131          noexcept(__nothrow_constructible<const _U1&, const _U2&>())
1132          : _Inherited(__in.first, __in.second) { }
1133
1134      template<typename _U1, typename _U2,
1135                 _ExplicitCtor<true, const _U1&, const _U2&> = false>
1136          explicit constexpr
1137          tuple(const pair<_U1, _U2>& __in)
1138          noexcept(__nothrow_constructible<const _U1&, const _U2&>())
1139          : _Inherited(__in.first, __in.second) { }
1140
1141      template<typename _U1, typename _U2,
1142                 _ImplicitCtor<true, _U1, _U2> = true>
1143          constexpr
1144          tuple(pair<_U1, _U2>&& __in)
1145          noexcept(__nothrow_constructible<_U1, _U2>())
1146          : _Inherited(std::forward<_U1>(__in.first),
1147                         std::forward<_U2>(__in.second)) { }
1148
1149      template<typename _U1, typename _U2,
1150                 _ExplicitCtor<true, _U1, _U2> = false>
1151          explicit constexpr
1152          tuple(pair<_U1, _U2>&& __in)
1153          noexcept(__nothrow_constructible<_U1, _U2>())
1154          : _Inherited(std::forward<_U1>(__in.first),
1155                         std::forward<_U2>(__in.second)) { }
1156
1157      // Allocator-extended constructors.
1158
1159      template<typename _Alloc,
1160                 _ImplicitDefaultCtor<is_object<_Alloc>::value, _T1, _T2> = true>
1161          _GLIBCXX20_CONSTEXPR
1162          tuple(allocator_arg_t __tag, const _Alloc& __a)
1163          : _Inherited(__tag, __a) { }
1164
1165      template<typename _Alloc,
1166                 _ExplicitDefaultCtor<is_object<_Alloc>::value, _T1, _T2> = false>
1167          _GLIBCXX20_CONSTEXPR
1168          explicit
1169          tuple(allocator_arg_t __tag, const _Alloc& __a)
1170          : _Inherited(__tag, __a) { }
1171
1172      template<typename _Alloc, bool _Dummy = true,
1173                 _ImplicitCtor<_Dummy, const _T1&, const _T2&> = true>
1174          _GLIBCXX20_CONSTEXPR
1175          tuple(allocator_arg_t __tag, const _Alloc& __a,
1176                const _T1& __a1, const _T2& __a2)
1177          : _Inherited(__tag, __a, __a1, __a2) { }
1178
1179      template<typename _Alloc, bool _Dummy = true,
1180                 _ExplicitCtor<_Dummy, const _T1&, const _T2&> = false>
1181          explicit
1182          _GLIBCXX20_CONSTEXPR
1183          tuple(allocator_arg_t __tag, const _Alloc& __a,
1184                const _T1& __a1, const _T2& __a2)
1185          : _Inherited(__tag, __a, __a1, __a2) { }
1186
1187      template<typename _Alloc, typename _U1, typename _U2,
1188                 _ImplicitCtor<true, _U1, _U2> = true>
1189          _GLIBCXX20_CONSTEXPR
1190          tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2)
1191          : _Inherited(__tag, __a, std::forward<_U1>(__a1),
1192                       std::forward<_U2>(__a2)) { }
1193
1194      template<typename _Alloc, typename _U1, typename _U2,
1195                 _ExplicitCtor<true, _U1, _U2> = false>
1196          explicit
1197          _GLIBCXX20_CONSTEXPR
1198          tuple(allocator_arg_t __tag, const _Alloc& __a,
1199                _U1&& __a1, _U2&& __a2)
1200          : _Inherited(__tag, __a, std::forward<_U1>(__a1),
1201                       std::forward<_U2>(__a2)) { }
1202
1203      template<typename _Alloc>
1204          _GLIBCXX20_CONSTEXPR
1205          tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
1206          : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
1207
1208      template<typename _Alloc>
1209          _GLIBCXX20_CONSTEXPR
1210          tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
1211          : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
1212
1213      template<typename _Alloc, typename _U1, typename _U2,
1214                 _ImplicitCtor<true, const _U1&, const _U2&> = true>
1215          _GLIBCXX20_CONSTEXPR
1216          tuple(allocator_arg_t __tag, const _Alloc& __a,
1217                const tuple<_U1, _U2>& __in)
1218          : _Inherited(__tag, __a,
1219                       static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
1220          { }
1221
1222      template<typename _Alloc, typename _U1, typename _U2,
1223                 _ExplicitCtor<true, const _U1&, const _U2&> = false>
1224          explicit
1225          _GLIBCXX20_CONSTEXPR
1226          tuple(allocator_arg_t __tag, const _Alloc& __a,
1227                const tuple<_U1, _U2>& __in)
1228          : _Inherited(__tag, __a,
1229                       static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
1230          { }
1231
1232      template<typename _Alloc, typename _U1, typename _U2,
1233                 _ImplicitCtor<true, _U1, _U2> = true>
1234          _GLIBCXX20_CONSTEXPR
1235          tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
1236          : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
1237          { }
1238
1239      template<typename _Alloc, typename _U1, typename _U2,
1240                 _ExplicitCtor<true, _U1, _U2> = false>
1241          explicit
1242          _GLIBCXX20_CONSTEXPR
1243          tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
1244          : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
1245          { }
1246
1247      template<typename _Alloc, typename _U1, typename _U2,
1248                 _ImplicitCtor<true, const _U1&, const _U2&> = true>
1249          _GLIBCXX20_CONSTEXPR
1250          tuple(allocator_arg_t __tag, const _Alloc& __a,
1251                const pair<_U1, _U2>& __in)
1252          : _Inherited(__tag, __a, __in.first, __in.second) { }
1253
1254      template<typename _Alloc, typename _U1, typename _U2,
1255                 _ExplicitCtor<true, const _U1&, const _U2&> = false>
1256          explicit
1257          _GLIBCXX20_CONSTEXPR
1258          tuple(allocator_arg_t __tag, const _Alloc& __a,
1259                const pair<_U1, _U2>& __in)
1260          : _Inherited(__tag, __a, __in.first, __in.second) { }
1261
1262      template<typename _Alloc, typename _U1, typename _U2,
1263                 _ImplicitCtor<true, _U1, _U2> = true>
1264          _GLIBCXX20_CONSTEXPR
1265          tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
1266          : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
1267                         std::forward<_U2>(__in.second)) { }
1268
1269      template<typename _Alloc, typename _U1, typename _U2,
1270                 _ExplicitCtor<true, _U1, _U2> = false>
1271          explicit
1272          _GLIBCXX20_CONSTEXPR
1273          tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
1274          : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
1275                         std::forward<_U2>(__in.second)) { }
1276
1277      // Tuple assignment.
1278
1279      _GLIBCXX20_CONSTEXPR
1280      tuple&
1281      operator=(__conditional_t<__assignable<const _T1&, const _T2&>(),
1282                                        const tuple&,
1283                                        const __nonesuch&> __in)
1284      noexcept(__nothrow_assignable<const _T1&, const _T2&>())
1285      {
1286          this->_M_assign(__in);
1287          return *this;
1288      }
1289
1290      _GLIBCXX20_CONSTEXPR
1291      tuple&
1292      operator=(__conditional_t<__assignable<_T1, _T2>(),
1293                                        tuple&&,
1294                                        __nonesuch&&> __in)
1295      noexcept(__nothrow_assignable<_T1, _T2>())
1296      {
1297          this->_M_assign(std::move(__in));
1298          return *this;
1299      }
1300
1301      template<typename _U1, typename _U2>
1302          _GLIBCXX20_CONSTEXPR
1303          __enable_if_t<__assignable<const _U1&, const _U2&>(), tuple&>
1304          operator=(const tuple<_U1, _U2>& __in)
1305          noexcept(__nothrow_assignable<const _U1&, const _U2&>())
1306          {
1307            this->_M_assign(__in);
1308            return *this;
1309          }
1310
1311      template<typename _U1, typename _U2>
1312          _GLIBCXX20_CONSTEXPR
1313          __enable_if_t<__assignable<_U1, _U2>(), tuple&>
1314          operator=(tuple<_U1, _U2>&& __in)
1315          noexcept(__nothrow_assignable<_U1, _U2>())
1316          {
1317            this->_M_assign(std::move(__in));
1318            return *this;
1319          }
1320
1321      template<typename _U1, typename _U2>
1322          _GLIBCXX20_CONSTEXPR
1323          __enable_if_t<__assignable<const _U1&, const _U2&>(), tuple&>
1324          operator=(const pair<_U1, _U2>& __in)
1325          noexcept(__nothrow_assignable<const _U1&, const _U2&>())
1326          {
1327            this->_M_head(*this) = __in.first;
1328            this->_M_tail(*this)._M_head(*this) = __in.second;
1329            return *this;
1330          }
1331
1332      template<typename _U1, typename _U2>
1333          _GLIBCXX20_CONSTEXPR
1334          __enable_if_t<__assignable<_U1, _U2>(), tuple&>
1335          operator=(pair<_U1, _U2>&& __in)
1336          noexcept(__nothrow_assignable<_U1, _U2>())
1337          {
1338            this->_M_head(*this) = std::forward<_U1>(__in.first);
1339            this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second);
1340            return *this;
1341          }
1342
1343      _GLIBCXX20_CONSTEXPR
1344      void
1345      swap(tuple& __in)
1346      noexcept(__and_<__is_nothrow_swappable<_T1>,
1347                          __is_nothrow_swappable<_T2>>::value)
1348      { _Inherited::_M_swap(__in); }
1349    };
1350
1351
1352  /// class tuple_size
1353  template<typename... _Elements>
1354    struct tuple_size<tuple<_Elements...>>
1355    : public integral_constant<size_t, sizeof...(_Elements)> { };
1356
1357#if __cplusplus >= 201703L
1358  template<typename... _Types>
1359    inline constexpr size_t tuple_size_v<tuple<_Types...>>
1360      = sizeof...(_Types);
1361
1362  template<typename... _Types>
1363    inline constexpr size_t tuple_size_v<const tuple<_Types...>>
1364      = sizeof...(_Types);
1365#endif
1366
1367  /// Trait to get the Ith element type from a tuple.
1368  template<size_t __i, typename... _Types>
1369    struct tuple_element<__i, tuple<_Types...>>
1370    {
1371      static_assert(__i < sizeof...(_Types), "tuple index must be in range");
1372
1373      using type = typename _Nth_type<__i, _Types...>::type;
1374    };
1375
1376  template<size_t __i, typename _Head, typename... _Tail>
1377    constexpr _Head&
1378    __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1379    { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
1380
1381  template<size_t __i, typename _Head, typename... _Tail>
1382    constexpr const _Head&
1383    __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1384    { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
1385
1386  // Deleted overload to improve diagnostics for invalid indices
1387  template<size_t __i, typename... _Types>
1388    __enable_if_t<(__i >= sizeof...(_Types))>
1389    __get_helper(const tuple<_Types...>&) = delete;
1390
1391  /// Return a reference to the ith element of a tuple.
1392  template<size_t __i, typename... _Elements>
1393    constexpr __tuple_element_t<__i, tuple<_Elements...>>&
1394    get(tuple<_Elements...>& __t) noexcept
1395    { return std::__get_helper<__i>(__t); }
1396
1397  /// Return a const reference to the ith element of a const tuple.
1398  template<size_t __i, typename... _Elements>
1399    constexpr const __tuple_element_t<__i, tuple<_Elements...>>&
1400    get(const tuple<_Elements...>& __t) noexcept
1401    { return std::__get_helper<__i>(__t); }
1402
1403  /// Return an rvalue reference to the ith element of a tuple rvalue.
1404  template<size_t __i, typename... _Elements>
1405    constexpr __tuple_element_t<__i, tuple<_Elements...>>&&
1406    get(tuple<_Elements...>&& __t) noexcept
1407    {
1408      typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
1409      return std::forward<__element_type>(std::__get_helper<__i>(__t));
1410    }
1411
1412  /// Return a const rvalue reference to the ith element of a const tuple rvalue.
1413  template<size_t __i, typename... _Elements>
1414    constexpr const __tuple_element_t<__i, tuple<_Elements...>>&&
1415    get(const tuple<_Elements...>&& __t) noexcept
1416    {
1417      typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
1418      return std::forward<const __element_type>(std::__get_helper<__i>(__t));
1419    }
1420
1421  /// @cond undocumented
1422  // Deleted overload chosen for invalid indices.
1423  template<size_t __i, typename... _Elements>
1424    constexpr __enable_if_t<(__i >= sizeof...(_Elements))>
1425    get(const tuple<_Elements...>&) = delete;
1426  /// @endcond
1427
1428#if __cplusplus >= 201402L
1429
1430#define __cpp_lib_tuples_by_type 201304L
1431
1432  /// Return a reference to the unique element of type _Tp of a tuple.
1433  template <typename _Tp, typename... _Types>
1434    constexpr _Tp&
1435    get(tuple<_Types...>& __t) noexcept
1436    {
1437      constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>();
1438      static_assert(__idx < sizeof...(_Types),
1439            "the type T in std::get<T> must occur exactly once in the tuple");
1440      return std::__get_helper<__idx>(__t);
1441    }
1442
1443  /// Return a reference to the unique element of type _Tp of a tuple rvalue.
1444  template <typename _Tp, typename... _Types>
1445    constexpr _Tp&&
1446    get(tuple<_Types...>&& __t) noexcept
1447    {
1448      constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>();
1449      static_assert(__idx < sizeof...(_Types),
1450            "the type T in std::get<T> must occur exactly once in the tuple");
1451      return std::forward<_Tp>(std::__get_helper<__idx>(__t));
1452    }
1453
1454  /// Return a const reference to the unique element of type _Tp of a tuple.
1455  template <typename _Tp, typename... _Types>
1456    constexpr const _Tp&
1457    get(const tuple<_Types...>& __t) noexcept
1458    {
1459      constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>();
1460      static_assert(__idx < sizeof...(_Types),
1461            "the type T in std::get<T> must occur exactly once in the tuple");
1462      return std::__get_helper<__idx>(__t);
1463    }
1464
1465  /// Return a const reference to the unique element of type _Tp of
1466  /// a const tuple rvalue.
1467  template <typename _Tp, typename... _Types>
1468    constexpr const _Tp&&
1469    get(const tuple<_Types...>&& __t) noexcept
1470    {
1471      constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>();
1472      static_assert(__idx < sizeof...(_Types),
1473            "the type T in std::get<T> must occur exactly once in the tuple");
1474      return std::forward<const _Tp>(std::__get_helper<__idx>(__t));
1475    }
1476#endif
1477
1478  // This class performs the comparison operations on tuples
1479  template<typename _Tp, typename _Up, size_t __i, size_t __size>
1480    struct __tuple_compare
1481    {
1482      static constexpr bool
1483      __eq(const _Tp& __t, const _Up& __u)
1484      {
1485          return bool(std::get<__i>(__t) == std::get<__i>(__u))
1486            && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u);
1487      }
1488
1489      static constexpr bool
1490      __less(const _Tp& __t, const _Up& __u)
1491      {
1492          return bool(std::get<__i>(__t) < std::get<__i>(__u))
1493            || (!bool(std::get<__i>(__u) < std::get<__i>(__t))
1494                && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u));
1495      }
1496    };
1497
1498  template<typename _Tp, typename _Up, size_t __size>
1499    struct __tuple_compare<_Tp, _Up, __size, __size>
1500    {
1501      static constexpr bool
1502      __eq(const _Tp&, const _Up&) { return true; }
1503
1504      static constexpr bool
1505      __less(const _Tp&, const _Up&) { return false; }
1506    };
1507
1508  template<typename... _TElements, typename... _UElements>
1509    constexpr bool
1510    operator==(const tuple<_TElements...>& __t,
1511                 const tuple<_UElements...>& __u)
1512    {
1513      static_assert(sizeof...(_TElements) == sizeof...(_UElements),
1514            "tuple objects can only be compared if they have equal sizes.");
1515      using __compare = __tuple_compare<tuple<_TElements...>,
1516                                                  tuple<_UElements...>,
1517                                                  0, sizeof...(_TElements)>;
1518      return __compare::__eq(__t, __u);
1519    }
1520
1521#if __cpp_lib_three_way_comparison
1522  template<typename _Cat, typename _Tp, typename _Up>
1523    constexpr _Cat
1524    __tuple_cmp(const _Tp&, const _Up&, index_sequence<>)
1525    { return _Cat::equivalent; }
1526
1527  template<typename _Cat, typename _Tp, typename _Up,
1528             size_t _Idx0, size_t... _Idxs>
1529    constexpr _Cat
1530    __tuple_cmp(const _Tp& __t, const _Up& __u,
1531                    index_sequence<_Idx0, _Idxs...>)
1532    {
1533      auto __c
1534          = __detail::__synth3way(std::get<_Idx0>(__t), std::get<_Idx0>(__u));
1535      if (__c != 0)
1536          return __c;
1537      return std::__tuple_cmp<_Cat>(__t, __u, index_sequence<_Idxs...>());
1538    }
1539
1540  template<typename... _Tps, typename... _Ups>
1541    constexpr
1542    common_comparison_category_t<__detail::__synth3way_t<_Tps, _Ups>...>
1543    operator<=>(const tuple<_Tps...>& __t, const tuple<_Ups...>& __u)
1544    {
1545      using _Cat
1546          = common_comparison_category_t<__detail::__synth3way_t<_Tps, _Ups>...>;
1547      return std::__tuple_cmp<_Cat>(__t, __u, index_sequence_for<_Tps...>());
1548    }
1549#else
1550  template<typename... _TElements, typename... _UElements>
1551    constexpr bool
1552    operator<(const tuple<_TElements...>& __t,
1553                const tuple<_UElements...>& __u)
1554    {
1555      static_assert(sizeof...(_TElements) == sizeof...(_UElements),
1556            "tuple objects can only be compared if they have equal sizes.");
1557      using __compare = __tuple_compare<tuple<_TElements...>,
1558                                                  tuple<_UElements...>,
1559                                                  0, sizeof...(_TElements)>;
1560      return __compare::__less(__t, __u);
1561    }
1562
1563  template<typename... _TElements, typename... _UElements>
1564    constexpr bool
1565    operator!=(const tuple<_TElements...>& __t,
1566                 const tuple<_UElements...>& __u)
1567    { return !(__t == __u); }
1568
1569  template<typename... _TElements, typename... _UElements>
1570    constexpr bool
1571    operator>(const tuple<_TElements...>& __t,
1572                const tuple<_UElements...>& __u)
1573    { return __u < __t; }
1574
1575  template<typename... _TElements, typename... _UElements>
1576    constexpr bool
1577    operator<=(const tuple<_TElements...>& __t,
1578                 const tuple<_UElements...>& __u)
1579    { return !(__u < __t); }
1580
1581  template<typename... _TElements, typename... _UElements>
1582    constexpr bool
1583    operator>=(const tuple<_TElements...>& __t,
1584                 const tuple<_UElements...>& __u)
1585    { return !(__t < __u); }
1586#endif // three_way_comparison
1587
1588  // NB: DR 705.
1589  /// Create a tuple containing copies of the arguments
1590  template<typename... _Elements>
1591    constexpr tuple<typename __decay_and_strip<_Elements>::__type...>
1592    make_tuple(_Elements&&... __args)
1593    {
1594      typedef tuple<typename __decay_and_strip<_Elements>::__type...>
1595          __result_type;
1596      return __result_type(std::forward<_Elements>(__args)...);
1597    }
1598
1599  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1600  // 2275. Why is forward_as_tuple not constexpr?
1601  /// Create a tuple of lvalue or rvalue references to the arguments
1602  template<typename... _Elements>
1603    constexpr tuple<_Elements&&...>
1604    forward_as_tuple(_Elements&&... __args) noexcept
1605    { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
1606
1607  // Declarations of std::array and its std::get overloads, so that
1608  // std::tuple_cat can use them if <tuple> is included before <array>.
1609
1610  template<typename _Tp, size_t _Nm> struct array;
1611
1612  template<size_t _Int, typename _Tp, size_t _Nm>
1613    constexpr _Tp&
1614    get(array<_Tp, _Nm>&) noexcept;
1615
1616  template<size_t _Int, typename _Tp, size_t _Nm>
1617    constexpr _Tp&&
1618    get(array<_Tp, _Nm>&&) noexcept;
1619
1620  template<size_t _Int, typename _Tp, size_t _Nm>
1621    constexpr const _Tp&
1622    get(const array<_Tp, _Nm>&) noexcept;
1623
1624  template<size_t _Int, typename _Tp, size_t _Nm>
1625    constexpr const _Tp&&
1626    get(const array<_Tp, _Nm>&&) noexcept;
1627
1628  /// @cond undocumented
1629  template<size_t, typename, typename, size_t>
1630    struct __make_tuple_impl;
1631
1632  template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm>
1633    struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm>
1634    : __make_tuple_impl<_Idx + 1,
1635                              tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>,
1636                              _Tuple, _Nm>
1637    { };
1638
1639  template<size_t _Nm, typename _Tuple, typename... _Tp>
1640    struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm>
1641    {
1642      typedef tuple<_Tp...> __type;
1643    };
1644
1645  template<typename _Tuple>
1646    struct __do_make_tuple
1647    : __make_tuple_impl<0, tuple<>, _Tuple, tuple_size<_Tuple>::value>
1648    { };
1649
1650  // Returns the std::tuple equivalent of a tuple-like type.
1651  template<typename _Tuple>
1652    struct __make_tuple
1653    : public __do_make_tuple<__remove_cvref_t<_Tuple>>
1654    { };
1655
1656  // Combines several std::tuple's into a single one.
1657  template<typename...>
1658    struct __combine_tuples;
1659
1660  template<>
1661    struct __combine_tuples<>
1662    {
1663      typedef tuple<> __type;
1664    };
1665
1666  template<typename... _Ts>
1667    struct __combine_tuples<tuple<_Ts...>>
1668    {
1669      typedef tuple<_Ts...> __type;
1670    };
1671
1672  template<typename... _T1s, typename... _T2s, typename... _Rem>
1673    struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...>
1674    {
1675      typedef typename __combine_tuples<tuple<_T1s..., _T2s...>,
1676                                                  _Rem...>::__type __type;
1677    };
1678
1679  // Computes the result type of tuple_cat given a set of tuple-like types.
1680  template<typename... _Tpls>
1681    struct __tuple_cat_result
1682    {
1683      typedef typename __combine_tuples
1684        <typename __make_tuple<_Tpls>::__type...>::__type __type;
1685    };
1686
1687  // Helper to determine the index set for the first tuple-like
1688  // type of a given set.
1689  template<typename...>
1690    struct __make_1st_indices;
1691
1692  template<>
1693    struct __make_1st_indices<>
1694    {
1695      typedef _Index_tuple<> __type;
1696    };
1697
1698  template<typename _Tp, typename... _Tpls>
1699    struct __make_1st_indices<_Tp, _Tpls...>
1700    {
1701      typedef typename _Build_index_tuple<tuple_size<
1702          typename remove_reference<_Tp>::type>::value>::__type __type;
1703    };
1704
1705  // Performs the actual concatenation by step-wise expanding tuple-like
1706  // objects into the elements,  which are finally forwarded into the
1707  // result tuple.
1708  template<typename _Ret, typename _Indices, typename... _Tpls>
1709    struct __tuple_concater;
1710
1711  template<typename _Ret, size_t... _Is, typename _Tp, typename... _Tpls>
1712    struct __tuple_concater<_Ret, _Index_tuple<_Is...>, _Tp, _Tpls...>
1713    {
1714      template<typename... _Us>
1715        static constexpr _Ret
1716        _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us)
1717        {
1718            typedef typename __make_1st_indices<_Tpls...>::__type __idx;
1719            typedef __tuple_concater<_Ret, __idx, _Tpls...>      __next;
1720            return __next::_S_do(std::forward<_Tpls>(__tps)...,
1721                                     std::forward<_Us>(__us)...,
1722                                     std::get<_Is>(std::forward<_Tp>(__tp))...);
1723          }
1724    };
1725
1726  template<typename _Ret>
1727    struct __tuple_concater<_Ret, _Index_tuple<>>
1728    {
1729      template<typename... _Us>
1730          static constexpr _Ret
1731          _S_do(_Us&&... __us)
1732        {
1733            return _Ret(std::forward<_Us>(__us)...);
1734          }
1735    };
1736
1737  template<typename... _Tps>
1738    struct __is_tuple_like_impl<tuple<_Tps...>> : true_type
1739    { };
1740  /// @endcond
1741
1742  /// Create a `tuple` containing all elements from multiple tuple-like objects
1743  template<typename... _Tpls, typename = typename
1744           enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type>
1745    constexpr auto
1746    tuple_cat(_Tpls&&... __tpls)
1747    -> typename __tuple_cat_result<_Tpls...>::__type
1748    {
1749      typedef typename __tuple_cat_result<_Tpls...>::__type __ret;
1750      typedef typename __make_1st_indices<_Tpls...>::__type __idx;
1751      typedef __tuple_concater<__ret, __idx, _Tpls...> __concater;
1752      return __concater::_S_do(std::forward<_Tpls>(__tpls)...);
1753    }
1754
1755  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1756  // 2301. Why is tie not constexpr?
1757  /// Return a tuple of lvalue references bound to the arguments
1758  template<typename... _Elements>
1759    constexpr tuple<_Elements&...>
1760    tie(_Elements&... __args) noexcept
1761    { return tuple<_Elements&...>(__args...); }
1762
1763  /// Exchange the values of two tuples
1764  template<typename... _Elements>
1765    _GLIBCXX20_CONSTEXPR
1766    inline
1767#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
1768    // Constrained free swap overload, see p0185r1
1769    typename enable_if<__and_<__is_swappable<_Elements>...>::value
1770      >::type
1771#else
1772    void
1773#endif
1774    swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
1775    noexcept(noexcept(__x.swap(__y)))
1776    { __x.swap(__y); }
1777
1778#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
1779  /// Exchange the values of two const tuples (if const elements can be swapped)
1780  template<typename... _Elements>
1781    _GLIBCXX20_CONSTEXPR
1782    typename enable_if<!__and_<__is_swappable<_Elements>...>::value>::type
1783    swap(tuple<_Elements...>&, tuple<_Elements...>&) = delete;
1784#endif
1785
1786  // A class (and instance) which can be used in 'tie' when an element
1787  // of a tuple is not required.
1788  // _GLIBCXX14_CONSTEXPR
1789  // 2933. PR for LWG 2773 could be clearer
1790  struct _Swallow_assign
1791  {
1792    template<class _Tp>
1793      _GLIBCXX14_CONSTEXPR const _Swallow_assign&
1794      operator=(const _Tp&) const
1795      { return *this; }
1796  };
1797
1798  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1799  // 2773. Making std::ignore constexpr
1800  /** Used with `std::tie` to ignore an element of a tuple
1801   *
1802   * When using `std::tie` to assign the elements of a tuple to variables,
1803   * unwanted elements can be ignored by using `std::ignore`. For example:
1804   *
1805   * ```
1806   * int x, y;
1807   * std::tie(x, std::ignore, y) = std::make_tuple(1, 2, 3);
1808   * ```
1809   *
1810   * This assignment will perform `x=1; std::ignore=2; y=3;` which results
1811   * in the second element being ignored.
1812   *
1813   * @since C++11
1814   */
1815  _GLIBCXX17_INLINE constexpr _Swallow_assign ignore{};
1816
1817  /// Partial specialization for tuples
1818  template<typename... _Types, typename _Alloc>
1819    struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { };
1820
1821  // See stl_pair.h...
1822  /** "piecewise construction" using a tuple of arguments for each member.
1823   *
1824   * @param __first Arguments for the first member of the pair.
1825   * @param __second Arguments for the second member of the pair.
1826   *
1827   * The elements of each tuple will be used as the constructor arguments
1828   * for the data members of the pair.
1829  */
1830  template<class _T1, class _T2>
1831    template<typename... _Args1, typename... _Args2>
1832      _GLIBCXX20_CONSTEXPR
1833      inline
1834      pair<_T1, _T2>::
1835      pair(piecewise_construct_t,
1836             tuple<_Args1...> __first, tuple<_Args2...> __second)
1837      : pair(__first, __second,
1838               typename _Build_index_tuple<sizeof...(_Args1)>::__type(),
1839               typename _Build_index_tuple<sizeof...(_Args2)>::__type())
1840      { }
1841
1842  template<class _T1, class _T2>
1843    template<typename... _Args1, size_t... _Indexes1,
1844               typename... _Args2, size_t... _Indexes2>
1845      _GLIBCXX20_CONSTEXPR inline
1846      pair<_T1, _T2>::
1847      pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2,
1848             _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)
1849      : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...),
1850          second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
1851      { }
1852
1853#if __cplusplus >= 201703L
1854
1855  // Unpack a std::tuple into a type trait and use its value.
1856  // For cv std::tuple<_Up> the result is _Trait<_Tp, cv _Up...>::value.
1857  // For cv std::tuple<_Up>& the result is _Trait<_Tp, cv _Up&...>::value.
1858  // Otherwise the result is false (because we don't know if std::get throws).
1859  template<template<typename...> class _Trait, typename _Tp, typename _Tuple>
1860    inline constexpr bool __unpack_std_tuple = false;
1861
1862  template<template<typename...> class _Trait, typename _Tp, typename... _Up>
1863    inline constexpr bool __unpack_std_tuple<_Trait, _Tp, tuple<_Up...>>
1864      = _Trait<_Tp, _Up...>::value;
1865
1866  template<template<typename...> class _Trait, typename _Tp, typename... _Up>
1867    inline constexpr bool __unpack_std_tuple<_Trait, _Tp, tuple<_Up...>&>
1868      = _Trait<_Tp, _Up&...>::value;
1869
1870  template<template<typename...> class _Trait, typename _Tp, typename... _Up>
1871    inline constexpr bool __unpack_std_tuple<_Trait, _Tp, const tuple<_Up...>>
1872      = _Trait<_Tp, const _Up...>::value;
1873
1874  template<template<typename...> class _Trait, typename _Tp, typename... _Up>
1875    inline constexpr bool __unpack_std_tuple<_Trait, _Tp, const tuple<_Up...>&>
1876      = _Trait<_Tp, const _Up&...>::value;
1877
1878# define __cpp_lib_apply 201603L
1879
1880  template <typename _Fn, typename _Tuple, size_t... _Idx>
1881    constexpr decltype(auto)
1882    __apply_impl(_Fn&& __f, _Tuple&& __t, index_sequence<_Idx...>)
1883    {
1884      return std::__invoke(std::forward<_Fn>(__f),
1885                                 std::get<_Idx>(std::forward<_Tuple>(__t))...);
1886    }
1887
1888  template <typename _Fn, typename _Tuple>
1889    constexpr decltype(auto)
1890    apply(_Fn&& __f, _Tuple&& __t)
1891    noexcept(__unpack_std_tuple<is_nothrow_invocable, _Fn, _Tuple>)
1892    {
1893      using _Indices
1894          = make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>;
1895      return std::__apply_impl(std::forward<_Fn>(__f),
1896                                     std::forward<_Tuple>(__t),
1897                                     _Indices{});
1898    }
1899
1900#define __cpp_lib_make_from_tuple  201606L
1901
1902  template <typename _Tp, typename _Tuple, size_t... _Idx>
1903    constexpr _Tp
1904    __make_from_tuple_impl(_Tuple&& __t, index_sequence<_Idx...>)
1905    { return _Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...); }
1906
1907  template <typename _Tp, typename _Tuple>
1908    constexpr _Tp
1909    make_from_tuple(_Tuple&& __t)
1910    noexcept(__unpack_std_tuple<is_nothrow_constructible, _Tp, _Tuple>)
1911    {
1912      return __make_from_tuple_impl<_Tp>(
1913        std::forward<_Tuple>(__t),
1914          make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>{});
1915    }
1916#endif // C++17
1917
1918  /// @}
1919
1920_GLIBCXX_END_NAMESPACE_VERSION
1921} // namespace std
1922
1923#endif // C++11
1924
1925#endif // _GLIBCXX_TUPLE
1926