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
42namespace 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    template<typename... _UElements>
504    static constexpr bool _NotSameTuple()
505    {
506      return  __not_<is_same<tuple<_Elements...>,
507			     typename remove_const<
508			       typename remove_reference<_UElements...>::type
509			       >::type>>::value;
510    }
511  };
512
513  template<typename... _Elements>
514  struct _TC<false, _Elements...>
515  {
516    template<typename... _UElements>
517    static constexpr bool _ConstructibleTuple()
518    {
519      return false;
520    }
521
522    template<typename... _UElements>
523    static constexpr bool _ImplicitlyConvertibleTuple()
524    {
525      return false;
526    }
527
528    template<typename... _UElements>
529    static constexpr bool _MoveConstructibleTuple()
530    {
531      return false;
532    }
533
534    template<typename... _UElements>
535    static constexpr bool _ImplicitlyMoveConvertibleTuple()
536    {
537      return false;
538    }
539
540    template<typename... _UElements>
541    static constexpr bool _NonNestedTuple()
542    {
543      return true;
544    }
545    template<typename... _UElements>
546    static constexpr bool _NotSameTuple()
547    {
548      return  true;
549    }
550  };
551
552  /// Primary class template, tuple
553  template<typename... _Elements>
554    class tuple : public _Tuple_impl<0, _Elements...>
555    {
556      typedef _Tuple_impl<0, _Elements...> _Inherited;
557
558      // Used for constraining the default constructor so
559      // that it becomes dependent on the constraints.
560      template<typename _Dummy>
561      struct _TC2
562      {
563        static constexpr bool _DefaultConstructibleTuple()
564        {
565          return __and_<is_default_constructible<_Elements>...>::value;
566        }
567        static constexpr bool _ImplicitlyDefaultConstructibleTuple()
568        {
569          return __and_<__is_implicitly_default_constructible<_Elements>...>
570            ::value;
571        }
572      };
573
574    public:
575      template<typename _Dummy = void,
576               typename enable_if<_TC2<_Dummy>::
577                                    _ImplicitlyDefaultConstructibleTuple(),
578                                  bool>::type = true>
579      constexpr tuple()
580      : _Inherited() { }
581
582      template<typename _Dummy = void,
583               typename enable_if<_TC2<_Dummy>::
584                                    _DefaultConstructibleTuple()
585                                  &&
586                                  !_TC2<_Dummy>::
587                                    _ImplicitlyDefaultConstructibleTuple(),
588                                  bool>::type = false>
589      explicit constexpr tuple()
590      : _Inherited() { }
591
592      // Shortcut for the cases where constructors taking _Elements...
593      // need to be constrained.
594      template<typename _Dummy> using _TCC =
595        _TC<is_same<_Dummy, void>::value,
596            _Elements...>;
597
598      template<typename _Dummy = void,
599               typename enable_if<
600                 _TCC<_Dummy>::template
601                   _ConstructibleTuple<_Elements...>()
602                 && _TCC<_Dummy>::template
603                   _ImplicitlyConvertibleTuple<_Elements...>()
604                 && (sizeof...(_Elements) >= 1),
605               bool>::type=true>
606        constexpr tuple(const _Elements&... __elements)
607      : _Inherited(__elements...) { }
608
609      template<typename _Dummy = void,
610               typename enable_if<
611                 _TCC<_Dummy>::template
612                   _ConstructibleTuple<_Elements...>()
613                 && !_TCC<_Dummy>::template
614                   _ImplicitlyConvertibleTuple<_Elements...>()
615                 && (sizeof...(_Elements) >= 1),
616               bool>::type=false>
617      explicit constexpr tuple(const _Elements&... __elements)
618      : _Inherited(__elements...) { }
619
620      // Shortcut for the cases where constructors taking _UElements...
621      // need to be constrained.
622      template<typename... _UElements> using _TMC =
623                  _TC<(sizeof...(_Elements) == sizeof...(_UElements)),
624                      _Elements...>;
625
626      template<typename... _UElements, typename
627	       enable_if<
628		  _TC<sizeof...(_UElements) == 1, _Elements...>::template
629		    _NotSameTuple<_UElements...>()
630		  && _TMC<_UElements...>::template
631                    _MoveConstructibleTuple<_UElements...>()
632                  && _TMC<_UElements...>::template
633                    _ImplicitlyMoveConvertibleTuple<_UElements...>()
634                  && (sizeof...(_Elements) >= 1),
635        bool>::type=true>
636        constexpr tuple(_UElements&&... __elements)
637        : _Inherited(std::forward<_UElements>(__elements)...) { }
638
639      template<typename... _UElements, typename
640        enable_if<
641		  _TC<sizeof...(_UElements) == 1, _Elements...>::template
642		    _NotSameTuple<_UElements...>()
643		  && _TMC<_UElements...>::template
644                    _MoveConstructibleTuple<_UElements...>()
645                  && !_TMC<_UElements...>::template
646                    _ImplicitlyMoveConvertibleTuple<_UElements...>()
647                  && (sizeof...(_Elements) >= 1),
648        bool>::type=false>
649        explicit constexpr tuple(_UElements&&... __elements)
650	: _Inherited(std::forward<_UElements>(__elements)...) {	}
651
652      constexpr tuple(const tuple&) = default;
653
654      constexpr tuple(tuple&&) = default;
655
656      // Shortcut for the cases where constructors taking tuples
657      // must avoid creating temporaries.
658      template<typename _Dummy> using _TNTC =
659        _TC<is_same<_Dummy, void>::value && sizeof...(_Elements) == 1,
660            _Elements...>;
661
662      template<typename... _UElements, typename _Dummy = void, typename
663        enable_if<_TMC<_UElements...>::template
664                    _ConstructibleTuple<_UElements...>()
665                  && _TMC<_UElements...>::template
666                    _ImplicitlyConvertibleTuple<_UElements...>()
667                  && _TNTC<_Dummy>::template
668                    _NonNestedTuple<const tuple<_UElements...>&>(),
669        bool>::type=true>
670        constexpr tuple(const tuple<_UElements...>& __in)
671        : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
672        { }
673
674      template<typename... _UElements, typename _Dummy = void, typename
675        enable_if<_TMC<_UElements...>::template
676                    _ConstructibleTuple<_UElements...>()
677                  && !_TMC<_UElements...>::template
678                    _ImplicitlyConvertibleTuple<_UElements...>()
679                  && _TNTC<_Dummy>::template
680                    _NonNestedTuple<const tuple<_UElements...>&>(),
681        bool>::type=false>
682        explicit constexpr tuple(const tuple<_UElements...>& __in)
683        : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
684        { }
685
686      template<typename... _UElements, typename _Dummy = void, typename
687        enable_if<_TMC<_UElements...>::template
688                    _MoveConstructibleTuple<_UElements...>()
689                  && _TMC<_UElements...>::template
690                    _ImplicitlyMoveConvertibleTuple<_UElements...>()
691                  && _TNTC<_Dummy>::template
692                    _NonNestedTuple<tuple<_UElements...>&&>(),
693        bool>::type=true>
694        constexpr tuple(tuple<_UElements...>&& __in)
695        : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
696
697      template<typename... _UElements, typename _Dummy = void, typename
698        enable_if<_TMC<_UElements...>::template
699                    _MoveConstructibleTuple<_UElements...>()
700                  && !_TMC<_UElements...>::template
701                    _ImplicitlyMoveConvertibleTuple<_UElements...>()
702                  && _TNTC<_Dummy>::template
703                    _NonNestedTuple<tuple<_UElements...>&&>(),
704        bool>::type=false>
705        explicit constexpr tuple(tuple<_UElements...>&& __in)
706        : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
707
708      // Allocator-extended constructors.
709
710      template<typename _Alloc>
711	tuple(allocator_arg_t __tag, const _Alloc& __a)
712	: _Inherited(__tag, __a) { }
713
714      template<typename _Alloc, typename _Dummy = void,
715               typename enable_if<
716                 _TCC<_Dummy>::template
717                   _ConstructibleTuple<_Elements...>()
718                 && _TCC<_Dummy>::template
719                   _ImplicitlyConvertibleTuple<_Elements...>(),
720               bool>::type=true>
721	tuple(allocator_arg_t __tag, const _Alloc& __a,
722	      const _Elements&... __elements)
723	: _Inherited(__tag, __a, __elements...) { }
724
725      template<typename _Alloc, typename _Dummy = void,
726               typename enable_if<
727                 _TCC<_Dummy>::template
728                   _ConstructibleTuple<_Elements...>()
729                 && !_TCC<_Dummy>::template
730                   _ImplicitlyConvertibleTuple<_Elements...>(),
731               bool>::type=false>
732	explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
733                       const _Elements&... __elements)
734	: _Inherited(__tag, __a, __elements...) { }
735
736      template<typename _Alloc, typename... _UElements, typename
737        enable_if<_TMC<_UElements...>::template
738                    _MoveConstructibleTuple<_UElements...>()
739                  && _TMC<_UElements...>::template
740                    _ImplicitlyMoveConvertibleTuple<_UElements...>(),
741        bool>::type=true>
742	tuple(allocator_arg_t __tag, const _Alloc& __a,
743	      _UElements&&... __elements)
744	: _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
745       	{ }
746
747      template<typename _Alloc, typename... _UElements, typename
748        enable_if<_TMC<_UElements...>::template
749                    _MoveConstructibleTuple<_UElements...>()
750                  && !_TMC<_UElements...>::template
751                    _ImplicitlyMoveConvertibleTuple<_UElements...>(),
752        bool>::type=false>
753	explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
754	      _UElements&&... __elements)
755	: _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
756        { }
757
758      template<typename _Alloc>
759	tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
760	: _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
761
762      template<typename _Alloc>
763	tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
764	: _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
765
766      template<typename _Alloc, typename... _UElements, typename
767        enable_if<_TMC<_UElements...>::template
768                    _ConstructibleTuple<_UElements...>()
769                  && _TMC<_UElements...>::template
770                    _ImplicitlyConvertibleTuple<_UElements...>(),
771        bool>::type=true>
772	tuple(allocator_arg_t __tag, const _Alloc& __a,
773	      const tuple<_UElements...>& __in)
774	: _Inherited(__tag, __a,
775	             static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
776	{ }
777
778      template<typename _Alloc, typename... _UElements, typename
779        enable_if<_TMC<_UElements...>::template
780                    _ConstructibleTuple<_UElements...>()
781                  && !_TMC<_UElements...>::template
782                    _ImplicitlyConvertibleTuple<_UElements...>(),
783        bool>::type=false>
784	explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
785	      const tuple<_UElements...>& __in)
786	: _Inherited(__tag, __a,
787	             static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
788	{ }
789
790      template<typename _Alloc, typename... _UElements, typename
791        enable_if<_TMC<_UElements...>::template
792                    _MoveConstructibleTuple<_UElements...>()
793                  && _TMC<_UElements...>::template
794                    _ImplicitlyMoveConvertibleTuple<_UElements...>(),
795        bool>::type=true>
796	tuple(allocator_arg_t __tag, const _Alloc& __a,
797	      tuple<_UElements...>&& __in)
798	: _Inherited(__tag, __a,
799	             static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
800	{ }
801
802      template<typename _Alloc, typename... _UElements, typename
803        enable_if<_TMC<_UElements...>::template
804                    _MoveConstructibleTuple<_UElements...>()
805                  && !_TMC<_UElements...>::template
806                    _ImplicitlyMoveConvertibleTuple<_UElements...>(),
807        bool>::type=false>
808	explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
809	      tuple<_UElements...>&& __in)
810	: _Inherited(__tag, __a,
811	             static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
812	{ }
813
814      tuple&
815      operator=(const tuple& __in)
816      {
817	static_cast<_Inherited&>(*this) = __in;
818	return *this;
819      }
820
821      tuple&
822      operator=(tuple&& __in)
823      noexcept(is_nothrow_move_assignable<_Inherited>::value)
824      {
825	static_cast<_Inherited&>(*this) = std::move(__in);
826	return *this;
827      }
828
829      template<typename... _UElements, typename = typename
830	       enable_if<sizeof...(_UElements)
831			 == sizeof...(_Elements)>::type>
832        tuple&
833        operator=(const tuple<_UElements...>& __in)
834        {
835	  static_cast<_Inherited&>(*this) = __in;
836	  return *this;
837	}
838
839      template<typename... _UElements, typename = typename
840	       enable_if<sizeof...(_UElements)
841			 == sizeof...(_Elements)>::type>
842        tuple&
843        operator=(tuple<_UElements...>&& __in)
844        {
845	  static_cast<_Inherited&>(*this) = std::move(__in);
846	  return *this;
847	}
848
849      void
850      swap(tuple& __in)
851      noexcept(noexcept(__in._M_swap(__in)))
852      { _Inherited::_M_swap(__in); }
853    };
854
855  // Explicit specialization, zero-element tuple.
856  template<>
857    class tuple<>
858    {
859    public:
860      void swap(tuple&) noexcept { /* no-op */ }
861    };
862
863  /// Partial specialization, 2-element tuple.
864  /// Includes construction and assignment from a pair.
865  template<typename _T1, typename _T2>
866    class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
867    {
868      typedef _Tuple_impl<0, _T1, _T2> _Inherited;
869
870    public:
871      template <typename _U1 = _T1,
872                typename _U2 = _T2,
873                typename enable_if<__and_<
874                                     __is_implicitly_default_constructible<_U1>,
875                                     __is_implicitly_default_constructible<_U2>>
876                                   ::value, bool>::type = true>
877
878      constexpr tuple()
879      : _Inherited() { }
880
881      template <typename _U1 = _T1,
882                typename _U2 = _T2,
883                typename enable_if<
884                  __and_<
885                    is_default_constructible<_U1>,
886                    is_default_constructible<_U2>,
887                    __not_<
888                      __and_<__is_implicitly_default_constructible<_U1>,
889                             __is_implicitly_default_constructible<_U2>>>>
890                  ::value, bool>::type = false>
891
892      explicit constexpr tuple()
893      : _Inherited() { }
894
895      // Shortcut for the cases where constructors taking _T1, _T2
896      // need to be constrained.
897      template<typename _Dummy> using _TCC =
898        _TC<is_same<_Dummy, void>::value, _T1, _T2>;
899
900      template<typename _Dummy = void, typename
901               enable_if<_TCC<_Dummy>::template
902                           _ConstructibleTuple<_T1, _T2>()
903                         && _TCC<_Dummy>::template
904                           _ImplicitlyConvertibleTuple<_T1, _T2>(),
905	bool>::type = true>
906        constexpr tuple(const _T1& __a1, const _T2& __a2)
907        : _Inherited(__a1, __a2) { }
908
909      template<typename _Dummy = void, typename
910               enable_if<_TCC<_Dummy>::template
911                           _ConstructibleTuple<_T1, _T2>()
912                         && !_TCC<_Dummy>::template
913                           _ImplicitlyConvertibleTuple<_T1, _T2>(),
914	bool>::type = false>
915        explicit constexpr tuple(const _T1& __a1, const _T2& __a2)
916        : _Inherited(__a1, __a2) { }
917
918      // Shortcut for the cases where constructors taking _U1, _U2
919      // need to be constrained.
920      using _TMC = _TC<true, _T1, _T2>;
921
922      template<typename _U1, typename _U2, typename
923        enable_if<_TMC::template
924                    _MoveConstructibleTuple<_U1, _U2>()
925                  && _TMC::template
926                    _ImplicitlyMoveConvertibleTuple<_U1, _U2>()
927	          && !is_same<typename decay<_U1>::type,
928			      allocator_arg_t>::value,
929	bool>::type = true>
930        constexpr tuple(_U1&& __a1, _U2&& __a2)
931	: _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
932
933      template<typename _U1, typename _U2, typename
934        enable_if<_TMC::template
935                    _MoveConstructibleTuple<_U1, _U2>()
936                  && !_TMC::template
937                    _ImplicitlyMoveConvertibleTuple<_U1, _U2>()
938	          && !is_same<typename decay<_U1>::type,
939			      allocator_arg_t>::value,
940	bool>::type = false>
941        explicit constexpr tuple(_U1&& __a1, _U2&& __a2)
942	: _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
943
944      constexpr tuple(const tuple&) = default;
945
946      constexpr tuple(tuple&&) = default;
947
948      template<typename _U1, typename _U2, typename
949        enable_if<_TMC::template
950                    _ConstructibleTuple<_U1, _U2>()
951                  && _TMC::template
952                    _ImplicitlyConvertibleTuple<_U1, _U2>(),
953	bool>::type = true>
954        constexpr tuple(const tuple<_U1, _U2>& __in)
955	: _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
956
957      template<typename _U1, typename _U2, typename
958        enable_if<_TMC::template
959                    _ConstructibleTuple<_U1, _U2>()
960                  && !_TMC::template
961                    _ImplicitlyConvertibleTuple<_U1, _U2>(),
962	bool>::type = false>
963        explicit constexpr tuple(const tuple<_U1, _U2>& __in)
964	: _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
965
966      template<typename _U1, typename _U2, typename
967        enable_if<_TMC::template
968                    _MoveConstructibleTuple<_U1, _U2>()
969                  && _TMC::template
970                    _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
971	bool>::type = true>
972        constexpr tuple(tuple<_U1, _U2>&& __in)
973	: _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
974
975      template<typename _U1, typename _U2, typename
976        enable_if<_TMC::template
977                    _MoveConstructibleTuple<_U1, _U2>()
978                  && !_TMC::template
979                    _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
980	bool>::type = false>
981        explicit constexpr tuple(tuple<_U1, _U2>&& __in)
982	: _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
983
984      template<typename _U1, typename _U2, typename
985        enable_if<_TMC::template
986                    _ConstructibleTuple<_U1, _U2>()
987                  && _TMC::template
988                    _ImplicitlyConvertibleTuple<_U1, _U2>(),
989	bool>::type = true>
990        constexpr tuple(const pair<_U1, _U2>& __in)
991	: _Inherited(__in.first, __in.second) { }
992
993      template<typename _U1, typename _U2, typename
994        enable_if<_TMC::template
995                    _ConstructibleTuple<_U1, _U2>()
996                  && !_TMC::template
997                    _ImplicitlyConvertibleTuple<_U1, _U2>(),
998	bool>::type = false>
999        explicit constexpr tuple(const pair<_U1, _U2>& __in)
1000	: _Inherited(__in.first, __in.second) { }
1001
1002      template<typename _U1, typename _U2, typename
1003        enable_if<_TMC::template
1004                    _MoveConstructibleTuple<_U1, _U2>()
1005                  && _TMC::template
1006                    _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1007	bool>::type = true>
1008        constexpr tuple(pair<_U1, _U2>&& __in)
1009	: _Inherited(std::forward<_U1>(__in.first),
1010		     std::forward<_U2>(__in.second)) { }
1011
1012      template<typename _U1, typename _U2, typename
1013        enable_if<_TMC::template
1014                    _MoveConstructibleTuple<_U1, _U2>()
1015                  && !_TMC::template
1016                    _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1017	bool>::type = false>
1018        explicit constexpr tuple(pair<_U1, _U2>&& __in)
1019	: _Inherited(std::forward<_U1>(__in.first),
1020		     std::forward<_U2>(__in.second)) { }
1021
1022      // Allocator-extended constructors.
1023
1024      template<typename _Alloc>
1025	tuple(allocator_arg_t __tag, const _Alloc& __a)
1026	: _Inherited(__tag, __a) { }
1027
1028      template<typename _Alloc, typename _Dummy = void,
1029               typename enable_if<
1030                 _TCC<_Dummy>::template
1031                   _ConstructibleTuple<_T1, _T2>()
1032                 && _TCC<_Dummy>::template
1033                   _ImplicitlyConvertibleTuple<_T1, _T2>(),
1034               bool>::type=true>
1035
1036	tuple(allocator_arg_t __tag, const _Alloc& __a,
1037	      const _T1& __a1, const _T2& __a2)
1038	: _Inherited(__tag, __a, __a1, __a2) { }
1039
1040      template<typename _Alloc, typename _Dummy = void,
1041               typename enable_if<
1042                 _TCC<_Dummy>::template
1043                   _ConstructibleTuple<_T1, _T2>()
1044                 && !_TCC<_Dummy>::template
1045                   _ImplicitlyConvertibleTuple<_T1, _T2>(),
1046               bool>::type=false>
1047
1048	explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1049	      const _T1& __a1, const _T2& __a2)
1050	: _Inherited(__tag, __a, __a1, __a2) { }
1051
1052      template<typename _Alloc, typename _U1, typename _U2, typename
1053        enable_if<_TMC::template
1054                    _MoveConstructibleTuple<_U1, _U2>()
1055                  && _TMC::template
1056                    _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1057	bool>::type = true>
1058	tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2)
1059	: _Inherited(__tag, __a, std::forward<_U1>(__a1),
1060	             std::forward<_U2>(__a2)) { }
1061
1062      template<typename _Alloc, typename _U1, typename _U2, typename
1063        enable_if<_TMC::template
1064                    _MoveConstructibleTuple<_U1, _U2>()
1065                  && !_TMC::template
1066                    _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1067	bool>::type = false>
1068	explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1069                       _U1&& __a1, _U2&& __a2)
1070	: _Inherited(__tag, __a, std::forward<_U1>(__a1),
1071	             std::forward<_U2>(__a2)) { }
1072
1073      template<typename _Alloc>
1074	tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
1075	: _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
1076
1077      template<typename _Alloc>
1078	tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
1079	: _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
1080
1081      template<typename _Alloc, typename _U1, typename _U2, typename
1082        enable_if<_TMC::template
1083                    _ConstructibleTuple<_U1, _U2>()
1084                  && _TMC::template
1085                    _ImplicitlyConvertibleTuple<_U1, _U2>(),
1086	bool>::type = true>
1087	tuple(allocator_arg_t __tag, const _Alloc& __a,
1088	      const tuple<_U1, _U2>& __in)
1089	: _Inherited(__tag, __a,
1090	             static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
1091	{ }
1092
1093      template<typename _Alloc, typename _U1, typename _U2, typename
1094        enable_if<_TMC::template
1095                    _ConstructibleTuple<_U1, _U2>()
1096                  && !_TMC::template
1097                    _ImplicitlyConvertibleTuple<_U1, _U2>(),
1098	bool>::type = false>
1099	explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1100	      const tuple<_U1, _U2>& __in)
1101	: _Inherited(__tag, __a,
1102	             static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
1103	{ }
1104
1105      template<typename _Alloc, typename _U1, typename _U2, typename
1106        enable_if<_TMC::template
1107                    _MoveConstructibleTuple<_U1, _U2>()
1108                  && _TMC::template
1109                    _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1110	bool>::type = true>
1111	tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
1112	: _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
1113	{ }
1114
1115      template<typename _Alloc, typename _U1, typename _U2, typename
1116        enable_if<_TMC::template
1117                    _MoveConstructibleTuple<_U1, _U2>()
1118                  && !_TMC::template
1119                    _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1120	bool>::type = false>
1121	explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1122                       tuple<_U1, _U2>&& __in)
1123	: _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
1124	{ }
1125
1126      template<typename _Alloc, typename _U1, typename _U2, typename
1127        enable_if<_TMC::template
1128                    _ConstructibleTuple<_U1, _U2>()
1129                  && _TMC::template
1130                    _ImplicitlyConvertibleTuple<_U1, _U2>(),
1131	bool>::type = true>
1132        tuple(allocator_arg_t __tag, const _Alloc& __a,
1133	      const pair<_U1, _U2>& __in)
1134	: _Inherited(__tag, __a, __in.first, __in.second) { }
1135
1136      template<typename _Alloc, typename _U1, typename _U2, typename
1137        enable_if<_TMC::template
1138                    _ConstructibleTuple<_U1, _U2>()
1139                  && !_TMC::template
1140                    _ImplicitlyConvertibleTuple<_U1, _U2>(),
1141	bool>::type = false>
1142        explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1143	      const pair<_U1, _U2>& __in)
1144	: _Inherited(__tag, __a, __in.first, __in.second) { }
1145
1146      template<typename _Alloc, typename _U1, typename _U2, typename
1147        enable_if<_TMC::template
1148                    _MoveConstructibleTuple<_U1, _U2>()
1149                  && _TMC::template
1150                    _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1151	bool>::type = true>
1152        tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
1153	: _Inherited(__tag, __a, std::forward<_U1>(__in.first),
1154		     std::forward<_U2>(__in.second)) { }
1155
1156      template<typename _Alloc, typename _U1, typename _U2, typename
1157        enable_if<_TMC::template
1158                    _MoveConstructibleTuple<_U1, _U2>()
1159                  && !_TMC::template
1160                    _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
1161	bool>::type = false>
1162        explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
1163                       pair<_U1, _U2>&& __in)
1164	: _Inherited(__tag, __a, std::forward<_U1>(__in.first),
1165		     std::forward<_U2>(__in.second)) { }
1166
1167      tuple&
1168      operator=(const tuple& __in)
1169      {
1170	static_cast<_Inherited&>(*this) = __in;
1171	return *this;
1172      }
1173
1174      tuple&
1175      operator=(tuple&& __in)
1176      noexcept(is_nothrow_move_assignable<_Inherited>::value)
1177      {
1178	static_cast<_Inherited&>(*this) = std::move(__in);
1179	return *this;
1180      }
1181
1182      template<typename _U1, typename _U2>
1183        tuple&
1184        operator=(const tuple<_U1, _U2>& __in)
1185        {
1186	  static_cast<_Inherited&>(*this) = __in;
1187	  return *this;
1188	}
1189
1190      template<typename _U1, typename _U2>
1191        tuple&
1192        operator=(tuple<_U1, _U2>&& __in)
1193        {
1194	  static_cast<_Inherited&>(*this) = std::move(__in);
1195	  return *this;
1196	}
1197
1198      template<typename _U1, typename _U2>
1199        tuple&
1200        operator=(const pair<_U1, _U2>& __in)
1201        {
1202	  this->_M_head(*this) = __in.first;
1203	  this->_M_tail(*this)._M_head(*this) = __in.second;
1204	  return *this;
1205	}
1206
1207      template<typename _U1, typename _U2>
1208        tuple&
1209        operator=(pair<_U1, _U2>&& __in)
1210        {
1211	  this->_M_head(*this) = std::forward<_U1>(__in.first);
1212	  this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second);
1213	  return *this;
1214	}
1215
1216      void
1217      swap(tuple& __in)
1218      noexcept(noexcept(__in._M_swap(__in)))
1219      { _Inherited::_M_swap(__in); }
1220    };
1221
1222
1223  /**
1224   * Recursive case for tuple_element: strip off the first element in
1225   * the tuple and retrieve the (i-1)th element of the remaining tuple.
1226   */
1227  template<std::size_t __i, typename _Head, typename... _Tail>
1228    struct tuple_element<__i, tuple<_Head, _Tail...> >
1229    : tuple_element<__i - 1, tuple<_Tail...> > { };
1230
1231  /**
1232   * Basis case for tuple_element: The first element is the one we're seeking.
1233   */
1234  template<typename _Head, typename... _Tail>
1235    struct tuple_element<0, tuple<_Head, _Tail...> >
1236    {
1237      typedef _Head type;
1238    };
1239
1240  /// class tuple_size
1241  template<typename... _Elements>
1242    struct tuple_size<tuple<_Elements...>>
1243    : public integral_constant<std::size_t, sizeof...(_Elements)> { };
1244
1245  template<std::size_t __i, typename _Head, typename... _Tail>
1246    constexpr _Head&
1247    __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1248    { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
1249
1250  template<std::size_t __i, typename _Head, typename... _Tail>
1251    constexpr const _Head&
1252    __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1253    { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
1254
1255  /// Return a reference to the ith element of a tuple.
1256  template<std::size_t __i, typename... _Elements>
1257    constexpr __tuple_element_t<__i, tuple<_Elements...>>&
1258    get(tuple<_Elements...>& __t) noexcept
1259    { return std::__get_helper<__i>(__t); }
1260
1261  /// Return a const reference to the ith element of a const tuple.
1262  template<std::size_t __i, typename... _Elements>
1263    constexpr const __tuple_element_t<__i, tuple<_Elements...>>&
1264    get(const tuple<_Elements...>& __t) noexcept
1265    { return std::__get_helper<__i>(__t); }
1266
1267  /// Return an rvalue reference to the ith element of a tuple rvalue.
1268  template<std::size_t __i, typename... _Elements>
1269    constexpr __tuple_element_t<__i, tuple<_Elements...>>&&
1270    get(tuple<_Elements...>&& __t) noexcept
1271    {
1272      typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
1273      return std::forward<__element_type&&>(std::get<__i>(__t));
1274    }
1275
1276#if __cplusplus > 201103L
1277
1278#define __cpp_lib_tuples_by_type 201304
1279
1280  template<typename _Head, size_t __i, typename... _Tail>
1281    constexpr _Head&
1282    __get_helper2(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1283    { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
1284
1285  template<typename _Head, size_t __i, typename... _Tail>
1286    constexpr const _Head&
1287    __get_helper2(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
1288    { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
1289
1290  /// Return a reference to the unique element of type _Tp of a tuple.
1291  template <typename _Tp, typename... _Types>
1292    constexpr _Tp&
1293    get(tuple<_Types...>& __t) noexcept
1294    { return std::__get_helper2<_Tp>(__t); }
1295
1296  /// Return a reference to the unique element of type _Tp of a tuple rvalue.
1297  template <typename _Tp, typename... _Types>
1298    constexpr _Tp&&
1299    get(tuple<_Types...>&& __t) noexcept
1300    { return std::forward<_Tp&&>(std::__get_helper2<_Tp>(__t)); }
1301
1302  /// Return a const reference to the unique element of type _Tp of a tuple.
1303  template <typename _Tp, typename... _Types>
1304    constexpr const _Tp&
1305    get(const tuple<_Types...>& __t) noexcept
1306    { return std::__get_helper2<_Tp>(__t); }
1307#endif
1308
1309  // This class performs the comparison operations on tuples
1310  template<typename _Tp, typename _Up, size_t __i, size_t __size>
1311    struct __tuple_compare
1312    {
1313      static constexpr bool
1314      __eq(const _Tp& __t, const _Up& __u)
1315      {
1316	return bool(std::get<__i>(__t) == std::get<__i>(__u))
1317	  && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u);
1318      }
1319
1320      static constexpr bool
1321      __less(const _Tp& __t, const _Up& __u)
1322      {
1323	return bool(std::get<__i>(__t) < std::get<__i>(__u))
1324	  || (!bool(std::get<__i>(__u) < std::get<__i>(__t))
1325	      && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u));
1326      }
1327    };
1328
1329  template<typename _Tp, typename _Up, size_t __size>
1330    struct __tuple_compare<_Tp, _Up, __size, __size>
1331    {
1332      static constexpr bool
1333      __eq(const _Tp&, const _Up&) { return true; }
1334
1335      static constexpr bool
1336      __less(const _Tp&, const _Up&) { return false; }
1337    };
1338
1339  template<typename... _TElements, typename... _UElements>
1340    constexpr bool
1341    operator==(const tuple<_TElements...>& __t,
1342	       const tuple<_UElements...>& __u)
1343    {
1344      static_assert(sizeof...(_TElements) == sizeof...(_UElements),
1345	  "tuple objects can only be compared if they have equal sizes.");
1346      using __compare = __tuple_compare<tuple<_TElements...>,
1347					tuple<_UElements...>,
1348					0, sizeof...(_TElements)>;
1349      return __compare::__eq(__t, __u);
1350    }
1351
1352  template<typename... _TElements, typename... _UElements>
1353    constexpr bool
1354    operator<(const tuple<_TElements...>& __t,
1355	      const tuple<_UElements...>& __u)
1356    {
1357      static_assert(sizeof...(_TElements) == sizeof...(_UElements),
1358	  "tuple objects can only be compared if they have equal sizes.");
1359      using __compare = __tuple_compare<tuple<_TElements...>,
1360					tuple<_UElements...>,
1361					0, sizeof...(_TElements)>;
1362      return __compare::__less(__t, __u);
1363    }
1364
1365  template<typename... _TElements, typename... _UElements>
1366    constexpr bool
1367    operator!=(const tuple<_TElements...>& __t,
1368	       const tuple<_UElements...>& __u)
1369    { return !(__t == __u); }
1370
1371  template<typename... _TElements, typename... _UElements>
1372    constexpr bool
1373    operator>(const tuple<_TElements...>& __t,
1374	      const tuple<_UElements...>& __u)
1375    { return __u < __t; }
1376
1377  template<typename... _TElements, typename... _UElements>
1378    constexpr bool
1379    operator<=(const tuple<_TElements...>& __t,
1380	       const tuple<_UElements...>& __u)
1381    { return !(__u < __t); }
1382
1383  template<typename... _TElements, typename... _UElements>
1384    constexpr bool
1385    operator>=(const tuple<_TElements...>& __t,
1386	       const tuple<_UElements...>& __u)
1387    { return !(__t < __u); }
1388
1389  // NB: DR 705.
1390  template<typename... _Elements>
1391    constexpr tuple<typename __decay_and_strip<_Elements>::__type...>
1392    make_tuple(_Elements&&... __args)
1393    {
1394      typedef tuple<typename __decay_and_strip<_Elements>::__type...>
1395	__result_type;
1396      return __result_type(std::forward<_Elements>(__args)...);
1397    }
1398
1399  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1400  // 2275. Why is forward_as_tuple not constexpr?
1401  template<typename... _Elements>
1402    constexpr tuple<_Elements&&...>
1403    forward_as_tuple(_Elements&&... __args) noexcept
1404    { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
1405
1406  template<typename... _Tps>
1407    struct __is_tuple_like_impl<tuple<_Tps...>> : true_type
1408    { };
1409
1410  // Internal type trait that allows us to sfinae-protect tuple_cat.
1411  template<typename _Tp>
1412    struct __is_tuple_like
1413    : public __is_tuple_like_impl<typename std::remove_cv
1414            <typename std::remove_reference<_Tp>::type>::type>::type
1415    { };
1416
1417  template<size_t, typename, typename, size_t>
1418    struct __make_tuple_impl;
1419
1420  template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm>
1421    struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm>
1422    : __make_tuple_impl<_Idx + 1,
1423			tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>,
1424			_Tuple, _Nm>
1425    { };
1426
1427  template<std::size_t _Nm, typename _Tuple, typename... _Tp>
1428    struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm>
1429    {
1430      typedef tuple<_Tp...> __type;
1431    };
1432
1433  template<typename _Tuple>
1434    struct __do_make_tuple
1435    : __make_tuple_impl<0, tuple<>, _Tuple, std::tuple_size<_Tuple>::value>
1436    { };
1437
1438  // Returns the std::tuple equivalent of a tuple-like type.
1439  template<typename _Tuple>
1440    struct __make_tuple
1441    : public __do_make_tuple<typename std::remove_cv
1442            <typename std::remove_reference<_Tuple>::type>::type>
1443    { };
1444
1445  // Combines several std::tuple's into a single one.
1446  template<typename...>
1447    struct __combine_tuples;
1448
1449  template<>
1450    struct __combine_tuples<>
1451    {
1452      typedef tuple<> __type;
1453    };
1454
1455  template<typename... _Ts>
1456    struct __combine_tuples<tuple<_Ts...>>
1457    {
1458      typedef tuple<_Ts...> __type;
1459    };
1460
1461  template<typename... _T1s, typename... _T2s, typename... _Rem>
1462    struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...>
1463    {
1464      typedef typename __combine_tuples<tuple<_T1s..., _T2s...>,
1465					_Rem...>::__type __type;
1466    };
1467
1468  // Computes the result type of tuple_cat given a set of tuple-like types.
1469  template<typename... _Tpls>
1470    struct __tuple_cat_result
1471    {
1472      typedef typename __combine_tuples
1473        <typename __make_tuple<_Tpls>::__type...>::__type __type;
1474    };
1475
1476  // Helper to determine the index set for the first tuple-like
1477  // type of a given set.
1478  template<typename...>
1479    struct __make_1st_indices;
1480
1481  template<>
1482    struct __make_1st_indices<>
1483    {
1484      typedef std::_Index_tuple<> __type;
1485    };
1486
1487  template<typename _Tp, typename... _Tpls>
1488    struct __make_1st_indices<_Tp, _Tpls...>
1489    {
1490      typedef typename std::_Build_index_tuple<std::tuple_size<
1491	typename std::remove_reference<_Tp>::type>::value>::__type __type;
1492    };
1493
1494  // Performs the actual concatenation by step-wise expanding tuple-like
1495  // objects into the elements,  which are finally forwarded into the
1496  // result tuple.
1497  template<typename _Ret, typename _Indices, typename... _Tpls>
1498    struct __tuple_concater;
1499
1500  template<typename _Ret, std::size_t... _Is, typename _Tp, typename... _Tpls>
1501    struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...>
1502    {
1503      template<typename... _Us>
1504        static constexpr _Ret
1505        _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us)
1506        {
1507	  typedef typename __make_1st_indices<_Tpls...>::__type __idx;
1508	  typedef __tuple_concater<_Ret, __idx, _Tpls...>      __next;
1509	  return __next::_S_do(std::forward<_Tpls>(__tps)...,
1510			       std::forward<_Us>(__us)...,
1511			       std::get<_Is>(std::forward<_Tp>(__tp))...);
1512	}
1513    };
1514
1515  template<typename _Ret>
1516    struct __tuple_concater<_Ret, std::_Index_tuple<>>
1517    {
1518      template<typename... _Us>
1519	static constexpr _Ret
1520	_S_do(_Us&&... __us)
1521        {
1522	  return _Ret(std::forward<_Us>(__us)...);
1523	}
1524    };
1525
1526  /// tuple_cat
1527  template<typename... _Tpls, typename = typename
1528           enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type>
1529    constexpr auto
1530    tuple_cat(_Tpls&&... __tpls)
1531    -> typename __tuple_cat_result<_Tpls...>::__type
1532    {
1533      typedef typename __tuple_cat_result<_Tpls...>::__type __ret;
1534      typedef typename __make_1st_indices<_Tpls...>::__type __idx;
1535      typedef __tuple_concater<__ret, __idx, _Tpls...> __concater;
1536      return __concater::_S_do(std::forward<_Tpls>(__tpls)...);
1537    }
1538
1539  // _GLIBCXX_RESOLVE_LIB_DEFECTS
1540  // 2301. Why is tie not constexpr?
1541  /// tie
1542  template<typename... _Elements>
1543    constexpr tuple<_Elements&...>
1544    tie(_Elements&... __args) noexcept
1545    { return tuple<_Elements&...>(__args...); }
1546
1547  /// swap
1548  template<typename... _Elements>
1549    inline void
1550    swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
1551    noexcept(noexcept(__x.swap(__y)))
1552    { __x.swap(__y); }
1553
1554  // A class (and instance) which can be used in 'tie' when an element
1555  // of a tuple is not required
1556  struct _Swallow_assign
1557  {
1558    template<class _Tp>
1559      const _Swallow_assign&
1560      operator=(const _Tp&) const
1561      { return *this; }
1562  };
1563
1564  const _Swallow_assign ignore{};
1565
1566  /// Partial specialization for tuples
1567  template<typename... _Types, typename _Alloc>
1568    struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { };
1569
1570  // See stl_pair.h...
1571  template<class _T1, class _T2>
1572    template<typename... _Args1, typename... _Args2>
1573      inline
1574      pair<_T1, _T2>::
1575      pair(piecewise_construct_t,
1576	   tuple<_Args1...> __first, tuple<_Args2...> __second)
1577      : pair(__first, __second,
1578	     typename _Build_index_tuple<sizeof...(_Args1)>::__type(),
1579	     typename _Build_index_tuple<sizeof...(_Args2)>::__type())
1580      { }
1581
1582  template<class _T1, class _T2>
1583    template<typename... _Args1, std::size_t... _Indexes1,
1584             typename... _Args2, std::size_t... _Indexes2>
1585      inline
1586      pair<_T1, _T2>::
1587      pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2,
1588	   _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)
1589      : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...),
1590        second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
1591      { }
1592
1593  /// @}
1594
1595_GLIBCXX_END_NAMESPACE_VERSION
1596} // namespace std
1597
1598#endif // C++11
1599
1600#endif // _GLIBCXX_TUPLE
1601