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