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