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