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