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  // Explicit specialization, zero-element tuple.
876  template<>
877  class tuple<>
878  {
879  public:
880  void swap(tuple&) noexcept { /* no-op */ }
881  // We need the default since we're going to define no-op
882  // allocator constructors.
883  tuple() = default;
884  // No-op allocator constructors.
885  template<typename _Alloc>
886  tuple(allocator_arg_t, const _Alloc&) { }
887  template<typename _Alloc>
888  tuple(allocator_arg_t, const _Alloc&, const tuple&) { }
889  };
890 
891  /// Partial specialization, 2-element tuple.
892  /// Includes construction and assignment from a pair.
893  template<typename _T1, typename _T2>
894  class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
895  {
896  typedef _Tuple_impl<0, _T1, _T2> _Inherited;
897 
898  public:
899  template <typename _U1 = _T1,
900  typename _U2 = _T2,
901  typename enable_if<__and_<
902  __is_implicitly_default_constructible<_U1>,
903  __is_implicitly_default_constructible<_U2>>
904  ::value, bool>::type = true>
905 
906  constexpr tuple()
907  : _Inherited() { }
908 
909  template <typename _U1 = _T1,
910  typename _U2 = _T2,
911  typename enable_if<
912  __and_<
913  is_default_constructible<_U1>,
914  is_default_constructible<_U2>,
915  __not_<
916  __and_<__is_implicitly_default_constructible<_U1>,
917  __is_implicitly_default_constructible<_U2>>>>
918  ::value, bool>::type = false>
919 
920  explicit constexpr tuple()
921  : _Inherited() { }
922 
923  // Shortcut for the cases where constructors taking _T1, _T2
924  // need to be constrained.
925  template<typename _Dummy> using _TCC =
926  _TC<is_same<_Dummy, void>::value, _T1, _T2>;
927 
928  template<typename _Dummy = void, typename
929  enable_if<_TCC<_Dummy>::template
930  _ConstructibleTuple<_T1, _T2>()
931  && _TCC<_Dummy>::template
932  _ImplicitlyConvertibleTuple<_T1, _T2>(),
933  bool>::type = true>
934  constexpr tuple(const _T1& __a1, const _T2& __a2)
935  : _Inherited(__a1, __a2) { }
936 
937  template<typename _Dummy = void, typename
938  enable_if<_TCC<_Dummy>::template
939  _ConstructibleTuple<_T1, _T2>()
940  && !_TCC<_Dummy>::template
941  _ImplicitlyConvertibleTuple<_T1, _T2>(),
942  bool>::type = false>
943  explicit constexpr tuple(const _T1& __a1, const _T2& __a2)
944  : _Inherited(__a1, __a2) { }
945 
946  // Shortcut for the cases where constructors taking _U1, _U2
947  // need to be constrained.
948  using _TMC = _TC<true, _T1, _T2>;
949 
950  template<typename _U1, typename _U2, typename
951  enable_if<_TMC::template
952  _MoveConstructibleTuple<_U1, _U2>()
953  && _TMC::template
954  _ImplicitlyMoveConvertibleTuple<_U1, _U2>()
955  && !is_same<typename decay<_U1>::type,
956  allocator_arg_t>::value,
957  bool>::type = true>
958  constexpr tuple(_U1&& __a1, _U2&& __a2)
959  : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
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<typename decay<_U1>::type,
967  allocator_arg_t>::value,
968  bool>::type = false>
969  explicit constexpr tuple(_U1&& __a1, _U2&& __a2)
970  : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
971 
972  constexpr tuple(const tuple&) = default;
973 
974  constexpr tuple(tuple&&) = default;
975 
976  template<typename _U1, typename _U2, typename
977  enable_if<_TMC::template
978  _ConstructibleTuple<_U1, _U2>()
979  && _TMC::template
980  _ImplicitlyConvertibleTuple<_U1, _U2>(),
981  bool>::type = true>
982  constexpr tuple(const tuple<_U1, _U2>& __in)
983  : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
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 = false>
991  explicit 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  _MoveConstructibleTuple<_U1, _U2>()
997  && _TMC::template
998  _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
999  bool>::type = true>
1000  constexpr tuple(tuple<_U1, _U2>&& __in)
1001  : _Inherited(static_cast<_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 = false>
1009  explicit 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  _ConstructibleTuple<_U1, _U2>()
1015  && _TMC::template
1016  _ImplicitlyConvertibleTuple<_U1, _U2>(),
1017  bool>::type = true>
1018  constexpr tuple(const pair<_U1, _U2>& __in)
1019  : _Inherited(__in.first, __in.second) { }
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 = false>
1027  explicit 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  _MoveConstructibleTuple<_U1, _U2>()
1033  && _TMC::template
1034  _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1035  bool>::type = true>
1036  constexpr tuple(pair<_U1, _U2>&& __in)
1037  : _Inherited(std::forward<_U1>(__in.first),
1038  std::forward<_U2>(__in.second)) { }
1039 
1040  template<typename _U1, typename _U2, typename
1041  enable_if<_TMC::template
1042  _MoveConstructibleTuple<_U1, _U2>()
1043  && !_TMC::template
1044  _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1045  bool>::type = false>
1046  explicit constexpr tuple(pair<_U1, _U2>&& __in)
1047  : _Inherited(std::forward<_U1>(__in.first),
1048  std::forward<_U2>(__in.second)) { }
1049 
1050  // Allocator-extended constructors.
1051 
1052  template<typename _Alloc>
1053  tuple(allocator_arg_t __tag, const _Alloc& __a)
1054  : _Inherited(__tag, __a) { }
1055 
1056  template<typename _Alloc, typename _Dummy = void,
1057  typename enable_if<
1058  _TCC<_Dummy>::template
1059  _ConstructibleTuple<_T1, _T2>()
1060  && _TCC<_Dummy>::template
1061  _ImplicitlyConvertibleTuple<_T1, _T2>(),
1062  bool>::type=true>
1063 
1064  tuple(allocator_arg_t __tag, const _Alloc& __a,
1065  const _T1& __a1, const _T2& __a2)
1066  : _Inherited(__tag, __a, __a1, __a2) { }
1067 
1068  template<typename _Alloc, typename _Dummy = void,
1069  typename enable_if<
1070  _TCC<_Dummy>::template
1071  _ConstructibleTuple<_T1, _T2>()
1072  && !_TCC<_Dummy>::template
1073  _ImplicitlyConvertibleTuple<_T1, _T2>(),
1074  bool>::type=false>
1075 
1076  explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1077  const _T1& __a1, const _T2& __a2)
1078  : _Inherited(__tag, __a, __a1, __a2) { }
1079 
1080  template<typename _Alloc, typename _U1, typename _U2, typename
1081  enable_if<_TMC::template
1082  _MoveConstructibleTuple<_U1, _U2>()
1083  && _TMC::template
1084  _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1085  bool>::type = true>
1086  tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2)
1087  : _Inherited(__tag, __a, std::forward<_U1>(__a1),
1088  std::forward<_U2>(__a2)) { }
1089 
1090  template<typename _Alloc, typename _U1, typename _U2, typename
1091  enable_if<_TMC::template
1092  _MoveConstructibleTuple<_U1, _U2>()
1093  && !_TMC::template
1094  _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1095  bool>::type = false>
1096  explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1097  _U1&& __a1, _U2&& __a2)
1098  : _Inherited(__tag, __a, std::forward<_U1>(__a1),
1099  std::forward<_U2>(__a2)) { }
1100 
1101  template<typename _Alloc>
1102  tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
1103  : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
1104 
1105  template<typename _Alloc>
1106  tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
1107  : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
1108 
1109  template<typename _Alloc, typename _U1, typename _U2, typename
1110  enable_if<_TMC::template
1111  _ConstructibleTuple<_U1, _U2>()
1112  && _TMC::template
1113  _ImplicitlyConvertibleTuple<_U1, _U2>(),
1114  bool>::type = true>
1115  tuple(allocator_arg_t __tag, const _Alloc& __a,
1116  const tuple<_U1, _U2>& __in)
1117  : _Inherited(__tag, __a,
1118  static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
1119  { }
1120 
1121  template<typename _Alloc, typename _U1, typename _U2, typename
1122  enable_if<_TMC::template
1123  _ConstructibleTuple<_U1, _U2>()
1124  && !_TMC::template
1125  _ImplicitlyConvertibleTuple<_U1, _U2>(),
1126  bool>::type = false>
1127  explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1128  const tuple<_U1, _U2>& __in)
1129  : _Inherited(__tag, __a,
1130  static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
1131  { }
1132 
1133  template<typename _Alloc, typename _U1, typename _U2, typename
1134  enable_if<_TMC::template
1135  _MoveConstructibleTuple<_U1, _U2>()
1136  && _TMC::template
1137  _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1138  bool>::type = true>
1139  tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
1140  : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
1141  { }
1142 
1143  template<typename _Alloc, typename _U1, typename _U2, typename
1144  enable_if<_TMC::template
1145  _MoveConstructibleTuple<_U1, _U2>()
1146  && !_TMC::template
1147  _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1148  bool>::type = false>
1149  explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1150  tuple<_U1, _U2>&& __in)
1151  : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
1152  { }
1153 
1154  template<typename _Alloc, typename _U1, typename _U2, typename
1155  enable_if<_TMC::template
1156  _ConstructibleTuple<_U1, _U2>()
1157  && _TMC::template
1158  _ImplicitlyConvertibleTuple<_U1, _U2>(),
1159  bool>::type = true>
1160  tuple(allocator_arg_t __tag, const _Alloc& __a,
1161  const pair<_U1, _U2>& __in)
1162  : _Inherited(__tag, __a, __in.first, __in.second) { }
1163 
1164  template<typename _Alloc, typename _U1, typename _U2, typename
1165  enable_if<_TMC::template
1166  _ConstructibleTuple<_U1, _U2>()
1167  && !_TMC::template
1168  _ImplicitlyConvertibleTuple<_U1, _U2>(),
1169  bool>::type = false>
1170  explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1171  const pair<_U1, _U2>& __in)
1172  : _Inherited(__tag, __a, __in.first, __in.second) { }
1173 
1174  template<typename _Alloc, typename _U1, typename _U2, typename
1175  enable_if<_TMC::template
1176  _MoveConstructibleTuple<_U1, _U2>()
1177  && _TMC::template
1178  _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1179  bool>::type = true>
1180  tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
1181  : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
1182  std::forward<_U2>(__in.second)) { }
1183 
1184  template<typename _Alloc, typename _U1, typename _U2, typename
1185  enable_if<_TMC::template
1186  _MoveConstructibleTuple<_U1, _U2>()
1187  && !_TMC::template
1188  _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1189  bool>::type = false>
1190  explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1191  pair<_U1, _U2>&& __in)
1192  : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
1193  std::forward<_U2>(__in.second)) { }
1194 
1195  tuple&
1196  operator=(const tuple& __in)
1197  {
1198  static_cast<_Inherited&>(*this) = __in;
1199  return *this;
1200  }
1201 
1202  tuple&
1203  operator=(tuple&& __in)
1204  noexcept(is_nothrow_move_assignable<_Inherited>::value)
1205  {
1206  static_cast<_Inherited&>(*this) = std::move(__in);
1207  return *this;
1208  }
1209 
1210  template<typename _U1, typename _U2>
1211  tuple&
1212  operator=(const tuple<_U1, _U2>& __in)
1213  {
1214  static_cast<_Inherited&>(*this) = __in;
1215  return *this;
1216  }
1217 
1218  template<typename _U1, typename _U2>
1219  tuple&
1220  operator=(tuple<_U1, _U2>&& __in)
1221  {
1222  static_cast<_Inherited&>(*this) = std::move(__in);
1223  return *this;
1224  }
1225 
1226  template<typename _U1, typename _U2>
1227  tuple&
1228  operator=(const pair<_U1, _U2>& __in)
1229  {
1230  this->_M_head(*this) = __in.first;
1231  this->_M_tail(*this)._M_head(*this) = __in.second;
1232  return *this;
1233  }
1234 
1235  template<typename _U1, typename _U2>
1236  tuple&
1237  operator=(pair<_U1, _U2>&& __in)
1238  {
1239  this->_M_head(*this) = std::forward<_U1>(__in.first);
1240  this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second);
1241  return *this;
1242  }
1243 
1244  void
1245  swap(tuple& __in)
1246  noexcept(noexcept(__in._M_swap(__in)))
1247  { _Inherited::_M_swap(__in); }
1248  };
1249 
1250 
1251  /// class tuple_size
1252  template<typename... _Elements>
1253  struct tuple_size<tuple<_Elements...>>
1254  : public integral_constant<std::size_t, sizeof...(_Elements)> { };
1255 
1256 #if __cplusplus > 201402L
1257  template <typename _Tp>
1258  constexpr size_t tuple_size_v = tuple_size<_Tp>::value;
1259 #endif
1260 
1261  /**
1262  * Recursive case for tuple_element: strip off the first element in
1263  * the tuple and retrieve the (i-1)th element of the remaining tuple.
1264  */
1265  template<std::size_t __i, typename _Head, typename... _Tail>
1266  struct tuple_element<__i, tuple<_Head, _Tail...> >
1267  : tuple_element<__i - 1, tuple<_Tail...> > { };
1268 
1269  /**
1270  * Basis case for tuple_element: The first element is the one we're seeking.
1271  */
1272  template<typename _Head, typename... _Tail>
1273  struct tuple_element<0, tuple<_Head, _Tail...> >
1274  {
1275  typedef _Head type;
1276  };
1277 
1278  /**
1279  * Error case for tuple_element: invalid index.
1280  */
1281  template<size_t __i>
1282  struct tuple_element<__i, tuple<>>
1283  {
1284  static_assert(__i < tuple_size<tuple<>>::value,
1285  "tuple index is in range");
1286  };
1287 
1288  template<std::size_t __i, typename _Head, typename... _Tail>
1289  constexpr _Head&
1290  __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1291  { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
1292 
1293  template<std::size_t __i, typename _Head, typename... _Tail>
1294  constexpr const _Head&
1295  __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1296  { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
1297 
1298  /// Return a reference to the ith element of a tuple.
1299  template<std::size_t __i, typename... _Elements>
1300  constexpr __tuple_element_t<__i, tuple<_Elements...>>&
1301  get(tuple<_Elements...>& __t) noexcept
1302  { return std::__get_helper<__i>(__t); }
1303 
1304  /// Return a const reference to the ith element of a const tuple.
1305  template<std::size_t __i, typename... _Elements>
1306  constexpr const __tuple_element_t<__i, tuple<_Elements...>>&
1307  get(const tuple<_Elements...>& __t) noexcept
1308  { return std::__get_helper<__i>(__t); }
1309 
1310  /// Return an rvalue reference to the ith element of a tuple rvalue.
1311  template<std::size_t __i, typename... _Elements>
1312  constexpr __tuple_element_t<__i, tuple<_Elements...>>&&
1313  get(tuple<_Elements...>&& __t) noexcept
1314  {
1315  typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
1316  return std::forward<__element_type&&>(std::get<__i>(__t));
1317  }
1318 
1319 #if __cplusplus > 201103L
1320 
1321 #define __cpp_lib_tuples_by_type 201304
1322 
1323  template<typename _Head, size_t __i, typename... _Tail>
1324  constexpr _Head&
1325  __get_helper2(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1326  { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
1327 
1328  template<typename _Head, size_t __i, typename... _Tail>
1329  constexpr const _Head&
1330  __get_helper2(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1331  { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
1332 
1333  /// Return a reference to the unique element of type _Tp of a tuple.
1334  template <typename _Tp, typename... _Types>
1335  constexpr _Tp&
1336  get(tuple<_Types...>& __t) noexcept
1337  { return std::__get_helper2<_Tp>(__t); }
1338 
1339  /// Return a reference to the unique element of type _Tp of a tuple rvalue.
1340  template <typename _Tp, typename... _Types>
1341  constexpr _Tp&&
1342  get(tuple<_Types...>&& __t) noexcept
1343  { return std::forward<_Tp&&>(std::__get_helper2<_Tp>(__t)); }
1344 
1345  /// Return a const reference to the unique element of type _Tp of a tuple.
1346  template <typename _Tp, typename... _Types>
1347  constexpr const _Tp&
1348  get(const tuple<_Types...>& __t) noexcept
1349  { return std::__get_helper2<_Tp>(__t); }
1350 #endif
1351 
1352  // This class performs the comparison operations on tuples
1353  template<typename _Tp, typename _Up, size_t __i, size_t __size>
1354  struct __tuple_compare
1355  {
1356  static constexpr bool
1357  __eq(const _Tp& __t, const _Up& __u)
1358  {
1359  return bool(std::get<__i>(__t) == std::get<__i>(__u))
1360  && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u);
1361  }
1362 
1363  static constexpr bool
1364  __less(const _Tp& __t, const _Up& __u)
1365  {
1366  return bool(std::get<__i>(__t) < std::get<__i>(__u))
1367  || (!bool(std::get<__i>(__u) < std::get<__i>(__t))
1368  && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u));
1369  }
1370  };
1371 
1372  template<typename _Tp, typename _Up, size_t __size>
1373  struct __tuple_compare<_Tp, _Up, __size, __size>
1374  {
1375  static constexpr bool
1376  __eq(const _Tp&, const _Up&) { return true; }
1377 
1378  static constexpr bool
1379  __less(const _Tp&, const _Up&) { return false; }
1380  };
1381 
1382  template<typename... _TElements, typename... _UElements>
1383  constexpr bool
1384  operator==(const tuple<_TElements...>& __t,
1385  const tuple<_UElements...>& __u)
1386  {
1387  static_assert(sizeof...(_TElements) == sizeof...(_UElements),
1388  "tuple objects can only be compared if they have equal sizes.");
1389  using __compare = __tuple_compare<tuple<_TElements...>,
1390  tuple<_UElements...>,
1391  0, sizeof...(_TElements)>;
1392  return __compare::__eq(__t, __u);
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::__less(__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  { return !(__t == __u); }
1413 
1414  template<typename... _TElements, typename... _UElements>
1415  constexpr bool
1416  operator>(const tuple<_TElements...>& __t,
1417  const tuple<_UElements...>& __u)
1418  { return __u < __t; }
1419 
1420  template<typename... _TElements, typename... _UElements>
1421  constexpr bool
1422  operator<=(const tuple<_TElements...>& __t,
1423  const tuple<_UElements...>& __u)
1424  { return !(__u < __t); }
1425 
1426  template<typename... _TElements, typename... _UElements>
1427  constexpr bool
1428  operator>=(const tuple<_TElements...>& __t,
1429  const tuple<_UElements...>& __u)
1430  { return !(__t < __u); }
1431 
1432  // NB: DR 705.
1433  template<typename... _Elements>
1434  constexpr tuple<typename __decay_and_strip<_Elements>::__type...>
1435  make_tuple(_Elements&&... __args)
1436  {
1437  typedef tuple<typename __decay_and_strip<_Elements>::__type...>
1438  __result_type;
1439  return __result_type(std::forward<_Elements>(__args)...);
1440  }
1441 
1442  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1443  // 2275. Why is forward_as_tuple not constexpr?
1444  template<typename... _Elements>
1445  constexpr tuple<_Elements&&...>
1446  forward_as_tuple(_Elements&&... __args) noexcept
1447  { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
1448 
1449  template<size_t, typename, typename, size_t>
1450  struct __make_tuple_impl;
1451 
1452  template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm>
1453  struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm>
1454  : __make_tuple_impl<_Idx + 1,
1455  tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>,
1456  _Tuple, _Nm>
1457  { };
1458 
1459  template<std::size_t _Nm, typename _Tuple, typename... _Tp>
1460  struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm>
1461  {
1462  typedef tuple<_Tp...> __type;
1463  };
1464 
1465  template<typename _Tuple>
1466  struct __do_make_tuple
1467  : __make_tuple_impl<0, tuple<>, _Tuple, std::tuple_size<_Tuple>::value>
1468  { };
1469 
1470  // Returns the std::tuple equivalent of a tuple-like type.
1471  template<typename _Tuple>
1472  struct __make_tuple
1473  : public __do_make_tuple<typename std::remove_cv
1474  <typename std::remove_reference<_Tuple>::type>::type>
1475  { };
1476 
1477  // Combines several std::tuple's into a single one.
1478  template<typename...>
1479  struct __combine_tuples;
1480 
1481  template<>
1482  struct __combine_tuples<>
1483  {
1484  typedef tuple<> __type;
1485  };
1486 
1487  template<typename... _Ts>
1488  struct __combine_tuples<tuple<_Ts...>>
1489  {
1490  typedef tuple<_Ts...> __type;
1491  };
1492 
1493  template<typename... _T1s, typename... _T2s, typename... _Rem>
1494  struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...>
1495  {
1496  typedef typename __combine_tuples<tuple<_T1s..., _T2s...>,
1497  _Rem...>::__type __type;
1498  };
1499 
1500  // Computes the result type of tuple_cat given a set of tuple-like types.
1501  template<typename... _Tpls>
1502  struct __tuple_cat_result
1503  {
1504  typedef typename __combine_tuples
1505  <typename __make_tuple<_Tpls>::__type...>::__type __type;
1506  };
1507 
1508  // Helper to determine the index set for the first tuple-like
1509  // type of a given set.
1510  template<typename...>
1511  struct __make_1st_indices;
1512 
1513  template<>
1514  struct __make_1st_indices<>
1515  {
1516  typedef std::_Index_tuple<> __type;
1517  };
1518 
1519  template<typename _Tp, typename... _Tpls>
1520  struct __make_1st_indices<_Tp, _Tpls...>
1521  {
1522  typedef typename std::_Build_index_tuple<std::tuple_size<
1523  typename std::remove_reference<_Tp>::type>::value>::__type __type;
1524  };
1525 
1526  // Performs the actual concatenation by step-wise expanding tuple-like
1527  // objects into the elements, which are finally forwarded into the
1528  // result tuple.
1529  template<typename _Ret, typename _Indices, typename... _Tpls>
1530  struct __tuple_concater;
1531 
1532  template<typename _Ret, std::size_t... _Is, typename _Tp, typename... _Tpls>
1533  struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...>
1534  {
1535  template<typename... _Us>
1536  static constexpr _Ret
1537  _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us)
1538  {
1539  typedef typename __make_1st_indices<_Tpls...>::__type __idx;
1540  typedef __tuple_concater<_Ret, __idx, _Tpls...> __next;
1541  return __next::_S_do(std::forward<_Tpls>(__tps)...,
1542  std::forward<_Us>(__us)...,
1543  std::get<_Is>(std::forward<_Tp>(__tp))...);
1544  }
1545  };
1546 
1547  template<typename _Ret>
1548  struct __tuple_concater<_Ret, std::_Index_tuple<>>
1549  {
1550  template<typename... _Us>
1551  static constexpr _Ret
1552  _S_do(_Us&&... __us)
1553  {
1554  return _Ret(std::forward<_Us>(__us)...);
1555  }
1556  };
1557 
1558  /// tuple_cat
1559  template<typename... _Tpls, typename = typename
1560  enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type>
1561  constexpr auto
1562  tuple_cat(_Tpls&&... __tpls)
1563  -> typename __tuple_cat_result<_Tpls...>::__type
1564  {
1565  typedef typename __tuple_cat_result<_Tpls...>::__type __ret;
1566  typedef typename __make_1st_indices<_Tpls...>::__type __idx;
1567  typedef __tuple_concater<__ret, __idx, _Tpls...> __concater;
1568  return __concater::_S_do(std::forward<_Tpls>(__tpls)...);
1569  }
1570 
1571  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1572  // 2301. Why is tie not constexpr?
1573  /// tie
1574  template<typename... _Elements>
1575  constexpr tuple<_Elements&...>
1576  tie(_Elements&... __args) noexcept
1577  { return tuple<_Elements&...>(__args...); }
1578 
1579  /// swap
1580  template<typename... _Elements>
1581  inline
1582 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
1583  // Constrained free swap overload, see p0185r1
1584  typename enable_if<__and_<__is_swappable<_Elements>...>::value
1585  >::type
1586 #else
1587  void
1588 #endif
1589  swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
1590  noexcept(noexcept(__x.swap(__y)))
1591  { __x.swap(__y); }
1592 
1593 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
1594  template<typename... _Elements>
1595  typename enable_if<!__and_<__is_swappable<_Elements>...>::value>::type
1596  swap(tuple<_Elements...>&, tuple<_Elements...>&) = delete;
1597 #endif
1598 
1599  // A class (and instance) which can be used in 'tie' when an element
1600  // of a tuple is not required
1601  struct _Swallow_assign
1602  {
1603  template<class _Tp>
1604  const _Swallow_assign&
1605  operator=(const _Tp&) const
1606  { return *this; }
1607  };
1608 
1609  const _Swallow_assign ignore{};
1610 
1611  /// Partial specialization for tuples
1612  template<typename... _Types, typename _Alloc>
1613  struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { };
1614 
1615  // See stl_pair.h...
1616  template<class _T1, class _T2>
1617  template<typename... _Args1, typename... _Args2>
1618  inline
1619  pair<_T1, _T2>::
1620  pair(piecewise_construct_t,
1621  tuple<_Args1...> __first, tuple<_Args2...> __second)
1622  : pair(__first, __second,
1623  typename _Build_index_tuple<sizeof...(_Args1)>::__type(),
1624  typename _Build_index_tuple<sizeof...(_Args2)>::__type())
1625  { }
1626 
1627  template<class _T1, class _T2>
1628  template<typename... _Args1, std::size_t... _Indexes1,
1629  typename... _Args2, std::size_t... _Indexes2>
1630  inline
1631  pair<_T1, _T2>::
1632  pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2,
1633  _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)
1634  : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...),
1635  second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
1636  { }
1637 
1638 #if __cplusplus > 201402L
1639 # define __cpp_lib_apply 201603
1640 
1641  template <typename _Fn, typename _Tuple, size_t... _Idx>
1642  constexpr decltype(auto)
1643  __apply_impl(_Fn&& __f, _Tuple&& __t, index_sequence<_Idx...>)
1644  {
1645  return std::__invoke(std::forward<_Fn>(__f),
1646  std::get<_Idx>(std::forward<_Tuple>(__t))...);
1647  }
1648 
1649  template <typename _Fn, typename _Tuple>
1650  constexpr decltype(auto)
1651  apply(_Fn&& __f, _Tuple&& __t)
1652  {
1653  using _Indices = make_index_sequence<tuple_size_v<decay_t<_Tuple>>>;
1654  return std::__apply_impl(std::forward<_Fn>(__f),
1655  std::forward<_Tuple>(__t),
1656  _Indices{});
1657  }
1658 
1659 #define __cpp_lib_make_from_tuple 201606
1660 
1661  template <typename _Tp, typename _Tuple, size_t... _Idx>
1662  constexpr _Tp
1663  __make_from_tuple_impl(_Tuple&& __t, index_sequence<_Idx...>)
1664  { return _Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...); }
1665 
1666  template <typename _Tp, typename _Tuple>
1667  constexpr _Tp
1668  make_from_tuple(_Tuple&& __t)
1669  {
1670  return __make_from_tuple_impl<_Tp>(
1671  std::forward<_Tuple>(__t),
1672  make_index_sequence<tuple_size_v<decay_t<_Tuple>>>{});
1673  }
1674 #endif // C++17
1675 
1676  /// @}
1677 
1678 _GLIBCXX_END_NAMESPACE_VERSION
1679 } // namespace std
1680 
1681 #endif // C++11
1682 
1683 #endif // _GLIBCXX_TUPLE