LCOV - code coverage report
Current view: top level - usr/include/c++/6 - tuple (source / functions) Hit Total Coverage
Test: coverage.info Lines: 83 108 76.9 %
Date: 2018-11-15 08:49:49 Functions: 581 1907 30.5 %

          Line data    Source code
       1             : // <tuple> -*- C++ -*-
       2             : 
       3             : // Copyright (C) 2007-2016 Free Software Foundation, Inc.
       4             : //
       5             : // This file is part of the GNU ISO C++ Library.  This library is free
       6             : // software; you can redistribute it and/or modify it under the
       7             : // terms of the GNU General Public License as published by the
       8             : // Free Software Foundation; either version 3, or (at your option)
       9             : // any later version.
      10             : 
      11             : // This library is distributed in the hope that it will be useful,
      12             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             : // GNU General Public License for more details.
      15             : 
      16             : // Under Section 7 of GPL version 3, you are granted additional
      17             : // permissions described in the GCC Runtime Library Exception, version
      18             : // 3.1, as published by the Free Software Foundation.
      19             : 
      20             : // You should have received a copy of the GNU General Public License and
      21             : // a copy of the GCC Runtime Library Exception along with this program;
      22             : // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      23             : // <http://www.gnu.org/licenses/>.
      24             : 
      25             : /** @file include/tuple
      26             :  *  This is a Standard C++ Library header.
      27             :  */
      28             : 
      29             : #ifndef _GLIBCXX_TUPLE
      30             : #define _GLIBCXX_TUPLE 1
      31             : 
      32             : #pragma GCC system_header
      33             : 
      34             : #if __cplusplus < 201103L
      35             : # include <bits/c++0x_warning.h>
      36             : #else
      37             : 
      38             : #include <utility>
      39             : #include <array>
      40             : #include <bits/uses_allocator.h>
      41             : 
      42             : namespace std _GLIBCXX_VISIBILITY(default)
      43             : {
      44             : _GLIBCXX_BEGIN_NAMESPACE_VERSION
      45             : 
      46             :   /**
      47             :    *  @addtogroup utilities
      48             :    *  @{
      49             :    */
      50             : 
      51             :   template<std::size_t _Idx, typename _Head, bool _IsEmptyNotFinal>
      52             :     struct _Head_base;
      53             : 
      54             :   template<std::size_t _Idx, typename _Head>
      55             :     struct _Head_base<_Idx, _Head, true>
      56             :     : public _Head
      57             :     {
      58         187 :       constexpr _Head_base()
      59         187 :       : _Head() { }
      60             : 
      61          10 :       constexpr _Head_base(const _Head& __h)
      62          10 :       : _Head(__h) { }
      63             : 
      64             :       constexpr _Head_base(const _Head_base&) = default;
      65             :       constexpr _Head_base(_Head_base&&) = default;
      66             : 
      67             :       template<typename _UHead>
      68          10 :         constexpr _Head_base(_UHead&& __h)
      69          10 :         : _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          28 :       _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         429 :     struct _Head_base<_Idx, _Head, false>
     103             :     {
     104         367 :       constexpr _Head_base()
     105         367 :       : _M_head_impl() { }
     106             : 
     107         121 :       constexpr _Head_base(const _Head& __h)
     108         121 :       : _M_head_impl(__h) { }
     109             : 
     110          40 :       constexpr _Head_base(const _Head_base&) = default;
     111             :       constexpr _Head_base(_Head_base&&) = default;
     112             : 
     113             :       template<typename _UHead>
     114         126 :         constexpr _Head_base(_UHead&& __h)
     115         126 :         : _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         301 :       _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; }
     143             : 
     144             :       static constexpr const _Head&
     145         168 :       _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         354 :     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         272 :       _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
     191             : 
     192             :       static constexpr const _Head&
     193         154 :       _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
     194             : 
     195             :       static constexpr _Inherited&
     196          53 :       _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         321 :       constexpr _Tuple_impl()
     202         321 :       : _Inherited(), _Base() { }
     203             : 
     204             :       explicit 
     205           5 :       constexpr _Tuple_impl(const _Head& __head, const _Tail&... __tail)
     206           5 :       : _Inherited(__tail...), _Base(__head) { }
     207             : 
     208             :       template<typename _UHead, typename... _UTail, typename = typename
     209             :                enable_if<sizeof...(_Tail) == sizeof...(_UTail)>::type> 
     210             :         explicit
     211         159 :         constexpr _Tuple_impl(_UHead&& __head, _UTail&&... __tail)
     212           0 :         : _Inherited(std::forward<_UTail>(__tail)...),
     213         159 :           _Base(std::forward<_UHead>(__head)) { }
     214             : 
     215          46 :       constexpr _Tuple_impl(const _Tuple_impl&) = default;
     216             : 
     217             :       constexpr
     218          19 :       _Tuple_impl(_Tuple_impl&& __in)
     219             :       noexcept(__and_<is_nothrow_move_constructible<_Head>,
     220             :                       is_nothrow_move_constructible<_Inherited>>::value)
     221          19 :       : _Inherited(std::move(_M_tail(__in))), 
     222          19 :         _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           0 :         constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
     231             :         : _Inherited(std::move
     232           0 :                      (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
     233             :           _Base(std::forward<_UHead>
     234           0 :                 (_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          17 :       operator=(_Tuple_impl&& __in)
     296             :       noexcept(__and_<is_nothrow_move_assignable<_Head>,
     297             :                       is_nothrow_move_assignable<_Inherited>>::value)
     298             :       {
     299          17 :         _M_head(*this) = std::forward<_Head>(_M_head(__in));
     300          17 :         _M_tail(*this) = std::move(_M_tail(__in));
     301          17 :         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         113 :     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          57 :       _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
     347             : 
     348             :       static constexpr const _Head&
     349          14 :       _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
     350             : 
     351         233 :       constexpr _Tuple_impl()
     352         233 :       : _Base() { }
     353             : 
     354             :       explicit
     355           9 :       constexpr _Tuple_impl(const _Head& __head)
     356           9 :       : _Base(__head) { }
     357             : 
     358             :       template<typename _UHead>
     359             :         explicit
     360          61 :         constexpr _Tuple_impl(_UHead&& __head)
     361          61 :         : _Base(std::forward<_UHead>(__head)) { }
     362             : 
     363          12 :       constexpr _Tuple_impl(const _Tuple_impl&) = default;
     364             : 
     365             :       constexpr
     366          14 :       _Tuple_impl(_Tuple_impl&& __in)
     367             :       noexcept(is_nothrow_move_constructible<_Head>::value)
     368          14 :       : _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           0 :         constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in)
     376           0 :         : _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
     377           0 :         { }
     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           7 :       operator=(_Tuple_impl&& __in)
     427             :       noexcept(is_nothrow_move_assignable<_Head>::value)
     428             :       {
     429           7 :         _M_head(*this) = std::forward<_Head>(_M_head(__in));
     430           7 :         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         125 :     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          46 :       constexpr tuple()
     580          46 :       : _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           7 :         constexpr tuple(const _Elements&... __elements)
     607           7 :       : _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          61 :         constexpr tuple(_UElements&&... __elements)
     637          61 :         : _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          18 :       constexpr tuple(const tuple&) = default;
     653             : 
     654          12 :       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           0 :         constexpr tuple(tuple<_UElements...>&& __in)
     695           0 :         : _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           7 :       operator=(tuple&& __in)
     823             :       noexcept(is_nothrow_move_assignable<_Inherited>::value)
     824             :       {
     825           7 :         static_cast<_Inherited&>(*this) = std::move(__in);
     826           7 :         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           8 :     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         187 :       constexpr tuple()
     879         187 :       : _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           2 :         constexpr tuple(const _T1& __a1, const _T2& __a2)
     907           2 :         : _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           0 :         constexpr tuple(_U1&& __a1, _U2&& __a2)
     931           0 :         : _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           4 :       constexpr tuple(const tuple&) = default;
     945             : 
     946           2 :       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         248 :     __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
    1248         248 :     { 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         168 :     __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
    1253         168 :     { 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         248 :     get(tuple<_Elements...>& __t) noexcept
    1259         248 :     { 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         168 :     get(const tuple<_Elements...>& __t) noexcept
    1265         168 :     { 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           2 :     get(tuple<_Elements...>&& __t) noexcept
    1271             :     {
    1272             :       typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
    1273           2 :       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           0 :       __less(const _Tp& __t, const _Up& __u)
    1322             :       {
    1323           0 :         return bool(std::get<__i>(__t) < std::get<__i>(__u))
    1324           0 :           || (!bool(std::get<__i>(__u) < std::get<__i>(__t))
    1325           0 :               && __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           0 :       __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           0 :     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           0 :       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          49 :     make_tuple(_Elements&&... __args)
    1393             :     {
    1394             :       typedef tuple<typename __decay_and_strip<_Elements>::__type...>
    1395             :         __result_type;
    1396          49 :       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          14 :     forward_as_tuple(_Elements&&... __args) noexcept
    1404          14 :     { 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           0 :       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           0 :              typename _Build_index_tuple<sizeof...(_Args2)>::__type())
    1580           0 :       { }
    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           0 :       pair<_T1, _T2>::
    1587             :       pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2,
    1588             :            _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)
    1589           0 :       : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...),
    1590           0 :         second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
    1591           0 :       { }
    1592             : 
    1593             :   /// @}
    1594             : 
    1595             : _GLIBCXX_END_NAMESPACE_VERSION
    1596             : } // namespace std
    1597             : 
    1598             : #endif // C++11
    1599             : 
    1600             : #endif // _GLIBCXX_TUPLE

Generated by: LCOV version 1.13