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