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