libstdc++
tuple
Go to the documentation of this file.
1 // <tuple> -*- C++ -*-
2 
3 // Copyright (C) 2007-2016 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)
233 
234  template<typename _UHead, typename... _UTails>
235  constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
236  : _Inherited(std::move
238  _Base(std::forward<_UHead>
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,
277  : _Inherited(__tag, __a,
279  _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
281 
282  template<typename _Alloc, typename _UHead, typename... _UTails>
283  _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
285  : _Inherited(__tag, __a, std::move
287  _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
288  std::forward<_UHead>
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>
324  _M_tail(*this) = std::move
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),
415 
416  template<typename _Alloc, typename _UHead>
417  _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
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  {
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  bool>::type = true>
956  constexpr tuple(_U1&& __a1, _U2&& __a2)
957  : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
958 
959  template<typename _U1, typename _U2, typename
960  enable_if<_TMC::template
961  _MoveConstructibleTuple<_U1, _U2>()
962  && !_TMC::template
963  _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
964  bool>::type = false>
965  explicit constexpr tuple(_U1&& __a1, _U2&& __a2)
966  : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
967 
968  constexpr tuple(const tuple&) = default;
969 
970  constexpr tuple(tuple&&) = default;
971 
972  template<typename _U1, typename _U2, typename
973  enable_if<_TMC::template
974  _ConstructibleTuple<_U1, _U2>()
975  && _TMC::template
976  _ImplicitlyConvertibleTuple<_U1, _U2>(),
977  bool>::type = true>
978  constexpr tuple(const tuple<_U1, _U2>& __in)
979  : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
980 
981  template<typename _U1, typename _U2, typename
982  enable_if<_TMC::template
983  _ConstructibleTuple<_U1, _U2>()
984  && !_TMC::template
985  _ImplicitlyConvertibleTuple<_U1, _U2>(),
986  bool>::type = false>
987  explicit constexpr tuple(const tuple<_U1, _U2>& __in)
988  : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
989 
990  template<typename _U1, typename _U2, typename
991  enable_if<_TMC::template
992  _MoveConstructibleTuple<_U1, _U2>()
993  && _TMC::template
994  _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
995  bool>::type = true>
996  constexpr tuple(tuple<_U1, _U2>&& __in)
997  : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
998 
999  template<typename _U1, typename _U2, typename
1000  enable_if<_TMC::template
1001  _MoveConstructibleTuple<_U1, _U2>()
1002  && !_TMC::template
1003  _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1004  bool>::type = false>
1005  explicit constexpr tuple(tuple<_U1, _U2>&& __in)
1006  : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
1007 
1008  template<typename _U1, typename _U2, typename
1009  enable_if<_TMC::template
1010  _ConstructibleTuple<_U1, _U2>()
1011  && _TMC::template
1012  _ImplicitlyConvertibleTuple<_U1, _U2>(),
1013  bool>::type = true>
1014  constexpr tuple(const pair<_U1, _U2>& __in)
1015  : _Inherited(__in.first, __in.second) { }
1016 
1017  template<typename _U1, typename _U2, typename
1018  enable_if<_TMC::template
1019  _ConstructibleTuple<_U1, _U2>()
1020  && !_TMC::template
1021  _ImplicitlyConvertibleTuple<_U1, _U2>(),
1022  bool>::type = false>
1023  explicit constexpr tuple(const pair<_U1, _U2>& __in)
1024  : _Inherited(__in.first, __in.second) { }
1025 
1026  template<typename _U1, typename _U2, typename
1027  enable_if<_TMC::template
1028  _MoveConstructibleTuple<_U1, _U2>()
1029  && _TMC::template
1030  _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1031  bool>::type = true>
1032  constexpr tuple(pair<_U1, _U2>&& __in)
1033  : _Inherited(std::forward<_U1>(__in.first),
1034  std::forward<_U2>(__in.second)) { }
1035 
1036  template<typename _U1, typename _U2, typename
1037  enable_if<_TMC::template
1038  _MoveConstructibleTuple<_U1, _U2>()
1039  && !_TMC::template
1040  _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1041  bool>::type = false>
1042  explicit constexpr tuple(pair<_U1, _U2>&& __in)
1043  : _Inherited(std::forward<_U1>(__in.first),
1044  std::forward<_U2>(__in.second)) { }
1045 
1046  // Allocator-extended constructors.
1047 
1048  template<typename _Alloc>
1049  tuple(allocator_arg_t __tag, const _Alloc& __a)
1050  : _Inherited(__tag, __a) { }
1051 
1052  template<typename _Alloc, typename _Dummy = void,
1053  typename enable_if<
1054  _TCC<_Dummy>::template
1055  _ConstructibleTuple<_T1, _T2>()
1056  && _TCC<_Dummy>::template
1057  _ImplicitlyConvertibleTuple<_T1, _T2>(),
1058  bool>::type=true>
1059 
1060  tuple(allocator_arg_t __tag, const _Alloc& __a,
1061  const _T1& __a1, const _T2& __a2)
1062  : _Inherited(__tag, __a, __a1, __a2) { }
1063 
1064  template<typename _Alloc, typename _Dummy = void,
1065  typename enable_if<
1066  _TCC<_Dummy>::template
1067  _ConstructibleTuple<_T1, _T2>()
1068  && !_TCC<_Dummy>::template
1069  _ImplicitlyConvertibleTuple<_T1, _T2>(),
1070  bool>::type=false>
1071 
1072  explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1073  const _T1& __a1, const _T2& __a2)
1074  : _Inherited(__tag, __a, __a1, __a2) { }
1075 
1076  template<typename _Alloc, typename _U1, typename _U2, typename
1077  enable_if<_TMC::template
1078  _MoveConstructibleTuple<_U1, _U2>()
1079  && _TMC::template
1080  _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1081  bool>::type = true>
1082  tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2)
1083  : _Inherited(__tag, __a, std::forward<_U1>(__a1),
1084  std::forward<_U2>(__a2)) { }
1085 
1086  template<typename _Alloc, typename _U1, typename _U2, typename
1087  enable_if<_TMC::template
1088  _MoveConstructibleTuple<_U1, _U2>()
1089  && !_TMC::template
1090  _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1091  bool>::type = false>
1092  explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1093  _U1&& __a1, _U2&& __a2)
1094  : _Inherited(__tag, __a, std::forward<_U1>(__a1),
1095  std::forward<_U2>(__a2)) { }
1096 
1097  template<typename _Alloc>
1098  tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
1099  : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
1100 
1101  template<typename _Alloc>
1102  tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
1103  : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
1104 
1105  template<typename _Alloc, typename _U1, typename _U2, typename
1106  enable_if<_TMC::template
1107  _ConstructibleTuple<_U1, _U2>()
1108  && _TMC::template
1109  _ImplicitlyConvertibleTuple<_U1, _U2>(),
1110  bool>::type = true>
1111  tuple(allocator_arg_t __tag, const _Alloc& __a,
1112  const tuple<_U1, _U2>& __in)
1113  : _Inherited(__tag, __a,
1114  static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
1115  { }
1116 
1117  template<typename _Alloc, typename _U1, typename _U2, typename
1118  enable_if<_TMC::template
1119  _ConstructibleTuple<_U1, _U2>()
1120  && !_TMC::template
1121  _ImplicitlyConvertibleTuple<_U1, _U2>(),
1122  bool>::type = false>
1123  explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1124  const tuple<_U1, _U2>& __in)
1125  : _Inherited(__tag, __a,
1126  static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
1127  { }
1128 
1129  template<typename _Alloc, typename _U1, typename _U2, typename
1130  enable_if<_TMC::template
1131  _MoveConstructibleTuple<_U1, _U2>()
1132  && _TMC::template
1133  _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1134  bool>::type = true>
1135  tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
1136  : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
1137  { }
1138 
1139  template<typename _Alloc, typename _U1, typename _U2, typename
1140  enable_if<_TMC::template
1141  _MoveConstructibleTuple<_U1, _U2>()
1142  && !_TMC::template
1143  _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1144  bool>::type = false>
1145  explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1146  tuple<_U1, _U2>&& __in)
1147  : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
1148  { }
1149 
1150  template<typename _Alloc, typename _U1, typename _U2, typename
1151  enable_if<_TMC::template
1152  _ConstructibleTuple<_U1, _U2>()
1153  && _TMC::template
1154  _ImplicitlyConvertibleTuple<_U1, _U2>(),
1155  bool>::type = true>
1156  tuple(allocator_arg_t __tag, const _Alloc& __a,
1157  const pair<_U1, _U2>& __in)
1158  : _Inherited(__tag, __a, __in.first, __in.second) { }
1159 
1160  template<typename _Alloc, typename _U1, typename _U2, typename
1161  enable_if<_TMC::template
1162  _ConstructibleTuple<_U1, _U2>()
1163  && !_TMC::template
1164  _ImplicitlyConvertibleTuple<_U1, _U2>(),
1165  bool>::type = false>
1166  explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1167  const pair<_U1, _U2>& __in)
1168  : _Inherited(__tag, __a, __in.first, __in.second) { }
1169 
1170  template<typename _Alloc, typename _U1, typename _U2, typename
1171  enable_if<_TMC::template
1172  _MoveConstructibleTuple<_U1, _U2>()
1173  && _TMC::template
1174  _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1175  bool>::type = true>
1176  tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
1177  : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
1178  std::forward<_U2>(__in.second)) { }
1179 
1180  template<typename _Alloc, typename _U1, typename _U2, typename
1181  enable_if<_TMC::template
1182  _MoveConstructibleTuple<_U1, _U2>()
1183  && !_TMC::template
1184  _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1185  bool>::type = false>
1186  explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1187  pair<_U1, _U2>&& __in)
1188  : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
1189  std::forward<_U2>(__in.second)) { }
1190 
1191  tuple&
1192  operator=(const tuple& __in)
1193  {
1194  static_cast<_Inherited&>(*this) = __in;
1195  return *this;
1196  }
1197 
1198  tuple&
1199  operator=(tuple&& __in)
1200  noexcept(is_nothrow_move_assignable<_Inherited>::value)
1201  {
1202  static_cast<_Inherited&>(*this) = std::move(__in);
1203  return *this;
1204  }
1205 
1206  template<typename _U1, typename _U2>
1207  tuple&
1208  operator=(const tuple<_U1, _U2>& __in)
1209  {
1210  static_cast<_Inherited&>(*this) = __in;
1211  return *this;
1212  }
1213 
1214  template<typename _U1, typename _U2>
1215  tuple&
1216  operator=(tuple<_U1, _U2>&& __in)
1217  {
1218  static_cast<_Inherited&>(*this) = std::move(__in);
1219  return *this;
1220  }
1221 
1222  template<typename _U1, typename _U2>
1223  tuple&
1224  operator=(const pair<_U1, _U2>& __in)
1225  {
1226  this->_M_head(*this) = __in.first;
1227  this->_M_tail(*this)._M_head(*this) = __in.second;
1228  return *this;
1229  }
1230 
1231  template<typename _U1, typename _U2>
1232  tuple&
1233  operator=(pair<_U1, _U2>&& __in)
1234  {
1235  this->_M_head(*this) = std::forward<_U1>(__in.first);
1236  this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second);
1237  return *this;
1238  }
1239 
1240  void
1241  swap(tuple& __in)
1242  noexcept(noexcept(__in._M_swap(__in)))
1243  { _Inherited::_M_swap(__in); }
1244  };
1245 
1246 
1247  /// class tuple_size
1248  template<typename... _Elements>
1249  struct tuple_size<tuple<_Elements...>>
1250  : public integral_constant<std::size_t, sizeof...(_Elements)> { };
1251 
1252 #if __cplusplus > 201402L
1253  template <typename _Tp>
1254  constexpr size_t tuple_size_v = tuple_size<_Tp>::value;
1255 #endif
1256 
1257  /**
1258  * Recursive case for tuple_element: strip off the first element in
1259  * the tuple and retrieve the (i-1)th element of the remaining tuple.
1260  */
1261  template<std::size_t __i, typename _Head, typename... _Tail>
1262  struct tuple_element<__i, tuple<_Head, _Tail...> >
1263  : tuple_element<__i - 1, tuple<_Tail...> > { };
1264 
1265  /**
1266  * Basis case for tuple_element: The first element is the one we're seeking.
1267  */
1268  template<typename _Head, typename... _Tail>
1269  struct tuple_element<0, tuple<_Head, _Tail...> >
1270  {
1271  typedef _Head type;
1272  };
1273 
1274  /**
1275  * Error case for tuple_element: invalid index.
1276  */
1277  template<size_t __i>
1278  struct tuple_element<__i, tuple<>>
1279  {
1280  static_assert(__i < tuple_size<tuple<>>::value,
1281  "tuple index is in range");
1282  };
1283 
1284  template<std::size_t __i, typename _Head, typename... _Tail>
1285  constexpr _Head&
1286  __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1288 
1289  template<std::size_t __i, typename _Head, typename... _Tail>
1290  constexpr const _Head&
1291  __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1293 
1294  /// Return a reference to the ith element of a tuple.
1295  template<std::size_t __i, typename... _Elements>
1296  constexpr __tuple_element_t<__i, tuple<_Elements...>>&
1297  get(tuple<_Elements...>& __t) noexcept
1298  { return std::__get_helper<__i>(__t); }
1299 
1300  /// Return a const reference to the ith element of a const tuple.
1301  template<std::size_t __i, typename... _Elements>
1302  constexpr const __tuple_element_t<__i, tuple<_Elements...>>&
1303  get(const tuple<_Elements...>& __t) noexcept
1304  { return std::__get_helper<__i>(__t); }
1305 
1306  /// Return an rvalue reference to the ith element of a tuple rvalue.
1307  template<std::size_t __i, typename... _Elements>
1308  constexpr __tuple_element_t<__i, tuple<_Elements...>>&&
1309  get(tuple<_Elements...>&& __t) noexcept
1310  {
1311  typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
1312  return std::forward<__element_type&&>(std::get<__i>(__t));
1313  }
1314 
1315 #if __cplusplus > 201103L
1316 
1317 #define __cpp_lib_tuples_by_type 201304
1318 
1319  template<typename _Head, size_t __i, typename... _Tail>
1320  constexpr _Head&
1321  __get_helper2(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1323 
1324  template<typename _Head, size_t __i, typename... _Tail>
1325  constexpr const _Head&
1326  __get_helper2(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1328 
1329  /// Return a reference to the unique element of type _Tp of a tuple.
1330  template <typename _Tp, typename... _Types>
1331  constexpr _Tp&
1332  get(tuple<_Types...>& __t) noexcept
1333  { return std::__get_helper2<_Tp>(__t); }
1334 
1335  /// Return a reference to the unique element of type _Tp of a tuple rvalue.
1336  template <typename _Tp, typename... _Types>
1337  constexpr _Tp&&
1338  get(tuple<_Types...>&& __t) noexcept
1339  { return std::forward<_Tp&&>(std::__get_helper2<_Tp>(__t)); }
1340 
1341  /// Return a const reference to the unique element of type _Tp of a tuple.
1342  template <typename _Tp, typename... _Types>
1343  constexpr const _Tp&
1344  get(const tuple<_Types...>& __t) noexcept
1345  { return std::__get_helper2<_Tp>(__t); }
1346 #endif
1347 
1348  // This class performs the comparison operations on tuples
1349  template<typename _Tp, typename _Up, size_t __i, size_t __size>
1350  struct __tuple_compare
1351  {
1352  static constexpr bool
1353  __eq(const _Tp& __t, const _Up& __u)
1354  {
1355  return bool(std::get<__i>(__t) == std::get<__i>(__u))
1356  && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u);
1357  }
1358 
1359  static constexpr bool
1360  __less(const _Tp& __t, const _Up& __u)
1361  {
1362  return bool(std::get<__i>(__t) < std::get<__i>(__u))
1363  || (!bool(std::get<__i>(__u) < std::get<__i>(__t))
1364  && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u));
1365  }
1366  };
1367 
1368  template<typename _Tp, typename _Up, size_t __size>
1369  struct __tuple_compare<_Tp, _Up, __size, __size>
1370  {
1371  static constexpr bool
1372  __eq(const _Tp&, const _Up&) { return true; }
1373 
1374  static constexpr bool
1375  __less(const _Tp&, const _Up&) { return false; }
1376  };
1377 
1378  template<typename... _TElements, typename... _UElements>
1379  constexpr bool
1380  operator==(const tuple<_TElements...>& __t,
1381  const tuple<_UElements...>& __u)
1382  {
1383  static_assert(sizeof...(_TElements) == sizeof...(_UElements),
1384  "tuple objects can only be compared if they have equal sizes.");
1385  using __compare = __tuple_compare<tuple<_TElements...>,
1386  tuple<_UElements...>,
1387  0, sizeof...(_TElements)>;
1388  return __compare::__eq(__t, __u);
1389  }
1390 
1391  template<typename... _TElements, typename... _UElements>
1392  constexpr bool
1393  operator<(const tuple<_TElements...>& __t,
1394  const tuple<_UElements...>& __u)
1395  {
1396  static_assert(sizeof...(_TElements) == sizeof...(_UElements),
1397  "tuple objects can only be compared if they have equal sizes.");
1398  using __compare = __tuple_compare<tuple<_TElements...>,
1399  tuple<_UElements...>,
1400  0, sizeof...(_TElements)>;
1401  return __compare::__less(__t, __u);
1402  }
1403 
1404  template<typename... _TElements, typename... _UElements>
1405  constexpr bool
1406  operator!=(const tuple<_TElements...>& __t,
1407  const tuple<_UElements...>& __u)
1408  { return !(__t == __u); }
1409 
1410  template<typename... _TElements, typename... _UElements>
1411  constexpr bool
1412  operator>(const tuple<_TElements...>& __t,
1413  const tuple<_UElements...>& __u)
1414  { return __u < __t; }
1415 
1416  template<typename... _TElements, typename... _UElements>
1417  constexpr bool
1418  operator<=(const tuple<_TElements...>& __t,
1419  const tuple<_UElements...>& __u)
1420  { return !(__u < __t); }
1421 
1422  template<typename... _TElements, typename... _UElements>
1423  constexpr bool
1424  operator>=(const tuple<_TElements...>& __t,
1425  const tuple<_UElements...>& __u)
1426  { return !(__t < __u); }
1427 
1428  // NB: DR 705.
1429  template<typename... _Elements>
1431  make_tuple(_Elements&&... __args)
1432  {
1434  __result_type;
1435  return __result_type(std::forward<_Elements>(__args)...);
1436  }
1437 
1438  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1439  // 2275. Why is forward_as_tuple not constexpr?
1440  template<typename... _Elements>
1441  constexpr tuple<_Elements&&...>
1442  forward_as_tuple(_Elements&&... __args) noexcept
1443  { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
1444 
1445  template<typename... _Tps>
1446  struct __is_tuple_like_impl<tuple<_Tps...>> : true_type
1447  { };
1448 
1449  // Internal type trait that allows us to sfinae-protect tuple_cat.
1450  template<typename _Tp>
1451  struct __is_tuple_like
1452  : public __is_tuple_like_impl<typename std::remove_cv
1453  <typename std::remove_reference<_Tp>::type>::type>::type
1454  { };
1455 
1456  template<size_t, typename, typename, size_t>
1457  struct __make_tuple_impl;
1458 
1459  template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm>
1460  struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm>
1461  : __make_tuple_impl<_Idx + 1,
1462  tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>,
1463  _Tuple, _Nm>
1464  { };
1465 
1466  template<std::size_t _Nm, typename _Tuple, typename... _Tp>
1467  struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm>
1468  {
1469  typedef tuple<_Tp...> __type;
1470  };
1471 
1472  template<typename _Tuple>
1473  struct __do_make_tuple
1474  : __make_tuple_impl<0, tuple<>, _Tuple, std::tuple_size<_Tuple>::value>
1475  { };
1476 
1477  // Returns the std::tuple equivalent of a tuple-like type.
1478  template<typename _Tuple>
1479  struct __make_tuple
1480  : public __do_make_tuple<typename std::remove_cv
1481  <typename std::remove_reference<_Tuple>::type>::type>
1482  { };
1483 
1484  // Combines several std::tuple's into a single one.
1485  template<typename...>
1486  struct __combine_tuples;
1487 
1488  template<>
1489  struct __combine_tuples<>
1490  {
1491  typedef tuple<> __type;
1492  };
1493 
1494  template<typename... _Ts>
1495  struct __combine_tuples<tuple<_Ts...>>
1496  {
1497  typedef tuple<_Ts...> __type;
1498  };
1499 
1500  template<typename... _T1s, typename... _T2s, typename... _Rem>
1501  struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...>
1502  {
1503  typedef typename __combine_tuples<tuple<_T1s..., _T2s...>,
1504  _Rem...>::__type __type;
1505  };
1506 
1507  // Computes the result type of tuple_cat given a set of tuple-like types.
1508  template<typename... _Tpls>
1509  struct __tuple_cat_result
1510  {
1511  typedef typename __combine_tuples
1512  <typename __make_tuple<_Tpls>::__type...>::__type __type;
1513  };
1514 
1515  // Helper to determine the index set for the first tuple-like
1516  // type of a given set.
1517  template<typename...>
1518  struct __make_1st_indices;
1519 
1520  template<>
1521  struct __make_1st_indices<>
1522  {
1523  typedef std::_Index_tuple<> __type;
1524  };
1525 
1526  template<typename _Tp, typename... _Tpls>
1527  struct __make_1st_indices<_Tp, _Tpls...>
1528  {
1529  typedef typename std::_Build_index_tuple<std::tuple_size<
1530  typename std::remove_reference<_Tp>::type>::value>::__type __type;
1531  };
1532 
1533  // Performs the actual concatenation by step-wise expanding tuple-like
1534  // objects into the elements, which are finally forwarded into the
1535  // result tuple.
1536  template<typename _Ret, typename _Indices, typename... _Tpls>
1537  struct __tuple_concater;
1538 
1539  template<typename _Ret, std::size_t... _Is, typename _Tp, typename... _Tpls>
1540  struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...>
1541  {
1542  template<typename... _Us>
1543  static constexpr _Ret
1544  _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us)
1545  {
1546  typedef typename __make_1st_indices<_Tpls...>::__type __idx;
1547  typedef __tuple_concater<_Ret, __idx, _Tpls...> __next;
1548  return __next::_S_do(std::forward<_Tpls>(__tps)...,
1549  std::forward<_Us>(__us)...,
1550  std::get<_Is>(std::forward<_Tp>(__tp))...);
1551  }
1552  };
1553 
1554  template<typename _Ret>
1555  struct __tuple_concater<_Ret, std::_Index_tuple<>>
1556  {
1557  template<typename... _Us>
1558  static constexpr _Ret
1559  _S_do(_Us&&... __us)
1560  {
1561  return _Ret(std::forward<_Us>(__us)...);
1562  }
1563  };
1564 
1565  /// tuple_cat
1566  template<typename... _Tpls, typename = typename
1567  enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type>
1568  constexpr auto
1569  tuple_cat(_Tpls&&... __tpls)
1570  -> typename __tuple_cat_result<_Tpls...>::__type
1571  {
1572  typedef typename __tuple_cat_result<_Tpls...>::__type __ret;
1573  typedef typename __make_1st_indices<_Tpls...>::__type __idx;
1574  typedef __tuple_concater<__ret, __idx, _Tpls...> __concater;
1575  return __concater::_S_do(std::forward<_Tpls>(__tpls)...);
1576  }
1577 
1578  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1579  // 2301. Why is tie not constexpr?
1580  /// tie
1581  template<typename... _Elements>
1582  constexpr tuple<_Elements&...>
1583  tie(_Elements&... __args) noexcept
1584  { return tuple<_Elements&...>(__args...); }
1585 
1586  /// swap
1587  template<typename... _Elements>
1588  inline
1589 #if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
1590  // Constrained free swap overload, see p0185r1
1591  typename enable_if<__and_<__is_swappable<_Elements>...>::value
1592  >::type
1593 #else
1594  void
1595 #endif
1597  noexcept(noexcept(__x.swap(__y)))
1598  { __x.swap(__y); }
1599 
1600  // A class (and instance) which can be used in 'tie' when an element
1601  // of a tuple is not required
1602  struct _Swallow_assign
1603  {
1604  template<class _Tp>
1605  const _Swallow_assign&
1606  operator=(const _Tp&) const
1607  { return *this; }
1608  };
1609 
1610  const _Swallow_assign ignore{};
1611 
1612  /// Partial specialization for tuples
1613  template<typename... _Types, typename _Alloc>
1614  struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { };
1615 
1616  // See stl_pair.h...
1617  template<class _T1, class _T2>
1618  template<typename... _Args1, typename... _Args2>
1619  inline
1622  tuple<_Args1...> __first, tuple<_Args2...> __second)
1623  : pair(__first, __second,
1624  typename _Build_index_tuple<sizeof...(_Args1)>::__type(),
1625  typename _Build_index_tuple<sizeof...(_Args2)>::__type())
1626  { }
1627 
1628  template<class _T1, class _T2>
1629  template<typename... _Args1, std::size_t... _Indexes1,
1630  typename... _Args2, std::size_t... _Indexes2>
1631  inline
1633  pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2,
1634  _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)
1635  : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...),
1636  second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
1637  { }
1638 
1639 #if __cplusplus > 201402L
1640 # define __cpp_lib_apply 201603
1641 
1642  template <typename _Fn, typename _Tuple, size_t... _Idx>
1643  constexpr decltype(auto)
1644  __apply_impl(_Fn&& __f, _Tuple&& __t, index_sequence<_Idx...>)
1645  {
1646  return std::__invoke(std::forward<_Fn>(__f),
1647  std::get<_Idx>(std::forward<_Tuple>(__t))...);
1648  }
1649 
1650  template <typename _Fn, typename _Tuple>
1651  constexpr decltype(auto)
1652  apply(_Fn&& __f, _Tuple&& __t)
1653  {
1655  return std::__apply_impl(std::forward<_Fn>(__f),
1656  std::forward<_Tuple>(__t),
1657  _Indices{});
1658  }
1659 
1660 #define __cpp_lib_make_from_tuple 201606
1661 
1662  template <typename _Tp, typename _Tuple, size_t... _Idx>
1663  constexpr _Tp
1664  __make_from_tuple_impl(_Tuple&& __t, index_sequence<_Idx...>)
1665  { return _Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...); }
1666 
1667  template <typename _Tp, typename _Tuple>
1668  constexpr _Tp
1669  make_from_tuple(_Tuple&& __t)
1670  {
1671  return __make_from_tuple_impl<_Tp>(
1672  std::forward<_Tuple>(__t),
1673  make_index_sequence<tuple_size_v<decay_t<_Tuple>>>{});
1674  }
1675 #endif // C++17
1676 
1677  /// @}
1678 
1679 _GLIBCXX_END_NAMESPACE_VERSION
1680 } // namespace std
1681 
1682 #endif // C++11
1683 
1684 #endif // _GLIBCXX_TUPLE
_T2 second
first is a copy of the first object
Definition: stl_pair.h:196
piecewise_construct_t
Definition: stl_pair.h:76
ISO C++ entities toplevel namespace is std.
Class template integer_sequence.
Definition: utility:306
constexpr tuple< _Elements &... > tie(_Elements &... __args) noexcept
tie
Definition: tuple:1583
make_integer_sequence< size_t, _Num > make_index_sequence
Alias template make_index_sequence.
Definition: utility:336
constexpr auto tuple_cat(_Tpls &&... __tpls) -> typename __tuple_cat_result< _Tpls... >::__type
tuple_cat
Definition: tuple:1569
Declare uses_allocator so it can be specialized in <queue> etc.
Definition: memoryfwd.h:71
Struct holding two objects of arbitrary type.
Definition: stl_pair.h:190
tuple_size
Definition: array:328
constexpr pair()
second is a copy of the second object
Definition: stl_pair.h:210
integral_constant
Definition: type_traits:69
integral_constant< bool, false > false_type
The type used as a compile-time boolean with false value.
Definition: type_traits:90
constexpr _Tp && forward(typename std::remove_reference< _Tp >::type &__t) noexcept
Forward an lvalue.
Definition: move.h:73
[allocator.tag]
constexpr result_of< _Callable &&(_Args &&...)>::type __invoke(_Callable &&__fn, _Args &&... __args) noexcept(__is_nothrow_callable< _Callable &&(_Args &&...)>::value)
Invoke a callable object.
Definition: invoke.h:89
tuple_element
Definition: array:337
Primary class template, tuple.
Definition: tuple:53
is_empty
Definition: type_traits:707
_T1 first
second_type is the second bound type
Definition: stl_pair.h:195