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