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