xref: /netbsd-src/external/gpl3/gcc/dist/libstdc++-v3/include/std/tuple (revision 2dd295436a0082eb4f8d294f4aa73c223413d0f2)
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, bool _NotEmpty = (sizeof...(_Elements) >= 1),
805	       _ImplicitCtor<_NotEmpty, const _Elements&...> = true>
806	_GLIBCXX20_CONSTEXPR
807	tuple(allocator_arg_t __tag, const _Alloc& __a,
808	      const _Elements&... __elements)
809	: _Inherited(__tag, __a, __elements...) { }
810
811      template<typename _Alloc, bool _NotEmpty = (sizeof...(_Elements) >= 1),
812	       _ExplicitCtor<_NotEmpty, const _Elements&...> = false>
813	_GLIBCXX20_CONSTEXPR
814	explicit
815	tuple(allocator_arg_t __tag, const _Alloc& __a,
816	      const _Elements&... __elements)
817	: _Inherited(__tag, __a, __elements...) { }
818
819      template<typename _Alloc, typename... _UElements,
820	       bool _Valid = __valid_args<_UElements...>(),
821	       _ImplicitCtor<_Valid, _UElements...> = true>
822	_GLIBCXX20_CONSTEXPR
823	tuple(allocator_arg_t __tag, const _Alloc& __a,
824	      _UElements&&... __elements)
825	: _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
826	{ }
827
828      template<typename _Alloc, typename... _UElements,
829		 bool _Valid = __valid_args<_UElements...>(),
830	       _ExplicitCtor<_Valid, _UElements...> = false>
831	_GLIBCXX20_CONSTEXPR
832	explicit
833	tuple(allocator_arg_t __tag, const _Alloc& __a,
834	      _UElements&&... __elements)
835	: _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
836	{ }
837
838      template<typename _Alloc>
839	_GLIBCXX20_CONSTEXPR
840	tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
841	: _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
842
843      template<typename _Alloc>
844	_GLIBCXX20_CONSTEXPR
845	tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
846	: _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
847
848      template<typename _Alloc, typename... _UElements,
849	       bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
850			     && !__use_other_ctor<const tuple<_UElements...>&>(),
851	       _ImplicitCtor<_Valid, const _UElements&...> = true>
852	_GLIBCXX20_CONSTEXPR
853	tuple(allocator_arg_t __tag, const _Alloc& __a,
854	      const tuple<_UElements...>& __in)
855	: _Inherited(__tag, __a,
856	             static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
857	{ }
858
859      template<typename _Alloc, typename... _UElements,
860	       bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
861			     && !__use_other_ctor<const tuple<_UElements...>&>(),
862	       _ExplicitCtor<_Valid, const _UElements&...> = false>
863	_GLIBCXX20_CONSTEXPR
864	explicit
865	tuple(allocator_arg_t __tag, const _Alloc& __a,
866	      const tuple<_UElements...>& __in)
867	: _Inherited(__tag, __a,
868	             static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
869	{ }
870
871      template<typename _Alloc, typename... _UElements,
872	       bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
873			     && !__use_other_ctor<tuple<_UElements...>&&>(),
874	       _ImplicitCtor<_Valid, _UElements...> = true>
875	_GLIBCXX20_CONSTEXPR
876	tuple(allocator_arg_t __tag, const _Alloc& __a,
877	      tuple<_UElements...>&& __in)
878	: _Inherited(__tag, __a,
879	             static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
880	{ }
881
882      template<typename _Alloc, typename... _UElements,
883	       bool _Valid = (sizeof...(_Elements) == sizeof...(_UElements))
884			     && !__use_other_ctor<tuple<_UElements...>&&>(),
885	       _ExplicitCtor<_Valid, _UElements...> = false>
886	_GLIBCXX20_CONSTEXPR
887	explicit
888	tuple(allocator_arg_t __tag, const _Alloc& __a,
889	      tuple<_UElements...>&& __in)
890	: _Inherited(__tag, __a,
891	             static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
892	{ }
893
894      // tuple assignment
895
896      _GLIBCXX20_CONSTEXPR
897      tuple&
898      operator=(__conditional_t<__assignable<const _Elements&...>(),
899				const tuple&,
900				const __nonesuch&> __in)
901      noexcept(__nothrow_assignable<const _Elements&...>())
902      {
903	this->_M_assign(__in);
904	return *this;
905      }
906
907      _GLIBCXX20_CONSTEXPR
908      tuple&
909      operator=(__conditional_t<__assignable<_Elements...>(),
910				tuple&&,
911				__nonesuch&&> __in)
912      noexcept(__nothrow_assignable<_Elements...>())
913      {
914	this->_M_assign(std::move(__in));
915	return *this;
916      }
917
918      template<typename... _UElements>
919	_GLIBCXX20_CONSTEXPR
920	__enable_if_t<__assignable<const _UElements&...>(), tuple&>
921	operator=(const tuple<_UElements...>& __in)
922	noexcept(__nothrow_assignable<const _UElements&...>())
923	{
924	  this->_M_assign(__in);
925	  return *this;
926	}
927
928      template<typename... _UElements>
929	_GLIBCXX20_CONSTEXPR
930	__enable_if_t<__assignable<_UElements...>(), tuple&>
931	operator=(tuple<_UElements...>&& __in)
932	noexcept(__nothrow_assignable<_UElements...>())
933	{
934	  this->_M_assign(std::move(__in));
935	  return *this;
936	}
937
938      // tuple swap
939      _GLIBCXX20_CONSTEXPR
940      void
941      swap(tuple& __in)
942      noexcept(__and_<__is_nothrow_swappable<_Elements>...>::value)
943      { _Inherited::_M_swap(__in); }
944    };
945
946#if __cpp_deduction_guides >= 201606
947  template<typename... _UTypes>
948    tuple(_UTypes...) -> tuple<_UTypes...>;
949  template<typename _T1, typename _T2>
950    tuple(pair<_T1, _T2>) -> tuple<_T1, _T2>;
951  template<typename _Alloc, typename... _UTypes>
952    tuple(allocator_arg_t, _Alloc, _UTypes...) -> tuple<_UTypes...>;
953  template<typename _Alloc, typename _T1, typename _T2>
954    tuple(allocator_arg_t, _Alloc, pair<_T1, _T2>) -> tuple<_T1, _T2>;
955  template<typename _Alloc, typename... _UTypes>
956    tuple(allocator_arg_t, _Alloc, tuple<_UTypes...>) -> tuple<_UTypes...>;
957#endif
958
959  // Explicit specialization, zero-element tuple.
960  template<>
961    class tuple<>
962    {
963    public:
964      _GLIBCXX20_CONSTEXPR
965      void swap(tuple&) noexcept { /* no-op */ }
966      // We need the default since we're going to define no-op
967      // allocator constructors.
968      tuple() = default;
969      // No-op allocator constructors.
970      template<typename _Alloc>
971	_GLIBCXX20_CONSTEXPR
972	tuple(allocator_arg_t, const _Alloc&) noexcept { }
973      template<typename _Alloc>
974	_GLIBCXX20_CONSTEXPR
975	tuple(allocator_arg_t, const _Alloc&, const tuple&) noexcept { }
976    };
977
978  /// Partial specialization, 2-element tuple.
979  /// Includes construction and assignment from a pair.
980  template<typename _T1, typename _T2>
981    class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
982    {
983      typedef _Tuple_impl<0, _T1, _T2> _Inherited;
984
985      // Constraint for non-explicit default constructor
986      template<bool _Dummy, typename _U1, typename _U2>
987	using _ImplicitDefaultCtor = __enable_if_t<
988	  _TupleConstraints<_Dummy, _U1, _U2>::
989	    __is_implicitly_default_constructible(),
990	  bool>;
991
992      // Constraint for explicit default constructor
993      template<bool _Dummy, typename _U1, typename _U2>
994	using _ExplicitDefaultCtor = __enable_if_t<
995	  _TupleConstraints<_Dummy, _U1, _U2>::
996	    __is_explicitly_default_constructible(),
997	  bool>;
998
999      template<bool _Dummy>
1000	using _TCC = _TupleConstraints<_Dummy, _T1, _T2>;
1001
1002      // Constraint for non-explicit constructors
1003      template<bool _Cond, typename _U1, typename _U2>
1004	using _ImplicitCtor = __enable_if_t<
1005	  _TCC<_Cond>::template __is_implicitly_constructible<_U1, _U2>(),
1006	  bool>;
1007
1008      // Constraint for non-explicit constructors
1009      template<bool _Cond, typename _U1, typename _U2>
1010	using _ExplicitCtor = __enable_if_t<
1011	  _TCC<_Cond>::template __is_explicitly_constructible<_U1, _U2>(),
1012	  bool>;
1013
1014      template<typename _U1, typename _U2>
1015	static constexpr bool __assignable()
1016	{
1017	  return __and_<is_assignable<_T1&, _U1>,
1018			is_assignable<_T2&, _U2>>::value;
1019	}
1020
1021      template<typename _U1, typename _U2>
1022	static constexpr bool __nothrow_assignable()
1023	{
1024	  return __and_<is_nothrow_assignable<_T1&, _U1>,
1025			is_nothrow_assignable<_T2&, _U2>>::value;
1026	}
1027
1028      template<typename _U1, typename _U2>
1029	static constexpr bool __nothrow_constructible()
1030	{
1031	  return __and_<is_nothrow_constructible<_T1, _U1>,
1032			    is_nothrow_constructible<_T2, _U2>>::value;
1033	}
1034
1035      static constexpr bool __nothrow_default_constructible()
1036      {
1037	return __and_<is_nothrow_default_constructible<_T1>,
1038		      is_nothrow_default_constructible<_T2>>::value;
1039      }
1040
1041      template<typename _U1>
1042	static constexpr bool __is_alloc_arg()
1043	{ return is_same<__remove_cvref_t<_U1>, allocator_arg_t>::value; }
1044
1045    public:
1046      template<bool _Dummy = true,
1047	       _ImplicitDefaultCtor<_Dummy, _T1, _T2> = true>
1048	constexpr
1049	tuple()
1050	noexcept(__nothrow_default_constructible())
1051	: _Inherited() { }
1052
1053      template<bool _Dummy = true,
1054	       _ExplicitDefaultCtor<_Dummy, _T1, _T2> = false>
1055	explicit constexpr
1056	tuple()
1057	noexcept(__nothrow_default_constructible())
1058	: _Inherited() { }
1059
1060      template<bool _Dummy = true,
1061	       _ImplicitCtor<_Dummy, const _T1&, const _T2&> = true>
1062	constexpr
1063	tuple(const _T1& __a1, const _T2& __a2)
1064	noexcept(__nothrow_constructible<const _T1&, const _T2&>())
1065	: _Inherited(__a1, __a2) { }
1066
1067      template<bool _Dummy = true,
1068	       _ExplicitCtor<_Dummy, const _T1&, const _T2&> = false>
1069	explicit constexpr
1070	tuple(const _T1& __a1, const _T2& __a2)
1071	noexcept(__nothrow_constructible<const _T1&, const _T2&>())
1072	: _Inherited(__a1, __a2) { }
1073
1074      template<typename _U1, typename _U2,
1075	       _ImplicitCtor<!__is_alloc_arg<_U1>(), _U1, _U2> = true>
1076	constexpr
1077	tuple(_U1&& __a1, _U2&& __a2)
1078	noexcept(__nothrow_constructible<_U1, _U2>())
1079	: _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
1080
1081      template<typename _U1, typename _U2,
1082	       _ExplicitCtor<!__is_alloc_arg<_U1>(), _U1, _U2> = false>
1083	explicit 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      constexpr tuple(const tuple&) = default;
1089
1090      constexpr tuple(tuple&&) = default;
1091
1092      template<typename _U1, typename _U2,
1093	       _ImplicitCtor<true, const _U1&, const _U2&> = true>
1094	constexpr
1095	tuple(const tuple<_U1, _U2>& __in)
1096	noexcept(__nothrow_constructible<const _U1&, const _U2&>())
1097	: _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
1098
1099      template<typename _U1, typename _U2,
1100	       _ExplicitCtor<true, const _U1&, const _U2&> = false>
1101	explicit 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	       _ImplicitCtor<true, _U1, _U2> = true>
1108	constexpr
1109	tuple(tuple<_U1, _U2>&& __in)
1110	noexcept(__nothrow_constructible<_U1, _U2>())
1111	: _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
1112
1113      template<typename _U1, typename _U2,
1114	       _ExplicitCtor<true, _U1, _U2> = false>
1115	explicit 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	       _ImplicitCtor<true, const _U1&, const _U2&> = true>
1122	constexpr
1123	tuple(const pair<_U1, _U2>& __in)
1124	noexcept(__nothrow_constructible<const _U1&, const _U2&>())
1125	: _Inherited(__in.first, __in.second) { }
1126
1127      template<typename _U1, typename _U2,
1128	       _ExplicitCtor<true, const _U1&, const _U2&> = false>
1129	explicit 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	       _ImplicitCtor<true, _U1, _U2> = true>
1136	constexpr
1137	tuple(pair<_U1, _U2>&& __in)
1138	noexcept(__nothrow_constructible<_U1, _U2>())
1139	: _Inherited(std::forward<_U1>(__in.first),
1140		     std::forward<_U2>(__in.second)) { }
1141
1142      template<typename _U1, typename _U2,
1143	       _ExplicitCtor<true, _U1, _U2> = false>
1144	explicit constexpr
1145	tuple(pair<_U1, _U2>&& __in)
1146	noexcept(__nothrow_constructible<_U1, _U2>())
1147	: _Inherited(std::forward<_U1>(__in.first),
1148		     std::forward<_U2>(__in.second)) { }
1149
1150      // Allocator-extended constructors.
1151
1152      template<typename _Alloc,
1153	       _ImplicitDefaultCtor<is_object<_Alloc>::value, _T1, _T2> = true>
1154	_GLIBCXX20_CONSTEXPR
1155	tuple(allocator_arg_t __tag, const _Alloc& __a)
1156	: _Inherited(__tag, __a) { }
1157
1158      template<typename _Alloc, bool _Dummy = true,
1159	       _ImplicitCtor<_Dummy, const _T1&, const _T2&> = true>
1160	_GLIBCXX20_CONSTEXPR
1161	tuple(allocator_arg_t __tag, const _Alloc& __a,
1162	      const _T1& __a1, const _T2& __a2)
1163	: _Inherited(__tag, __a, __a1, __a2) { }
1164
1165      template<typename _Alloc, bool _Dummy = true,
1166	       _ExplicitCtor<_Dummy, const _T1&, const _T2&> = false>
1167	explicit
1168	_GLIBCXX20_CONSTEXPR
1169	tuple(allocator_arg_t __tag, const _Alloc& __a,
1170	      const _T1& __a1, const _T2& __a2)
1171	: _Inherited(__tag, __a, __a1, __a2) { }
1172
1173      template<typename _Alloc, typename _U1, typename _U2,
1174	       _ImplicitCtor<true, _U1, _U2> = true>
1175	_GLIBCXX20_CONSTEXPR
1176	tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2)
1177	: _Inherited(__tag, __a, std::forward<_U1>(__a1),
1178	             std::forward<_U2>(__a2)) { }
1179
1180      template<typename _Alloc, typename _U1, typename _U2,
1181	       _ExplicitCtor<true, _U1, _U2> = false>
1182	explicit
1183	_GLIBCXX20_CONSTEXPR
1184	tuple(allocator_arg_t __tag, const _Alloc& __a,
1185	      _U1&& __a1, _U2&& __a2)
1186	: _Inherited(__tag, __a, std::forward<_U1>(__a1),
1187	             std::forward<_U2>(__a2)) { }
1188
1189      template<typename _Alloc>
1190	_GLIBCXX20_CONSTEXPR
1191	tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
1192	: _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
1193
1194      template<typename _Alloc>
1195	_GLIBCXX20_CONSTEXPR
1196	tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
1197	: _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
1198
1199      template<typename _Alloc, typename _U1, typename _U2,
1200	       _ImplicitCtor<true, const _U1&, const _U2&> = true>
1201	_GLIBCXX20_CONSTEXPR
1202	tuple(allocator_arg_t __tag, const _Alloc& __a,
1203	      const tuple<_U1, _U2>& __in)
1204	: _Inherited(__tag, __a,
1205	             static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
1206	{ }
1207
1208      template<typename _Alloc, typename _U1, typename _U2,
1209	       _ExplicitCtor<true, const _U1&, const _U2&> = false>
1210	explicit
1211	_GLIBCXX20_CONSTEXPR
1212	tuple(allocator_arg_t __tag, const _Alloc& __a,
1213	      const tuple<_U1, _U2>& __in)
1214	: _Inherited(__tag, __a,
1215	             static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
1216	{ }
1217
1218      template<typename _Alloc, typename _U1, typename _U2,
1219	       _ImplicitCtor<true, _U1, _U2> = true>
1220	_GLIBCXX20_CONSTEXPR
1221	tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
1222	: _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
1223	{ }
1224
1225      template<typename _Alloc, typename _U1, typename _U2,
1226	       _ExplicitCtor<true, _U1, _U2> = false>
1227	explicit
1228	_GLIBCXX20_CONSTEXPR
1229	tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
1230	: _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
1231	{ }
1232
1233      template<typename _Alloc, typename _U1, typename _U2,
1234	       _ImplicitCtor<true, const _U1&, const _U2&> = true>
1235	_GLIBCXX20_CONSTEXPR
1236	tuple(allocator_arg_t __tag, const _Alloc& __a,
1237	      const pair<_U1, _U2>& __in)
1238	: _Inherited(__tag, __a, __in.first, __in.second) { }
1239
1240      template<typename _Alloc, typename _U1, typename _U2,
1241	       _ExplicitCtor<true, const _U1&, const _U2&> = false>
1242	explicit
1243	_GLIBCXX20_CONSTEXPR
1244	tuple(allocator_arg_t __tag, const _Alloc& __a,
1245	      const pair<_U1, _U2>& __in)
1246	: _Inherited(__tag, __a, __in.first, __in.second) { }
1247
1248      template<typename _Alloc, typename _U1, typename _U2,
1249	       _ImplicitCtor<true, _U1, _U2> = true>
1250	_GLIBCXX20_CONSTEXPR
1251	tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
1252	: _Inherited(__tag, __a, std::forward<_U1>(__in.first),
1253		     std::forward<_U2>(__in.second)) { }
1254
1255      template<typename _Alloc, typename _U1, typename _U2,
1256	       _ExplicitCtor<true, _U1, _U2> = false>
1257	explicit
1258	_GLIBCXX20_CONSTEXPR
1259	tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
1260	: _Inherited(__tag, __a, std::forward<_U1>(__in.first),
1261		     std::forward<_U2>(__in.second)) { }
1262
1263      // Tuple assignment.
1264
1265      _GLIBCXX20_CONSTEXPR
1266      tuple&
1267      operator=(__conditional_t<__assignable<const _T1&, const _T2&>(),
1268				const tuple&,
1269				const __nonesuch&> __in)
1270      noexcept(__nothrow_assignable<const _T1&, const _T2&>())
1271      {
1272	this->_M_assign(__in);
1273	return *this;
1274      }
1275
1276      _GLIBCXX20_CONSTEXPR
1277      tuple&
1278      operator=(__conditional_t<__assignable<_T1, _T2>(),
1279				tuple&&,
1280				__nonesuch&&> __in)
1281      noexcept(__nothrow_assignable<_T1, _T2>())
1282      {
1283	this->_M_assign(std::move(__in));
1284	return *this;
1285      }
1286
1287      template<typename _U1, typename _U2>
1288	_GLIBCXX20_CONSTEXPR
1289	__enable_if_t<__assignable<const _U1&, const _U2&>(), tuple&>
1290	operator=(const tuple<_U1, _U2>& __in)
1291	noexcept(__nothrow_assignable<const _U1&, const _U2&>())
1292	{
1293	  this->_M_assign(__in);
1294	  return *this;
1295	}
1296
1297      template<typename _U1, typename _U2>
1298	_GLIBCXX20_CONSTEXPR
1299	__enable_if_t<__assignable<_U1, _U2>(), tuple&>
1300	operator=(tuple<_U1, _U2>&& __in)
1301	noexcept(__nothrow_assignable<_U1, _U2>())
1302	{
1303	  this->_M_assign(std::move(__in));
1304	  return *this;
1305	}
1306
1307      template<typename _U1, typename _U2>
1308	_GLIBCXX20_CONSTEXPR
1309	__enable_if_t<__assignable<const _U1&, const _U2&>(), tuple&>
1310	operator=(const pair<_U1, _U2>& __in)
1311	noexcept(__nothrow_assignable<const _U1&, const _U2&>())
1312	{
1313	  this->_M_head(*this) = __in.first;
1314	  this->_M_tail(*this)._M_head(*this) = __in.second;
1315	  return *this;
1316	}
1317
1318      template<typename _U1, typename _U2>
1319	_GLIBCXX20_CONSTEXPR
1320	__enable_if_t<__assignable<_U1, _U2>(), tuple&>
1321	operator=(pair<_U1, _U2>&& __in)
1322	noexcept(__nothrow_assignable<_U1, _U2>())
1323	{
1324	  this->_M_head(*this) = std::forward<_U1>(__in.first);
1325	  this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second);
1326	  return *this;
1327	}
1328
1329      _GLIBCXX20_CONSTEXPR
1330      void
1331      swap(tuple& __in)
1332      noexcept(__and_<__is_nothrow_swappable<_T1>,
1333		      __is_nothrow_swappable<_T2>>::value)
1334      { _Inherited::_M_swap(__in); }
1335    };
1336
1337
1338  /// class tuple_size
1339  template<typename... _Elements>
1340    struct tuple_size<tuple<_Elements...>>
1341    : public integral_constant<size_t, sizeof...(_Elements)> { };
1342
1343#if __cplusplus >= 201703L
1344  template<typename... _Types>
1345    inline constexpr size_t tuple_size_v<tuple<_Types...>>
1346      = sizeof...(_Types);
1347
1348  template<typename... _Types>
1349    inline constexpr size_t tuple_size_v<const tuple<_Types...>>
1350      = sizeof...(_Types);
1351#endif
1352
1353  /// Trait to get the Ith element type from a tuple.
1354  template<size_t __i, typename... _Types>
1355    struct tuple_element<__i, tuple<_Types...>>
1356    {
1357      static_assert(__i < sizeof...(_Types), "tuple index must be in range");
1358
1359      using type = typename _Nth_type<__i, _Types...>::type;
1360    };
1361
1362  template<size_t __i, typename _Head, typename... _Tail>
1363    constexpr _Head&
1364    __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1365    { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
1366
1367  template<size_t __i, typename _Head, typename... _Tail>
1368    constexpr const _Head&
1369    __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1370    { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
1371
1372  // Deleted overload to improve diagnostics for invalid indices
1373  template<size_t __i, typename... _Types>
1374    __enable_if_t<(__i >= sizeof...(_Types))>
1375    __get_helper(const tuple<_Types...>&) = delete;
1376
1377  /// Return a reference to the ith element of a tuple.
1378  template<size_t __i, typename... _Elements>
1379    constexpr __tuple_element_t<__i, tuple<_Elements...>>&
1380    get(tuple<_Elements...>& __t) noexcept
1381    { return std::__get_helper<__i>(__t); }
1382
1383  /// Return a const reference to the ith element of a const tuple.
1384  template<size_t __i, typename... _Elements>
1385    constexpr const __tuple_element_t<__i, tuple<_Elements...>>&
1386    get(const tuple<_Elements...>& __t) noexcept
1387    { return std::__get_helper<__i>(__t); }
1388
1389  /// Return an rvalue reference to the ith element of a tuple rvalue.
1390  template<size_t __i, typename... _Elements>
1391    constexpr __tuple_element_t<__i, tuple<_Elements...>>&&
1392    get(tuple<_Elements...>&& __t) noexcept
1393    {
1394      typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
1395      return std::forward<__element_type>(std::__get_helper<__i>(__t));
1396    }
1397
1398  /// Return a const rvalue reference to the ith element of a const tuple rvalue.
1399  template<size_t __i, typename... _Elements>
1400    constexpr const __tuple_element_t<__i, tuple<_Elements...>>&&
1401    get(const tuple<_Elements...>&& __t) noexcept
1402    {
1403      typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
1404      return std::forward<const __element_type>(std::__get_helper<__i>(__t));
1405    }
1406
1407  /// @cond undocumented
1408  // Deleted overload chosen for invalid indices.
1409  template<size_t __i, typename... _Elements>
1410    constexpr __enable_if_t<(__i >= sizeof...(_Elements))>
1411    get(const tuple<_Elements...>&) = delete;
1412  /// @endcond
1413
1414#if __cplusplus >= 201402L
1415
1416#define __cpp_lib_tuples_by_type 201304L
1417
1418  /// Return a reference to the unique element of type _Tp of a tuple.
1419  template <typename _Tp, typename... _Types>
1420    constexpr _Tp&
1421    get(tuple<_Types...>& __t) noexcept
1422    {
1423      constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>();
1424      static_assert(__idx < sizeof...(_Types),
1425	  "the type T in std::get<T> must occur exactly once in the tuple");
1426      return std::__get_helper<__idx>(__t);
1427    }
1428
1429  /// Return a reference to the unique element of type _Tp of a tuple rvalue.
1430  template <typename _Tp, typename... _Types>
1431    constexpr _Tp&&
1432    get(tuple<_Types...>&& __t) noexcept
1433    {
1434      constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>();
1435      static_assert(__idx < sizeof...(_Types),
1436	  "the type T in std::get<T> must occur exactly once in the tuple");
1437      return std::forward<_Tp>(std::__get_helper<__idx>(__t));
1438    }
1439
1440  /// Return a const reference to the unique element of type _Tp of a tuple.
1441  template <typename _Tp, typename... _Types>
1442    constexpr const _Tp&
1443    get(const tuple<_Types...>& __t) noexcept
1444    {
1445      constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>();
1446      static_assert(__idx < sizeof...(_Types),
1447	  "the type T in std::get<T> must occur exactly once in the tuple");
1448      return std::__get_helper<__idx>(__t);
1449    }
1450
1451  /// Return a const reference to the unique element of type _Tp of
1452  /// a const tuple rvalue.
1453  template <typename _Tp, typename... _Types>
1454    constexpr const _Tp&&
1455    get(const tuple<_Types...>&& __t) noexcept
1456    {
1457      constexpr size_t __idx = __find_uniq_type_in_pack<_Tp, _Types...>();
1458      static_assert(__idx < sizeof...(_Types),
1459	  "the type T in std::get<T> must occur exactly once in the tuple");
1460      return std::forward<const _Tp>(std::__get_helper<__idx>(__t));
1461    }
1462#endif
1463
1464  // This class performs the comparison operations on tuples
1465  template<typename _Tp, typename _Up, size_t __i, size_t __size>
1466    struct __tuple_compare
1467    {
1468      static constexpr bool
1469      __eq(const _Tp& __t, const _Up& __u)
1470      {
1471	return bool(std::get<__i>(__t) == std::get<__i>(__u))
1472	  && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u);
1473      }
1474
1475      static constexpr bool
1476      __less(const _Tp& __t, const _Up& __u)
1477      {
1478	return bool(std::get<__i>(__t) < std::get<__i>(__u))
1479	  || (!bool(std::get<__i>(__u) < std::get<__i>(__t))
1480	      && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u));
1481      }
1482    };
1483
1484  template<typename _Tp, typename _Up, size_t __size>
1485    struct __tuple_compare<_Tp, _Up, __size, __size>
1486    {
1487      static constexpr bool
1488      __eq(const _Tp&, const _Up&) { return true; }
1489
1490      static constexpr bool
1491      __less(const _Tp&, const _Up&) { return false; }
1492    };
1493
1494  template<typename... _TElements, typename... _UElements>
1495    constexpr bool
1496    operator==(const tuple<_TElements...>& __t,
1497	       const tuple<_UElements...>& __u)
1498    {
1499      static_assert(sizeof...(_TElements) == sizeof...(_UElements),
1500	  "tuple objects can only be compared if they have equal sizes.");
1501      using __compare = __tuple_compare<tuple<_TElements...>,
1502					tuple<_UElements...>,
1503					0, sizeof...(_TElements)>;
1504      return __compare::__eq(__t, __u);
1505    }
1506
1507#if __cpp_lib_three_way_comparison
1508  template<typename _Cat, typename _Tp, typename _Up>
1509    constexpr _Cat
1510    __tuple_cmp(const _Tp&, const _Up&, index_sequence<>)
1511    { return _Cat::equivalent; }
1512
1513  template<typename _Cat, typename _Tp, typename _Up,
1514	   size_t _Idx0, size_t... _Idxs>
1515    constexpr _Cat
1516    __tuple_cmp(const _Tp& __t, const _Up& __u,
1517		index_sequence<_Idx0, _Idxs...>)
1518    {
1519      auto __c
1520	= __detail::__synth3way(std::get<_Idx0>(__t), std::get<_Idx0>(__u));
1521      if (__c != 0)
1522	return __c;
1523      return std::__tuple_cmp<_Cat>(__t, __u, index_sequence<_Idxs...>());
1524    }
1525
1526  template<typename... _Tps, typename... _Ups>
1527    constexpr
1528    common_comparison_category_t<__detail::__synth3way_t<_Tps, _Ups>...>
1529    operator<=>(const tuple<_Tps...>& __t, const tuple<_Ups...>& __u)
1530    {
1531      using _Cat
1532	= common_comparison_category_t<__detail::__synth3way_t<_Tps, _Ups>...>;
1533      return std::__tuple_cmp<_Cat>(__t, __u, index_sequence_for<_Tps...>());
1534    }
1535#else
1536  template<typename... _TElements, typename... _UElements>
1537    constexpr bool
1538    operator<(const tuple<_TElements...>& __t,
1539	      const tuple<_UElements...>& __u)
1540    {
1541      static_assert(sizeof...(_TElements) == sizeof...(_UElements),
1542	  "tuple objects can only be compared if they have equal sizes.");
1543      using __compare = __tuple_compare<tuple<_TElements...>,
1544					tuple<_UElements...>,
1545					0, sizeof...(_TElements)>;
1546      return __compare::__less(__t, __u);
1547    }
1548
1549  template<typename... _TElements, typename... _UElements>
1550    constexpr bool
1551    operator!=(const tuple<_TElements...>& __t,
1552	       const tuple<_UElements...>& __u)
1553    { return !(__t == __u); }
1554
1555  template<typename... _TElements, typename... _UElements>
1556    constexpr bool
1557    operator>(const tuple<_TElements...>& __t,
1558	      const tuple<_UElements...>& __u)
1559    { return __u < __t; }
1560
1561  template<typename... _TElements, typename... _UElements>
1562    constexpr bool
1563    operator<=(const tuple<_TElements...>& __t,
1564	       const tuple<_UElements...>& __u)
1565    { return !(__u < __t); }
1566
1567  template<typename... _TElements, typename... _UElements>
1568    constexpr bool
1569    operator>=(const tuple<_TElements...>& __t,
1570	       const tuple<_UElements...>& __u)
1571    { return !(__t < __u); }
1572#endif // three_way_comparison
1573
1574  // NB: DR 705.
1575  template<typename... _Elements>
1576    constexpr tuple<typename __decay_and_strip<_Elements>::__type...>
1577    make_tuple(_Elements&&... __args)
1578    {
1579      typedef tuple<typename __decay_and_strip<_Elements>::__type...>
1580	__result_type;
1581      return __result_type(std::forward<_Elements>(__args)...);
1582    }
1583
1584  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1585  // 2275. Why is forward_as_tuple not constexpr?
1586  /// std::forward_as_tuple
1587  template<typename... _Elements>
1588    constexpr tuple<_Elements&&...>
1589    forward_as_tuple(_Elements&&... __args) noexcept
1590    { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
1591
1592  // Declarations of std::array and its std::get overloads, so that
1593  // std::tuple_cat can use them if <tuple> is included before <array>.
1594
1595  template<typename _Tp, size_t _Nm> struct array;
1596
1597  template<size_t _Int, typename _Tp, size_t _Nm>
1598    constexpr _Tp&
1599    get(array<_Tp, _Nm>&) noexcept;
1600
1601  template<size_t _Int, typename _Tp, size_t _Nm>
1602    constexpr _Tp&&
1603    get(array<_Tp, _Nm>&&) noexcept;
1604
1605  template<size_t _Int, typename _Tp, size_t _Nm>
1606    constexpr const _Tp&
1607    get(const array<_Tp, _Nm>&) noexcept;
1608
1609  template<size_t _Int, typename _Tp, size_t _Nm>
1610    constexpr const _Tp&&
1611    get(const array<_Tp, _Nm>&&) noexcept;
1612
1613
1614  template<size_t, typename, typename, size_t>
1615    struct __make_tuple_impl;
1616
1617  template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm>
1618    struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm>
1619    : __make_tuple_impl<_Idx + 1,
1620			tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>,
1621			_Tuple, _Nm>
1622    { };
1623
1624  template<size_t _Nm, typename _Tuple, typename... _Tp>
1625    struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm>
1626    {
1627      typedef tuple<_Tp...> __type;
1628    };
1629
1630  template<typename _Tuple>
1631    struct __do_make_tuple
1632    : __make_tuple_impl<0, tuple<>, _Tuple, tuple_size<_Tuple>::value>
1633    { };
1634
1635  // Returns the std::tuple equivalent of a tuple-like type.
1636  template<typename _Tuple>
1637    struct __make_tuple
1638    : public __do_make_tuple<__remove_cvref_t<_Tuple>>
1639    { };
1640
1641  // Combines several std::tuple's into a single one.
1642  template<typename...>
1643    struct __combine_tuples;
1644
1645  template<>
1646    struct __combine_tuples<>
1647    {
1648      typedef tuple<> __type;
1649    };
1650
1651  template<typename... _Ts>
1652    struct __combine_tuples<tuple<_Ts...>>
1653    {
1654      typedef tuple<_Ts...> __type;
1655    };
1656
1657  template<typename... _T1s, typename... _T2s, typename... _Rem>
1658    struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...>
1659    {
1660      typedef typename __combine_tuples<tuple<_T1s..., _T2s...>,
1661					_Rem...>::__type __type;
1662    };
1663
1664  // Computes the result type of tuple_cat given a set of tuple-like types.
1665  template<typename... _Tpls>
1666    struct __tuple_cat_result
1667    {
1668      typedef typename __combine_tuples
1669        <typename __make_tuple<_Tpls>::__type...>::__type __type;
1670    };
1671
1672  // Helper to determine the index set for the first tuple-like
1673  // type of a given set.
1674  template<typename...>
1675    struct __make_1st_indices;
1676
1677  template<>
1678    struct __make_1st_indices<>
1679    {
1680      typedef _Index_tuple<> __type;
1681    };
1682
1683  template<typename _Tp, typename... _Tpls>
1684    struct __make_1st_indices<_Tp, _Tpls...>
1685    {
1686      typedef typename _Build_index_tuple<tuple_size<
1687	typename remove_reference<_Tp>::type>::value>::__type __type;
1688    };
1689
1690  // Performs the actual concatenation by step-wise expanding tuple-like
1691  // objects into the elements,  which are finally forwarded into the
1692  // result tuple.
1693  template<typename _Ret, typename _Indices, typename... _Tpls>
1694    struct __tuple_concater;
1695
1696  template<typename _Ret, size_t... _Is, typename _Tp, typename... _Tpls>
1697    struct __tuple_concater<_Ret, _Index_tuple<_Is...>, _Tp, _Tpls...>
1698    {
1699      template<typename... _Us>
1700        static constexpr _Ret
1701        _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us)
1702        {
1703	  typedef typename __make_1st_indices<_Tpls...>::__type __idx;
1704	  typedef __tuple_concater<_Ret, __idx, _Tpls...>      __next;
1705	  return __next::_S_do(std::forward<_Tpls>(__tps)...,
1706			       std::forward<_Us>(__us)...,
1707			       std::get<_Is>(std::forward<_Tp>(__tp))...);
1708	}
1709    };
1710
1711  template<typename _Ret>
1712    struct __tuple_concater<_Ret, _Index_tuple<>>
1713    {
1714      template<typename... _Us>
1715	static constexpr _Ret
1716	_S_do(_Us&&... __us)
1717        {
1718	  return _Ret(std::forward<_Us>(__us)...);
1719	}
1720    };
1721
1722  template<typename... _Tps>
1723    struct __is_tuple_like_impl<tuple<_Tps...>> : true_type
1724    { };
1725
1726  /// tuple_cat
1727  template<typename... _Tpls, typename = typename
1728           enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type>
1729    constexpr auto
1730    tuple_cat(_Tpls&&... __tpls)
1731    -> typename __tuple_cat_result<_Tpls...>::__type
1732    {
1733      typedef typename __tuple_cat_result<_Tpls...>::__type __ret;
1734      typedef typename __make_1st_indices<_Tpls...>::__type __idx;
1735      typedef __tuple_concater<__ret, __idx, _Tpls...> __concater;
1736      return __concater::_S_do(std::forward<_Tpls>(__tpls)...);
1737    }
1738
1739  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1740  // 2301. Why is tie not constexpr?
1741  /// tie
1742  template<typename... _Elements>
1743    constexpr tuple<_Elements&...>
1744    tie(_Elements&... __args) noexcept
1745    { return tuple<_Elements&...>(__args...); }
1746
1747  /// swap
1748  template<typename... _Elements>
1749    _GLIBCXX20_CONSTEXPR
1750    inline
1751#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
1752    // Constrained free swap overload, see p0185r1
1753    typename enable_if<__and_<__is_swappable<_Elements>...>::value
1754      >::type
1755#else
1756    void
1757#endif
1758    swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
1759    noexcept(noexcept(__x.swap(__y)))
1760    { __x.swap(__y); }
1761
1762#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
1763  template<typename... _Elements>
1764    _GLIBCXX20_CONSTEXPR
1765    typename enable_if<!__and_<__is_swappable<_Elements>...>::value>::type
1766    swap(tuple<_Elements...>&, tuple<_Elements...>&) = delete;
1767#endif
1768
1769  // A class (and instance) which can be used in 'tie' when an element
1770  // of a tuple is not required.
1771  // _GLIBCXX14_CONSTEXPR
1772  // 2933. PR for LWG 2773 could be clearer
1773  struct _Swallow_assign
1774  {
1775    template<class _Tp>
1776      _GLIBCXX14_CONSTEXPR const _Swallow_assign&
1777      operator=(const _Tp&) const
1778      { return *this; }
1779  };
1780
1781  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1782  // 2773. Making std::ignore constexpr
1783  _GLIBCXX17_INLINE constexpr _Swallow_assign ignore{};
1784
1785  /// Partial specialization for tuples
1786  template<typename... _Types, typename _Alloc>
1787    struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { };
1788
1789  // See stl_pair.h...
1790  /** "piecewise construction" using a tuple of arguments for each member.
1791   *
1792   * @param __first Arguments for the first member of the pair.
1793   * @param __second Arguments for the second member of the pair.
1794   *
1795   * The elements of each tuple will be used as the constructor arguments
1796   * for the data members of the pair.
1797  */
1798  template<class _T1, class _T2>
1799    template<typename... _Args1, typename... _Args2>
1800      _GLIBCXX20_CONSTEXPR
1801      inline
1802      pair<_T1, _T2>::
1803      pair(piecewise_construct_t,
1804	   tuple<_Args1...> __first, tuple<_Args2...> __second)
1805      : pair(__first, __second,
1806	     typename _Build_index_tuple<sizeof...(_Args1)>::__type(),
1807	     typename _Build_index_tuple<sizeof...(_Args2)>::__type())
1808      { }
1809
1810  template<class _T1, class _T2>
1811    template<typename... _Args1, size_t... _Indexes1,
1812	     typename... _Args2, size_t... _Indexes2>
1813      _GLIBCXX20_CONSTEXPR inline
1814      pair<_T1, _T2>::
1815      pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2,
1816	   _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)
1817      : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...),
1818	second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
1819      { }
1820
1821#if __cplusplus >= 201703L
1822
1823  // Unpack a std::tuple into a type trait and use its value.
1824  // For cv std::tuple<_Up> the result is _Trait<_Tp, cv _Up...>::value.
1825  // For cv std::tuple<_Up>& the result is _Trait<_Tp, cv _Up&...>::value.
1826  // Otherwise the result is false (because we don't know if std::get throws).
1827  template<template<typename...> class _Trait, typename _Tp, typename _Tuple>
1828    inline constexpr bool __unpack_std_tuple = false;
1829
1830  template<template<typename...> class _Trait, typename _Tp, typename... _Up>
1831    inline constexpr bool __unpack_std_tuple<_Trait, _Tp, tuple<_Up...>>
1832      = _Trait<_Tp, _Up...>::value;
1833
1834  template<template<typename...> class _Trait, typename _Tp, typename... _Up>
1835    inline constexpr bool __unpack_std_tuple<_Trait, _Tp, tuple<_Up...>&>
1836      = _Trait<_Tp, _Up&...>::value;
1837
1838  template<template<typename...> class _Trait, typename _Tp, typename... _Up>
1839    inline constexpr bool __unpack_std_tuple<_Trait, _Tp, const tuple<_Up...>>
1840      = _Trait<_Tp, const _Up...>::value;
1841
1842  template<template<typename...> class _Trait, typename _Tp, typename... _Up>
1843    inline constexpr bool __unpack_std_tuple<_Trait, _Tp, const tuple<_Up...>&>
1844      = _Trait<_Tp, const _Up&...>::value;
1845
1846# define __cpp_lib_apply 201603L
1847
1848  template <typename _Fn, typename _Tuple, size_t... _Idx>
1849    constexpr decltype(auto)
1850    __apply_impl(_Fn&& __f, _Tuple&& __t, index_sequence<_Idx...>)
1851    {
1852      return std::__invoke(std::forward<_Fn>(__f),
1853			   std::get<_Idx>(std::forward<_Tuple>(__t))...);
1854    }
1855
1856  template <typename _Fn, typename _Tuple>
1857    constexpr decltype(auto)
1858    apply(_Fn&& __f, _Tuple&& __t)
1859    noexcept(__unpack_std_tuple<is_nothrow_invocable, _Fn, _Tuple>)
1860    {
1861      using _Indices
1862	= make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>;
1863      return std::__apply_impl(std::forward<_Fn>(__f),
1864			       std::forward<_Tuple>(__t),
1865			       _Indices{});
1866    }
1867
1868#define __cpp_lib_make_from_tuple  201606L
1869
1870  template <typename _Tp, typename _Tuple, size_t... _Idx>
1871    constexpr _Tp
1872    __make_from_tuple_impl(_Tuple&& __t, index_sequence<_Idx...>)
1873    { return _Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...); }
1874
1875  template <typename _Tp, typename _Tuple>
1876    constexpr _Tp
1877    make_from_tuple(_Tuple&& __t)
1878    noexcept(__unpack_std_tuple<is_nothrow_constructible, _Tp, _Tuple>)
1879    {
1880      return __make_from_tuple_impl<_Tp>(
1881        std::forward<_Tuple>(__t),
1882	make_index_sequence<tuple_size_v<remove_reference_t<_Tuple>>>{});
1883    }
1884#endif // C++17
1885
1886  /// @}
1887
1888_GLIBCXX_END_NAMESPACE_VERSION
1889} // namespace std
1890
1891#endif // C++11
1892
1893#endif // _GLIBCXX_TUPLE
1894