LCOV - code coverage report
Current view: top level - usr/include/c++/4.9 - tuple (source / functions) Hit Total Coverage
Test: coverage.info Lines: 65 89 73.0 %
Date: 2016-09-12 13:07:23 Functions: 591 1797 32.9 %

          Line data    Source code
       1             : // <tuple> -*- C++ -*-
       2             : 
       3             : // Copyright (C) 2007-2014 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             :   // Adds a const reference to a non-reference type.
      52             :   template<typename _Tp>
      53             :     struct __add_c_ref
      54             :     { typedef const _Tp& type; };
      55             : 
      56             :   template<typename _Tp>
      57             :     struct __add_c_ref<_Tp&>
      58             :     { typedef _Tp& type; };
      59             : 
      60             :   // Adds a reference to a non-reference type.
      61             :   template<typename _Tp>
      62             :     struct __add_ref
      63             :     { typedef _Tp& type; };
      64             : 
      65             :   template<typename _Tp>
      66             :     struct __add_ref<_Tp&>
      67             :     { typedef _Tp& type; };
      68             : 
      69             :   // Adds an rvalue reference to a non-reference type.
      70             :   template<typename _Tp>
      71             :     struct __add_r_ref
      72             :     { typedef _Tp&& type; };
      73             : 
      74             :   template<typename _Tp>
      75             :     struct __add_r_ref<_Tp&>
      76             :     { typedef _Tp& type; };
      77             : 
      78             :   template<std::size_t _Idx, typename _Head, bool _IsEmptyNotFinal>
      79             :     struct _Head_base;
      80             : 
      81             :   template<std::size_t _Idx, typename _Head>
      82             :     struct _Head_base<_Idx, _Head, true>
      83             :     : public _Head
      84             :     {
      85         117 :       constexpr _Head_base()
      86         117 :       : _Head() { }
      87             : 
      88           8 :       constexpr _Head_base(const _Head& __h)
      89           8 :       : _Head(__h) { }
      90             : 
      91             :       constexpr _Head_base(const _Head_base&) = default;
      92             :       constexpr _Head_base(_Head_base&&) = default;
      93             : 
      94             :       template<typename _UHead>
      95          11 :         constexpr _Head_base(_UHead&& __h)
      96          11 :         : _Head(std::forward<_UHead>(__h)) { }
      97             : 
      98             :       _Head_base(allocator_arg_t, __uses_alloc0)
      99             :       : _Head() { }
     100             : 
     101             :       template<typename _Alloc>
     102             :         _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
     103             :         : _Head(allocator_arg, *__a._M_a) { }
     104             : 
     105             :       template<typename _Alloc>
     106             :         _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
     107             :         : _Head(*__a._M_a) { }
     108             : 
     109             :       template<typename _UHead>
     110             :         _Head_base(__uses_alloc0, _UHead&& __uhead)
     111             :         : _Head(std::forward<_UHead>(__uhead)) { }
     112             : 
     113             :       template<typename _Alloc, typename _UHead>
     114             :         _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
     115             :         : _Head(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { }
     116             : 
     117             :       template<typename _Alloc, typename _UHead>
     118             :         _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
     119             :         : _Head(std::forward<_UHead>(__uhead), *__a._M_a) { }
     120             : 
     121             :       static constexpr _Head&
     122          22 :       _M_head(_Head_base& __b) noexcept { return __b; }
     123             : 
     124             :       static constexpr const _Head&
     125             :       _M_head(const _Head_base& __b) noexcept { return __b; }
     126             :     };
     127             : 
     128             :   template<std::size_t _Idx, typename _Head>
     129         323 :     struct _Head_base<_Idx, _Head, false>
     130             :     {
     131         252 :       constexpr _Head_base()
     132         252 :       : _M_head_impl() { }
     133             : 
     134          90 :       constexpr _Head_base(const _Head& __h)
     135          90 :       : _M_head_impl(__h) { }
     136             : 
     137          37 :       constexpr _Head_base(const _Head_base&) = default;
     138             :       constexpr _Head_base(_Head_base&&) = default;
     139             : 
     140             :       template<typename _UHead>
     141          99 :         constexpr _Head_base(_UHead&& __h)
     142          99 :         : _M_head_impl(std::forward<_UHead>(__h)) { }
     143             : 
     144             :       _Head_base(allocator_arg_t, __uses_alloc0)
     145             :       : _M_head_impl() { }
     146             : 
     147             :       template<typename _Alloc>
     148             :         _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
     149             :         : _M_head_impl(allocator_arg, *__a._M_a) { }
     150             : 
     151             :       template<typename _Alloc>
     152             :         _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
     153             :         : _M_head_impl(*__a._M_a) { }
     154             : 
     155             :       template<typename _UHead>
     156             :         _Head_base(__uses_alloc0, _UHead&& __uhead)
     157             :         : _M_head_impl(std::forward<_UHead>(__uhead)) { }
     158             : 
     159             :       template<typename _Alloc, typename _UHead>
     160             :         _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
     161             :         : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead))
     162             :         { }
     163             : 
     164             :       template<typename _Alloc, typename _UHead>
     165             :         _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
     166             :         : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { }
     167             : 
     168             :       static constexpr _Head&
     169         221 :       _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; }
     170             : 
     171             :       static constexpr const _Head&
     172         124 :       _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; }
     173             : 
     174             :       _Head _M_head_impl;
     175             :     };
     176             : 
     177             :   /**
     178             :    * Contains the actual implementation of the @c tuple template, stored
     179             :    * as a recursive inheritance hierarchy from the first element (most
     180             :    * derived class) to the last (least derived class). The @c Idx
     181             :    * parameter gives the 0-based index of the element stored at this
     182             :    * point in the hierarchy; we use it to implement a constant-time
     183             :    * get() operation.
     184             :    */
     185             :   template<std::size_t _Idx, typename... _Elements>
     186             :     struct _Tuple_impl; 
     187             : 
     188             :   /**
     189             :    * Zero-element tuple implementation. This is the basis case for the 
     190             :    * inheritance recursion.
     191             :    */
     192             :   template<std::size_t _Idx>
     193             :     struct _Tuple_impl<_Idx>
     194             :     {
     195             :       template<std::size_t, typename...> friend class _Tuple_impl;
     196             : 
     197         206 :       _Tuple_impl() = default;
     198             : 
     199             :       template<typename _Alloc>
     200             :         _Tuple_impl(allocator_arg_t, const _Alloc&) { }
     201             : 
     202             :       template<typename _Alloc>
     203             :         _Tuple_impl(allocator_arg_t, const _Alloc&, const _Tuple_impl&) { }
     204             : 
     205             :       template<typename _Alloc>
     206             :         _Tuple_impl(allocator_arg_t, const _Alloc&, _Tuple_impl&&) { }
     207             : 
     208             :     protected:
     209             :       void _M_swap(_Tuple_impl&) noexcept { /* no-op */ }
     210             :     };
     211             : 
     212             :   template<typename _Tp>
     213             :     struct __is_empty_non_tuple : is_empty<_Tp> { };
     214             : 
     215             :   // Using EBO for elements that are tuples causes ambiguous base errors.
     216             :   template<typename _El0, typename... _El>
     217             :     struct __is_empty_non_tuple<tuple<_El0, _El...>> : false_type { };
     218             : 
     219             :   // Use the Empty Base-class Optimization for empty, non-final types.
     220             :   template<typename _Tp>
     221             :     using __empty_not_final
     222             :     = typename conditional<__is_final(_Tp), false_type,
     223             :                            __is_empty_non_tuple<_Tp>>::type;
     224             : 
     225             :   /**
     226             :    * Recursive tuple implementation. Here we store the @c Head element
     227             :    * and derive from a @c Tuple_impl containing the remaining elements
     228             :    * (which contains the @c Tail).
     229             :    */
     230             :   template<std::size_t _Idx, typename _Head, typename... _Tail>
     231         353 :     struct _Tuple_impl<_Idx, _Head, _Tail...>
     232             :     : public _Tuple_impl<_Idx + 1, _Tail...>,
     233             :       private _Head_base<_Idx, _Head, __empty_not_final<_Head>::value>
     234             :     {
     235             :       template<std::size_t, typename...> friend class _Tuple_impl;
     236             : 
     237             :       typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
     238             :       typedef _Head_base<_Idx, _Head, __empty_not_final<_Head>::value> _Base;
     239             : 
     240             :       static constexpr _Head&  
     241         243 :       _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
     242             : 
     243             :       static constexpr const _Head&
     244         124 :       _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
     245             : 
     246             :       static constexpr _Inherited&
     247          75 :       _M_tail(_Tuple_impl& __t) noexcept { return __t; }
     248             : 
     249             :       static constexpr const _Inherited&
     250             :       _M_tail(const _Tuple_impl& __t) noexcept { return __t; }
     251             : 
     252         369 :       constexpr _Tuple_impl()
     253         369 :       : _Inherited(), _Base() { }
     254             : 
     255             :       explicit 
     256          10 :       constexpr _Tuple_impl(const _Head& __head, const _Tail&... __tail)
     257          10 :       : _Inherited(__tail...), _Base(__head) { }
     258             : 
     259             :       template<typename _UHead, typename... _UTail, typename = typename
     260             :                enable_if<sizeof...(_Tail) == sizeof...(_UTail)>::type> 
     261             :         explicit
     262         169 :         constexpr _Tuple_impl(_UHead&& __head, _UTail&&... __tail)
     263         121 :         : _Inherited(std::forward<_UTail>(__tail)...),
     264         169 :           _Base(std::forward<_UHead>(__head)) { }
     265             : 
     266          51 :       constexpr _Tuple_impl(const _Tuple_impl&) = default;
     267             : 
     268             :       constexpr
     269          29 :       _Tuple_impl(_Tuple_impl&& __in)
     270             :       noexcept(__and_<is_nothrow_move_constructible<_Head>,
     271             :                       is_nothrow_move_constructible<_Inherited>>::value)
     272          29 :       : _Inherited(std::move(_M_tail(__in))), 
     273          29 :         _Base(std::forward<_Head>(_M_head(__in))) { }
     274             : 
     275             :       template<typename... _UElements>
     276             :         constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in)
     277             :         : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
     278             :           _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { }
     279             : 
     280             :       template<typename _UHead, typename... _UTails>
     281           0 :         constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
     282             :         : _Inherited(std::move
     283           0 :                      (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
     284             :           _Base(std::forward<_UHead>
     285           0 :                 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { }
     286             : 
     287             :       template<typename _Alloc>
     288             :         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
     289             :         : _Inherited(__tag, __a),
     290             :           _Base(__tag, __use_alloc<_Head>(__a)) { }
     291             : 
     292             :       template<typename _Alloc>
     293             :         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
     294             :                     const _Head& __head, const _Tail&... __tail)
     295             :         : _Inherited(__tag, __a, __tail...),
     296             :           _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { }
     297             : 
     298             :       template<typename _Alloc, typename _UHead, typename... _UTail,
     299             :                typename = typename enable_if<sizeof...(_Tail)
     300             :                                              == sizeof...(_UTail)>::type>
     301             :         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
     302             :                     _UHead&& __head, _UTail&&... __tail)
     303             :         : _Inherited(__tag, __a, std::forward<_UTail>(__tail)...),
     304             :           _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
     305             :                 std::forward<_UHead>(__head)) { }
     306             : 
     307             :       template<typename _Alloc>
     308             :         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
     309             :                     const _Tuple_impl& __in)
     310             :         : _Inherited(__tag, __a, _M_tail(__in)), 
     311             :           _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { }
     312             : 
     313             :       template<typename _Alloc>
     314             :         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
     315             :                     _Tuple_impl&& __in)
     316             :         : _Inherited(__tag, __a, std::move(_M_tail(__in))), 
     317             :           _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
     318             :                 std::forward<_Head>(_M_head(__in))) { }
     319             : 
     320             :       template<typename _Alloc, typename... _UElements>
     321             :         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
     322             :                     const _Tuple_impl<_Idx, _UElements...>& __in)
     323             :         : _Inherited(__tag, __a,
     324             :                      _Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
     325             :           _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
     326             :                 _Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { }
     327             : 
     328             :       template<typename _Alloc, typename _UHead, typename... _UTails>
     329             :         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
     330             :                     _Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
     331             :         : _Inherited(__tag, __a, std::move
     332             :                      (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
     333             :           _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
     334             :                 std::forward<_UHead>
     335             :                 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { }
     336             : 
     337             :       _Tuple_impl&
     338             :       operator=(const _Tuple_impl& __in)
     339             :       {
     340             :         _M_head(*this) = _M_head(__in);
     341             :         _M_tail(*this) = _M_tail(__in);
     342             :         return *this;
     343             :       }
     344             : 
     345             :       _Tuple_impl&
     346          23 :       operator=(_Tuple_impl&& __in)
     347             :       noexcept(__and_<is_nothrow_move_assignable<_Head>,
     348             :                       is_nothrow_move_assignable<_Inherited>>::value)
     349             :       {
     350          23 :         _M_head(*this) = std::forward<_Head>(_M_head(__in));
     351          23 :         _M_tail(*this) = std::move(_M_tail(__in));
     352          23 :         return *this;
     353             :       }
     354             : 
     355             :       template<typename... _UElements>
     356             :         _Tuple_impl&
     357             :         operator=(const _Tuple_impl<_Idx, _UElements...>& __in)
     358             :         {
     359             :           _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in);
     360             :           _M_tail(*this) = _Tuple_impl<_Idx, _UElements...>::_M_tail(__in);
     361             :           return *this;
     362             :         }
     363             : 
     364             :       template<typename _UHead, typename... _UTails>
     365             :         _Tuple_impl&
     366             :         operator=(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
     367             :         {
     368             :           _M_head(*this) = std::forward<_UHead>
     369             :             (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in));
     370             :           _M_tail(*this) = std::move
     371             :             (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in));
     372             :           return *this;
     373             :         }
     374             : 
     375             :     protected:
     376             :       void
     377             :       _M_swap(_Tuple_impl& __in)
     378             :       noexcept(noexcept(swap(std::declval<_Head&>(),
     379             :                              std::declval<_Head&>()))
     380             :                && noexcept(_M_tail(__in)._M_swap(_M_tail(__in))))
     381             :       {
     382             :         using std::swap;
     383             :         swap(_M_head(*this), _M_head(__in));
     384             :         _Inherited::_M_swap(_M_tail(__in));
     385             :       }
     386             :     };
     387             : 
     388             :   /// Primary class template, tuple
     389             :   template<typename... _Elements> 
     390         101 :     class tuple : public _Tuple_impl<0, _Elements...>
     391             :     {
     392             :       typedef _Tuple_impl<0, _Elements...> _Inherited;
     393             : 
     394             :     public:
     395          34 :       constexpr tuple()
     396          34 :       : _Inherited() { }
     397             : 
     398             :       explicit
     399           7 :       constexpr tuple(const _Elements&... __elements)
     400           7 :       : _Inherited(__elements...) { }
     401             : 
     402             :       template<typename... _UElements, typename = typename
     403             :         enable_if<__and_<is_convertible<_UElements,
     404             :                                         _Elements>...>::value>::type>
     405             :         explicit
     406          45 :         constexpr tuple(_UElements&&... __elements)
     407          45 :         : _Inherited(std::forward<_UElements>(__elements)...) {   }
     408             : 
     409          19 :       constexpr tuple(const tuple&) = default;
     410             : 
     411          12 :       constexpr tuple(tuple&&) = default; 
     412             : 
     413             :       template<typename... _UElements, typename = typename
     414             :         enable_if<__and_<is_convertible<const _UElements&,
     415             :                                         _Elements>...>::value>::type>
     416             :         constexpr tuple(const tuple<_UElements...>& __in)
     417             :         : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
     418             :         { }
     419             : 
     420             :       template<typename... _UElements, typename = typename
     421             :         enable_if<__and_<is_convertible<_UElements,
     422             :                                         _Elements>...>::value>::type>
     423           0 :         constexpr tuple(tuple<_UElements...>&& __in)
     424           0 :         : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
     425             : 
     426             :       // Allocator-extended constructors.
     427             : 
     428             :       template<typename _Alloc>
     429             :         tuple(allocator_arg_t __tag, const _Alloc& __a)
     430             :         : _Inherited(__tag, __a) { }
     431             : 
     432             :       template<typename _Alloc>
     433             :         tuple(allocator_arg_t __tag, const _Alloc& __a,
     434             :               const _Elements&... __elements)
     435             :         : _Inherited(__tag, __a, __elements...) { }
     436             : 
     437             :       template<typename _Alloc, typename... _UElements, typename = typename
     438             :                enable_if<sizeof...(_UElements)
     439             :                          == sizeof...(_Elements)>::type>
     440             :         tuple(allocator_arg_t __tag, const _Alloc& __a,
     441             :               _UElements&&... __elements)
     442             :         : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
     443             :         { }
     444             : 
     445             :       template<typename _Alloc>
     446             :         tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
     447             :         : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
     448             : 
     449             :       template<typename _Alloc>
     450             :         tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
     451             :         : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
     452             : 
     453             :       template<typename _Alloc, typename... _UElements, typename = typename
     454             :                enable_if<sizeof...(_UElements)
     455             :                          == sizeof...(_Elements)>::type>
     456             :         tuple(allocator_arg_t __tag, const _Alloc& __a,
     457             :               const tuple<_UElements...>& __in)
     458             :         : _Inherited(__tag, __a,
     459             :                      static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
     460             :         { }
     461             : 
     462             :       template<typename _Alloc, typename... _UElements, typename = typename
     463             :                enable_if<sizeof...(_UElements)
     464             :                          == sizeof...(_Elements)>::type>
     465             :         tuple(allocator_arg_t __tag, const _Alloc& __a,
     466             :               tuple<_UElements...>&& __in)
     467             :         : _Inherited(__tag, __a,
     468             :                      static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
     469             :         { }
     470             : 
     471             :       tuple&
     472             :       operator=(const tuple& __in)
     473             :       {
     474             :         static_cast<_Inherited&>(*this) = __in;
     475             :         return *this;
     476             :       }
     477             : 
     478             :       tuple&
     479           6 :       operator=(tuple&& __in)
     480             :       noexcept(is_nothrow_move_assignable<_Inherited>::value)
     481             :       {
     482           6 :         static_cast<_Inherited&>(*this) = std::move(__in);
     483           6 :         return *this;
     484             :       }
     485             : 
     486             :       template<typename... _UElements, typename = typename
     487             :                enable_if<sizeof...(_UElements)
     488             :                          == sizeof...(_Elements)>::type>
     489             :         tuple&
     490             :         operator=(const tuple<_UElements...>& __in)
     491             :         {
     492             :           static_cast<_Inherited&>(*this) = __in;
     493             :           return *this;
     494             :         }
     495             : 
     496             :       template<typename... _UElements, typename = typename
     497             :                enable_if<sizeof...(_UElements)
     498             :                          == sizeof...(_Elements)>::type>
     499             :         tuple&
     500             :         operator=(tuple<_UElements...>&& __in)
     501             :         {
     502             :           static_cast<_Inherited&>(*this) = std::move(__in);
     503             :           return *this;
     504             :         }
     505             : 
     506             :       void
     507             :       swap(tuple& __in)
     508             :       noexcept(noexcept(__in._M_swap(__in)))
     509             :       { _Inherited::_M_swap(__in); }
     510             :     };
     511             : 
     512             :   // Explicit specialization, zero-element tuple.
     513             :   template<>  
     514             :     class tuple<>
     515             :     {
     516             :     public:
     517             :       void swap(tuple&) noexcept { /* no-op */ }
     518             :     };
     519             : 
     520             :   /// Partial specialization, 2-element tuple.
     521             :   /// Includes construction and assignment from a pair.
     522             :   template<typename _T1, typename _T2>
     523           0 :     class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
     524             :     {
     525             :       typedef _Tuple_impl<0, _T1, _T2> _Inherited;
     526             : 
     527             :     public:
     528         117 :       constexpr tuple()
     529         117 :       : _Inherited() { }
     530             : 
     531             :       explicit
     532           0 :       constexpr tuple(const _T1& __a1, const _T2& __a2)
     533           0 :       : _Inherited(__a1, __a2) { }
     534             : 
     535             :       template<typename _U1, typename _U2, typename = typename
     536             :                enable_if<__and_<is_convertible<_U1, _T1>,
     537             :                                 is_convertible<_U2, _T2>>::value>::type>
     538             :         explicit
     539           3 :         constexpr tuple(_U1&& __a1, _U2&& __a2)
     540           3 :         : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
     541             : 
     542           0 :       constexpr tuple(const tuple&) = default;
     543             : 
     544           0 :       constexpr tuple(tuple&&) = default;
     545             : 
     546             :       template<typename _U1, typename _U2, typename = typename
     547             :         enable_if<__and_<is_convertible<const _U1&, _T1>,
     548             :                          is_convertible<const _U2&, _T2>>::value>::type>
     549             :         constexpr tuple(const tuple<_U1, _U2>& __in)
     550             :         : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
     551             : 
     552             :       template<typename _U1, typename _U2, typename = typename
     553             :                enable_if<__and_<is_convertible<_U1, _T1>,
     554             :                                 is_convertible<_U2, _T2>>::value>::type>
     555             :         constexpr tuple(tuple<_U1, _U2>&& __in)
     556             :         : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
     557             : 
     558             :       template<typename _U1, typename _U2, typename = typename
     559             :         enable_if<__and_<is_convertible<const _U1&, _T1>,
     560             :                          is_convertible<const _U2&, _T2>>::value>::type>
     561             :         constexpr tuple(const pair<_U1, _U2>& __in)
     562             :         : _Inherited(__in.first, __in.second) { }
     563             : 
     564             :       template<typename _U1, typename _U2, typename = typename
     565             :                enable_if<__and_<is_convertible<_U1, _T1>,
     566             :                                 is_convertible<_U2, _T2>>::value>::type>
     567             :         constexpr tuple(pair<_U1, _U2>&& __in)
     568             :         : _Inherited(std::forward<_U1>(__in.first),
     569             :                      std::forward<_U2>(__in.second)) { }
     570             : 
     571             :       // Allocator-extended constructors.
     572             : 
     573             :       template<typename _Alloc>
     574             :         tuple(allocator_arg_t __tag, const _Alloc& __a)
     575             :         : _Inherited(__tag, __a) { }
     576             : 
     577             :       template<typename _Alloc>
     578             :         tuple(allocator_arg_t __tag, const _Alloc& __a,
     579             :               const _T1& __a1, const _T2& __a2)
     580             :         : _Inherited(__tag, __a, __a1, __a2) { }
     581             : 
     582             :       template<typename _Alloc, typename _U1, typename _U2>
     583             :         tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2)
     584             :         : _Inherited(__tag, __a, std::forward<_U1>(__a1),
     585             :                      std::forward<_U2>(__a2)) { }
     586             : 
     587             :       template<typename _Alloc>
     588             :         tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
     589             :         : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
     590             : 
     591             :       template<typename _Alloc>
     592             :         tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
     593             :         : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
     594             : 
     595             :       template<typename _Alloc, typename _U1, typename _U2>
     596             :         tuple(allocator_arg_t __tag, const _Alloc& __a,
     597             :               const tuple<_U1, _U2>& __in)
     598             :         : _Inherited(__tag, __a,
     599             :                      static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
     600             :         { }
     601             : 
     602             :       template<typename _Alloc, typename _U1, typename _U2>
     603             :         tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
     604             :         : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
     605             :         { }
     606             : 
     607             :       template<typename _Alloc, typename _U1, typename _U2>
     608             :         tuple(allocator_arg_t __tag, const _Alloc& __a,
     609             :               const pair<_U1, _U2>& __in)
     610             :         : _Inherited(__tag, __a, __in.first, __in.second) { }
     611             : 
     612             :       template<typename _Alloc, typename _U1, typename _U2>
     613             :         tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
     614             :         : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
     615             :                      std::forward<_U2>(__in.second)) { }
     616             : 
     617             :       tuple&
     618             :       operator=(const tuple& __in)
     619             :       {
     620             :         static_cast<_Inherited&>(*this) = __in;
     621             :         return *this;
     622             :       }
     623             : 
     624             :       tuple&
     625             :       operator=(tuple&& __in)
     626             :       noexcept(is_nothrow_move_assignable<_Inherited>::value)
     627             :       {
     628             :         static_cast<_Inherited&>(*this) = std::move(__in);
     629             :         return *this;
     630             :       }
     631             : 
     632             :       template<typename _U1, typename _U2>
     633             :         tuple&
     634             :         operator=(const tuple<_U1, _U2>& __in)
     635             :         {
     636             :           static_cast<_Inherited&>(*this) = __in;
     637             :           return *this;
     638             :         }
     639             : 
     640             :       template<typename _U1, typename _U2>
     641             :         tuple&
     642             :         operator=(tuple<_U1, _U2>&& __in)
     643             :         {
     644             :           static_cast<_Inherited&>(*this) = std::move(__in);
     645             :           return *this;
     646             :         }
     647             : 
     648             :       template<typename _U1, typename _U2>
     649             :         tuple&
     650             :         operator=(const pair<_U1, _U2>& __in)
     651             :         {
     652             :           this->_M_head(*this) = __in.first;
     653             :           this->_M_tail(*this)._M_head(*this) = __in.second;
     654             :           return *this;
     655             :         }
     656             : 
     657             :       template<typename _U1, typename _U2>
     658             :         tuple&
     659             :         operator=(pair<_U1, _U2>&& __in)
     660             :         {
     661             :           this->_M_head(*this) = std::forward<_U1>(__in.first);
     662             :           this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second);
     663             :           return *this;
     664             :         }
     665             : 
     666             :       void
     667             :       swap(tuple& __in)
     668             :       noexcept(noexcept(__in._M_swap(__in)))
     669             :       { _Inherited::_M_swap(__in); }
     670             :     };
     671             : 
     672             : 
     673             :   /// Gives the type of the ith element of a given tuple type.
     674             :   template<std::size_t __i, typename _Tp>
     675             :     struct tuple_element;
     676             : 
     677             :   /**
     678             :    * Recursive case for tuple_element: strip off the first element in
     679             :    * the tuple and retrieve the (i-1)th element of the remaining tuple.
     680             :    */
     681             :   template<std::size_t __i, typename _Head, typename... _Tail>
     682             :     struct tuple_element<__i, tuple<_Head, _Tail...> >
     683             :     : tuple_element<__i - 1, tuple<_Tail...> > { };
     684             : 
     685             :   /**
     686             :    * Basis case for tuple_element: The first element is the one we're seeking.
     687             :    */
     688             :   template<typename _Head, typename... _Tail>
     689             :     struct tuple_element<0, tuple<_Head, _Tail...> >
     690             :     {
     691             :       typedef _Head type;
     692             :     };
     693             : 
     694             :   template<std::size_t __i, typename _Tp>
     695             :     struct tuple_element<__i, const _Tp>
     696             :     {
     697             :       typedef typename
     698             :       add_const<typename tuple_element<__i, _Tp>::type>::type type;
     699             :     };
     700             : 
     701             :   template<std::size_t __i, typename _Tp>
     702             :     struct tuple_element<__i, volatile _Tp>
     703             :     {
     704             :       typedef typename
     705             :       add_volatile<typename tuple_element<__i, _Tp>::type>::type type;
     706             :     };
     707             : 
     708             :   template<std::size_t __i, typename _Tp>
     709             :     struct tuple_element<__i, const volatile _Tp>
     710             :     {
     711             :       typedef typename
     712             :       add_cv<typename tuple_element<__i, _Tp>::type>::type type;
     713             :     };
     714             : 
     715             : #if __cplusplus > 201103L
     716             :   template<std::size_t __i, typename _Tp>
     717             :     using tuple_element_t = typename tuple_element<__i, _Tp>::type;
     718             : #endif
     719             : 
     720             :   /// Finds the size of a given tuple type.
     721             :   template<typename _Tp>
     722             :     struct tuple_size;
     723             : 
     724             :   // _GLIBCXX_RESOLVE_LIB_DEFECTS
     725             :   // 2313. tuple_size should always derive from integral_constant<size_t, N>
     726             :   template<typename _Tp>
     727             :     struct tuple_size<const _Tp>
     728             :     : public integral_constant<size_t, tuple_size<_Tp>::value> { };
     729             : 
     730             :   template<typename _Tp>
     731             :     struct tuple_size<volatile _Tp>
     732             :     : public integral_constant<size_t, tuple_size<_Tp>::value> { };
     733             : 
     734             :   template<typename _Tp>
     735             :     struct tuple_size<const volatile _Tp>
     736             :     : public integral_constant<size_t, tuple_size<_Tp>::value> { };
     737             : 
     738             :   /// class tuple_size
     739             :   template<typename... _Elements>
     740             :     struct tuple_size<tuple<_Elements...>>
     741             :     : public integral_constant<std::size_t, sizeof...(_Elements)> { };
     742             : 
     743             :   template<std::size_t __i, typename _Head, typename... _Tail>
     744             :     constexpr typename __add_ref<_Head>::type
     745         168 :     __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
     746         168 :     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
     747             : 
     748             :   template<std::size_t __i, typename _Head, typename... _Tail>
     749             :     constexpr typename __add_c_ref<_Head>::type
     750         124 :     __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
     751         124 :     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
     752             : 
     753             :   /// Return a reference to the ith element of a tuple.
     754             :   template<std::size_t __i, typename... _Elements>
     755             :     constexpr typename __add_ref<
     756             :                       typename tuple_element<__i, tuple<_Elements...>>::type
     757             :                     >::type
     758         168 :     get(tuple<_Elements...>& __t) noexcept
     759         168 :     { return std::__get_helper<__i>(__t); }
     760             : 
     761             :   /// Return a const reference to the ith element of a const tuple.
     762             :   template<std::size_t __i, typename... _Elements>
     763             :     constexpr typename __add_c_ref<
     764             :                       typename tuple_element<__i, tuple<_Elements...>>::type
     765             :                     >::type
     766         124 :     get(const tuple<_Elements...>& __t) noexcept
     767         124 :     { return std::__get_helper<__i>(__t); }
     768             : 
     769             :   /// Return an rvalue reference to the ith element of a tuple rvalue.
     770             :   template<std::size_t __i, typename... _Elements>
     771             :     constexpr typename __add_r_ref<
     772             :                       typename tuple_element<__i, tuple<_Elements...>>::type
     773             :                     >::type
     774             :     get(tuple<_Elements...>&& __t) noexcept
     775             :     { return std::forward<typename tuple_element<__i,
     776             :         tuple<_Elements...>>::type&&>(get<__i>(__t)); }
     777             : 
     778             : #if __cplusplus > 201103L
     779             : 
     780             : #define __cpp_lib_tuples_by_type 201304
     781             : 
     782             :   template<typename _Head, size_t __i, typename... _Tail>
     783             :     constexpr typename __add_ref<_Head>::type
     784             :     __get_helper2(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
     785             :     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
     786             : 
     787             :   template<typename _Head, size_t __i, typename... _Tail>
     788             :     constexpr typename __add_c_ref<_Head>::type
     789             :     __get_helper2(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
     790             :     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
     791             : 
     792             :   /// Return a reference to the unique element of type _Tp of a tuple.
     793             :   template <typename _Tp, typename... _Types>
     794             :     constexpr _Tp&
     795             :     get(tuple<_Types...>& __t) noexcept
     796             :     { return std::__get_helper2<_Tp>(__t); }
     797             : 
     798             :   /// Return a reference to the unique element of type _Tp of a tuple rvalue.
     799             :   template <typename _Tp, typename... _Types>
     800             :     constexpr _Tp&&
     801             :     get(tuple<_Types...>&& __t) noexcept
     802             :     { return std::forward<_Tp&&>(std::__get_helper2<_Tp>(__t)); }
     803             : 
     804             :   /// Return a const reference to the unique element of type _Tp of a tuple.
     805             :   template <typename _Tp, typename... _Types>
     806             :     constexpr const _Tp&
     807             :     get(const tuple<_Types...>& __t) noexcept
     808             :     { return std::__get_helper2<_Tp>(__t); }
     809             : #endif
     810             : 
     811             : 
     812             :   // This class helps construct the various comparison operations on tuples
     813             :   template<std::size_t __check_equal_size, std::size_t __i, std::size_t __j,
     814             :            typename _Tp, typename _Up>
     815             :     struct __tuple_compare;
     816             : 
     817             :   template<std::size_t __i, std::size_t __j, typename _Tp, typename _Up>
     818             :     struct __tuple_compare<0, __i, __j, _Tp, _Up>
     819             :     {
     820             :       static constexpr bool 
     821             :       __eq(const _Tp& __t, const _Up& __u)
     822             :       {
     823             :         return (get<__i>(__t) == get<__i>(__u) &&
     824             :                 __tuple_compare<0, __i + 1, __j, _Tp, _Up>::__eq(__t, __u));
     825             :       }
     826             :      
     827             :       static constexpr bool 
     828           0 :       __less(const _Tp& __t, const _Up& __u)
     829             :       {
     830           0 :         return ((get<__i>(__t) < get<__i>(__u))
     831           0 :                 || !(get<__i>(__u) < get<__i>(__t)) &&
     832           0 :                 __tuple_compare<0, __i + 1, __j, _Tp, _Up>::__less(__t, __u));
     833             :       }
     834             :     };
     835             : 
     836             :   template<std::size_t __i, typename _Tp, typename _Up>
     837             :     struct __tuple_compare<0, __i, __i, _Tp, _Up>
     838             :     {
     839             :       static constexpr bool 
     840             :       __eq(const _Tp&, const _Up&) { return true; }
     841             :      
     842             :       static constexpr bool 
     843           0 :       __less(const _Tp&, const _Up&) { return false; }
     844             :     };
     845             : 
     846             :   template<typename... _TElements, typename... _UElements>
     847             :     constexpr bool
     848             :     operator==(const tuple<_TElements...>& __t,
     849             :                const tuple<_UElements...>& __u)
     850             :     {
     851             :       typedef tuple<_TElements...> _Tp;
     852             :       typedef tuple<_UElements...> _Up;
     853             :       return bool(__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value,
     854             :               0, tuple_size<_Tp>::value, _Tp, _Up>::__eq(__t, __u));
     855             :     }
     856             : 
     857             :   template<typename... _TElements, typename... _UElements>
     858             :     constexpr bool
     859           0 :     operator<(const tuple<_TElements...>& __t,
     860             :               const tuple<_UElements...>& __u)
     861             :     {
     862             :       typedef tuple<_TElements...> _Tp;
     863             :       typedef tuple<_UElements...> _Up;
     864             :       return bool(__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value,
     865           0 :               0, tuple_size<_Tp>::value, _Tp, _Up>::__less(__t, __u));
     866             :     }
     867             : 
     868             :   template<typename... _TElements, typename... _UElements>
     869             :     constexpr bool
     870             :     operator!=(const tuple<_TElements...>& __t,
     871             :                const tuple<_UElements...>& __u)
     872             :     { return !(__t == __u); }
     873             : 
     874             :   template<typename... _TElements, typename... _UElements>
     875             :     constexpr bool
     876             :     operator>(const tuple<_TElements...>& __t,
     877             :               const tuple<_UElements...>& __u)
     878             :     { return __u < __t; }
     879             : 
     880             :   template<typename... _TElements, typename... _UElements>
     881             :     constexpr bool
     882             :     operator<=(const tuple<_TElements...>& __t,
     883             :                const tuple<_UElements...>& __u)
     884             :     { return !(__u < __t); }
     885             : 
     886             :   template<typename... _TElements, typename... _UElements>
     887             :     constexpr bool
     888             :     operator>=(const tuple<_TElements...>& __t,
     889             :                const tuple<_UElements...>& __u)
     890             :     { return !(__t < __u); }
     891             : 
     892             :   // NB: DR 705.
     893             :   template<typename... _Elements>
     894             :     constexpr tuple<typename __decay_and_strip<_Elements>::__type...>
     895          34 :     make_tuple(_Elements&&... __args)
     896             :     {
     897             :       typedef tuple<typename __decay_and_strip<_Elements>::__type...>
     898             :         __result_type;
     899          34 :       return __result_type(std::forward<_Elements>(__args)...);
     900             :     }
     901             : 
     902             :   template<typename... _Elements>
     903             :     tuple<_Elements&&...>
     904          12 :     forward_as_tuple(_Elements&&... __args) noexcept
     905          12 :     { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
     906             : 
     907             :   template<typename>
     908             :     struct __is_tuple_like_impl : false_type
     909             :     { };
     910             : 
     911             :   template<typename... _Tps>
     912             :     struct __is_tuple_like_impl<tuple<_Tps...>> : true_type
     913             :     { };
     914             : 
     915             :   template<typename _T1, typename _T2>
     916             :     struct __is_tuple_like_impl<pair<_T1, _T2>> : true_type
     917             :     { };
     918             : 
     919             :   template<typename _Tp, std::size_t _Nm>
     920             :     struct __is_tuple_like_impl<array<_Tp, _Nm>> : true_type
     921             :     { };
     922             : 
     923             :   // Internal type trait that allows us to sfinae-protect tuple_cat.
     924             :   template<typename _Tp>
     925             :     struct __is_tuple_like
     926             :     : public __is_tuple_like_impl<typename std::remove_cv
     927             :             <typename std::remove_reference<_Tp>::type>::type>::type
     928             :     { };
     929             : 
     930             :   template<std::size_t, typename, typename, std::size_t>
     931             :     struct __make_tuple_impl;
     932             : 
     933             :   template<std::size_t _Idx, typename _Tuple, typename... _Tp,
     934             :            std::size_t _Nm>
     935             :     struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm>
     936             :     {
     937             :       typedef typename __make_tuple_impl<_Idx + 1, tuple<_Tp...,
     938             :         typename std::tuple_element<_Idx, _Tuple>::type>, _Tuple, _Nm>::__type
     939             :       __type;
     940             :     };
     941             : 
     942             :   template<std::size_t _Nm, typename _Tuple, typename... _Tp>
     943             :     struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm>
     944             :     {
     945             :       typedef tuple<_Tp...> __type;
     946             :     };
     947             : 
     948             :   template<typename _Tuple>
     949             :     struct __do_make_tuple
     950             :     : public __make_tuple_impl<0, tuple<>, _Tuple,
     951             :                                std::tuple_size<_Tuple>::value>
     952             :     { };
     953             : 
     954             :   // Returns the std::tuple equivalent of a tuple-like type.
     955             :   template<typename _Tuple>
     956             :     struct __make_tuple
     957             :     : public __do_make_tuple<typename std::remove_cv
     958             :             <typename std::remove_reference<_Tuple>::type>::type>
     959             :     { };
     960             : 
     961             :   // Combines several std::tuple's into a single one.
     962             :   template<typename...>
     963             :     struct __combine_tuples;
     964             : 
     965             :   template<>
     966             :     struct __combine_tuples<>
     967             :     {
     968             :       typedef tuple<> __type;
     969             :     };
     970             : 
     971             :   template<typename... _Ts>
     972             :     struct __combine_tuples<tuple<_Ts...>>
     973             :     {
     974             :       typedef tuple<_Ts...> __type;
     975             :     };
     976             : 
     977             :   template<typename... _T1s, typename... _T2s, typename... _Rem>
     978             :     struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...>
     979             :     {
     980             :       typedef typename __combine_tuples<tuple<_T1s..., _T2s...>,
     981             :                                         _Rem...>::__type __type;
     982             :     };
     983             : 
     984             :   // Computes the result type of tuple_cat given a set of tuple-like types.
     985             :   template<typename... _Tpls>
     986             :     struct __tuple_cat_result
     987             :     {
     988             :       typedef typename __combine_tuples
     989             :         <typename __make_tuple<_Tpls>::__type...>::__type __type;
     990             :     };
     991             : 
     992             :   // Helper to determine the index set for the first tuple-like
     993             :   // type of a given set.
     994             :   template<typename...>
     995             :     struct __make_1st_indices;
     996             : 
     997             :   template<>
     998             :     struct __make_1st_indices<>
     999             :     {
    1000             :       typedef std::_Index_tuple<> __type;
    1001             :     };
    1002             : 
    1003             :   template<typename _Tp, typename... _Tpls>
    1004             :     struct __make_1st_indices<_Tp, _Tpls...>
    1005             :     {
    1006             :       typedef typename std::_Build_index_tuple<std::tuple_size<
    1007             :         typename std::remove_reference<_Tp>::type>::value>::__type __type;
    1008             :     };
    1009             : 
    1010             :   // Performs the actual concatenation by step-wise expanding tuple-like
    1011             :   // objects into the elements,  which are finally forwarded into the
    1012             :   // result tuple.
    1013             :   template<typename _Ret, typename _Indices, typename... _Tpls>
    1014             :     struct __tuple_concater;
    1015             : 
    1016             :   template<typename _Ret, std::size_t... _Is, typename _Tp, typename... _Tpls>
    1017             :     struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...>
    1018             :     {
    1019             :       template<typename... _Us>
    1020             :         static constexpr _Ret
    1021             :         _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us)
    1022             :         {
    1023             :           typedef typename __make_1st_indices<_Tpls...>::__type __idx;
    1024             :           typedef __tuple_concater<_Ret, __idx, _Tpls...>      __next;
    1025             :           return __next::_S_do(std::forward<_Tpls>(__tps)...,
    1026             :                                std::forward<_Us>(__us)...,
    1027             :                                std::get<_Is>(std::forward<_Tp>(__tp))...);
    1028             :         }
    1029             :     };
    1030             : 
    1031             :   template<typename _Ret>
    1032             :     struct __tuple_concater<_Ret, std::_Index_tuple<>>
    1033             :     {
    1034             :       template<typename... _Us>
    1035             :         static constexpr _Ret
    1036             :         _S_do(_Us&&... __us)
    1037             :         {
    1038             :           return _Ret(std::forward<_Us>(__us)...);
    1039             :         }
    1040             :     };
    1041             : 
    1042             :   /// tuple_cat
    1043             :   template<typename... _Tpls, typename = typename
    1044             :            enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type>
    1045             :     constexpr auto
    1046             :     tuple_cat(_Tpls&&... __tpls)
    1047             :     -> typename __tuple_cat_result<_Tpls...>::__type
    1048             :     {
    1049             :       typedef typename __tuple_cat_result<_Tpls...>::__type __ret;
    1050             :       typedef typename __make_1st_indices<_Tpls...>::__type __idx;
    1051             :       typedef __tuple_concater<__ret, __idx, _Tpls...> __concater;
    1052             :       return __concater::_S_do(std::forward<_Tpls>(__tpls)...);
    1053             :     }
    1054             : 
    1055             :   /// tie
    1056             :   template<typename... _Elements>
    1057             :     inline tuple<_Elements&...>
    1058             :     tie(_Elements&... __args) noexcept
    1059             :     { return tuple<_Elements&...>(__args...); }
    1060             : 
    1061             :   /// swap
    1062             :   template<typename... _Elements>
    1063             :     inline void 
    1064             :     swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
    1065             :     noexcept(noexcept(__x.swap(__y)))
    1066             :     { __x.swap(__y); }
    1067             : 
    1068             :   // A class (and instance) which can be used in 'tie' when an element
    1069             :   // of a tuple is not required
    1070             :   struct _Swallow_assign
    1071             :   {
    1072             :     template<class _Tp>
    1073             :       const _Swallow_assign&
    1074             :       operator=(const _Tp&) const
    1075             :       { return *this; }
    1076             :   };
    1077             : 
    1078             :   const _Swallow_assign ignore{};
    1079             : 
    1080             :   /// Partial specialization for tuples
    1081             :   template<typename... _Types, typename _Alloc>
    1082             :     struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { };
    1083             : 
    1084             :   // See stl_pair.h...
    1085             :   template<class _T1, class _T2>
    1086             :     template<typename... _Args1, typename... _Args2>
    1087             :       inline
    1088           0 :       pair<_T1, _T2>::
    1089             :       pair(piecewise_construct_t,
    1090             :            tuple<_Args1...> __first, tuple<_Args2...> __second)
    1091             :       : pair(__first, __second,
    1092             :              typename _Build_index_tuple<sizeof...(_Args1)>::__type(),
    1093           0 :              typename _Build_index_tuple<sizeof...(_Args2)>::__type())
    1094           0 :       { }
    1095             : 
    1096             :   template<class _T1, class _T2>
    1097             :     template<typename... _Args1, std::size_t... _Indexes1,
    1098             :              typename... _Args2, std::size_t... _Indexes2>
    1099             :       inline
    1100           0 :       pair<_T1, _T2>::
    1101             :       pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2,
    1102             :            _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)
    1103           0 :       : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...),
    1104           0 :         second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
    1105           0 :       { }
    1106             : 
    1107             :   /// @}
    1108             : 
    1109             : _GLIBCXX_END_NAMESPACE_VERSION
    1110             : } // namespace std
    1111             : 
    1112             : #endif // C++11
    1113             : 
    1114             : #endif // _GLIBCXX_TUPLE

Generated by: LCOV version 1.11