LCOV - code coverage report
Current view: top level - c++/4.8 - tuple (source / functions) Hit Total Coverage
Test: clang.info Lines: 26 26 100.0 %
Date: 2016-01-31 12:01:00 Functions: 96 96 100.0 %

          Line data    Source code
       1             : // <tuple> -*- C++ -*-
       2             : 
       3             : // Copyright (C) 2007-2013 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             :       constexpr _Head_base()
      86             :       : _Head() { }
      87             : 
      88             :       constexpr _Head_base(const _Head& __h)
      89             :       : _Head(__h) { }
      90             : 
      91             :       constexpr _Head_base(const _Head_base&) = default;
      92             :       constexpr _Head_base(_Head_base&&) = default;
      93             : 
      94             :       template<typename _UHead>
      95             :         constexpr _Head_base(_UHead&& __h)
      96          47 :         : _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          75 :       _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             :     struct _Head_base<_Idx, _Head, false>
     130             :     {
     131             :       constexpr _Head_base()
     132             :       : _M_head_impl() { }
     133             : 
     134             :       constexpr _Head_base(const _Head& __h)
     135          26 :       : _M_head_impl(__h) { }
     136             : 
     137             :       constexpr _Head_base(const _Head_base&) = default;
     138             :       constexpr _Head_base(_Head_base&&) = default;
     139             : 
     140             :       template<typename _UHead>
     141             :         constexpr _Head_base(_UHead&& __h)
     142          47 :         : _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         113 :       _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; }
     170             : 
     171             :       static constexpr const _Head&
     172          47 :       _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             :       _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             :     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         188 :       _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
     242             : 
     243             :       static constexpr const _Head&
     244          47 :       _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
     245             : 
     246             :       static constexpr _Inherited&
     247          13 :       _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             :       constexpr _Tuple_impl()
     253             :       : _Inherited(), _Base() { }
     254             : 
     255             :       explicit 
     256             :       constexpr _Tuple_impl(const _Head& __head, const _Tail&... __tail)
     257          13 :       : _Inherited(__tail...), _Base(__head) { }
     258             : 
     259             :       template<typename _UHead, typename... _UTail, typename = typename
     260             :                enable_if<sizeof...(_Tail) == sizeof...(_UTail)>::type> 
     261             :         explicit
     262             :         constexpr _Tuple_impl(_UHead&& __head, _UTail&&... __tail)
     263          47 :         : _Inherited(std::forward<_UTail>(__tail)...),
     264         141 :           _Base(std::forward<_UHead>(__head)) { }
     265             : 
     266             :       constexpr _Tuple_impl(const _Tuple_impl&) = default;
     267             : 
     268             :       constexpr
     269             :       _Tuple_impl(_Tuple_impl&& __in)
     270             :       noexcept(__and_<is_nothrow_move_constructible<_Head>,
     271             :                       is_nothrow_move_constructible<_Inherited>>::value)
     272          13 :       : _Inherited(std::move(_M_tail(__in))), 
     273          39 :         _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             :         constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
     282             :         : _Inherited(std::move
     283             :                      (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
     284             :           _Base(std::forward<_UHead>
     285             :                 (_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             :       operator=(_Tuple_impl&& __in)
     347             :       noexcept(__and_<is_nothrow_move_assignable<_Head>,
     348             :                       is_nothrow_move_assignable<_Inherited>>::value)
     349             :       {
     350             :         _M_head(*this) = std::forward<_Head>(_M_head(__in));
     351             :         _M_tail(*this) = std::move(_M_tail(__in));
     352             :         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             :     class tuple : public _Tuple_impl<0, _Elements...>
     391             :     {
     392             :       typedef _Tuple_impl<0, _Elements...> _Inherited;
     393             : 
     394             :     public:
     395             :       constexpr tuple()
     396             :       : _Inherited() { }
     397             : 
     398             :       explicit
     399             :       constexpr tuple(const _Elements&... __elements)
     400          13 :       : _Inherited(__elements...) { }
     401             : 
     402             :       template<typename... _UElements, typename = typename
     403             :         enable_if<__and_<is_convertible<_UElements,
     404             :                                         _Elements>...>::value>::type>
     405             :         explicit
     406             :         constexpr tuple(_UElements&&... __elements)
     407             :         : _Inherited(std::forward<_UElements>(__elements)...) {   }
     408             : 
     409             :       constexpr tuple(const tuple&) = default;
     410             : 
     411          13 :       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             :         constexpr tuple(tuple<_UElements...>&& __in)
     424             :         : _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             :       operator=(tuple&& __in)
     480             :       noexcept(is_nothrow_move_assignable<_Inherited>::value)
     481             :       {
     482             :         static_cast<_Inherited&>(*this) = std::move(__in);
     483             :         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             :     class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
     524             :     {
     525             :       typedef _Tuple_impl<0, _T1, _T2> _Inherited;
     526             : 
     527             :     public:
     528             :       constexpr tuple()
     529             :       : _Inherited() { }
     530             : 
     531             :       explicit
     532             :       constexpr tuple(const _T1& __a1, const _T2& __a2)
     533             :       : _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             :         constexpr tuple(_U1&& __a1, _U2&& __a2)
     540          47 :         : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
     541             : 
     542             :       constexpr tuple(const tuple&) = default;
     543             : 
     544             :       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             :   /// Finds the size of a given tuple type.
     716             :   template<typename _Tp>
     717             :     struct tuple_size;
     718             : 
     719             :   template<typename _Tp>
     720             :     struct tuple_size<const _Tp>
     721             :     : public integral_constant<
     722             :              typename remove_cv<decltype(tuple_size<_Tp>::value)>::type,
     723             :              tuple_size<_Tp>::value> { };
     724             : 
     725             :   template<typename _Tp>
     726             :     struct tuple_size<volatile _Tp>
     727             :     : public integral_constant<
     728             :              typename remove_cv<decltype(tuple_size<_Tp>::value)>::type,
     729             :              tuple_size<_Tp>::value> { };
     730             : 
     731             :   template<typename _Tp>
     732             :     struct tuple_size<const volatile _Tp>
     733             :     : public integral_constant<
     734             :              typename remove_cv<decltype(tuple_size<_Tp>::value)>::type,
     735             :              tuple_size<_Tp>::value> { };
     736             : 
     737             :   /// class tuple_size
     738             :   template<typename... _Elements>
     739             :     struct tuple_size<tuple<_Elements...>>
     740             :     : public integral_constant<std::size_t, sizeof...(_Elements)> { };
     741             : 
     742             :   template<std::size_t __i, typename _Head, typename... _Tail>
     743             :     constexpr typename __add_ref<_Head>::type
     744             :     __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
     745         175 :     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
     746             : 
     747             :   template<std::size_t __i, typename _Head, typename... _Tail>
     748             :     constexpr typename __add_c_ref<_Head>::type
     749             :     __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
     750          47 :     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
     751             : 
     752             :   // Return a reference (const reference, rvalue reference) to the ith element
     753             :   // of a tuple.  Any const or non-const ref elements are returned with their
     754             :   // original type.
     755             :   template<std::size_t __i, typename... _Elements>
     756             :     constexpr typename __add_ref<
     757             :                       typename tuple_element<__i, tuple<_Elements...>>::type
     758             :                     >::type
     759             :     get(tuple<_Elements...>& __t) noexcept
     760         175 :     { return std::__get_helper<__i>(__t); }
     761             : 
     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             :     get(const tuple<_Elements...>& __t) noexcept
     767          47 :     { return std::__get_helper<__i>(__t); }
     768             : 
     769             :   template<std::size_t __i, typename... _Elements>
     770             :     constexpr typename __add_r_ref<
     771             :                       typename tuple_element<__i, tuple<_Elements...>>::type
     772             :                     >::type
     773             :     get(tuple<_Elements...>&& __t) noexcept
     774             :     { return std::forward<typename tuple_element<__i,
     775             :         tuple<_Elements...>>::type&&>(get<__i>(__t)); }
     776             : 
     777             :   // This class helps construct the various comparison operations on tuples
     778             :   template<std::size_t __check_equal_size, std::size_t __i, std::size_t __j,
     779             :            typename _Tp, typename _Up>
     780             :     struct __tuple_compare;
     781             : 
     782             :   template<std::size_t __i, std::size_t __j, typename _Tp, typename _Up>
     783             :     struct __tuple_compare<0, __i, __j, _Tp, _Up>
     784             :     {
     785             :       static constexpr bool 
     786             :       __eq(const _Tp& __t, const _Up& __u)
     787             :       {
     788             :         return (get<__i>(__t) == get<__i>(__u) &&
     789             :                 __tuple_compare<0, __i + 1, __j, _Tp, _Up>::__eq(__t, __u));
     790             :       }
     791             :      
     792             :       static constexpr bool 
     793             :       __less(const _Tp& __t, const _Up& __u)
     794             :       {
     795             :         return ((get<__i>(__t) < get<__i>(__u))
     796             :                 || !(get<__i>(__u) < get<__i>(__t)) &&
     797             :                 __tuple_compare<0, __i + 1, __j, _Tp, _Up>::__less(__t, __u));
     798             :       }
     799             :     };
     800             : 
     801             :   template<std::size_t __i, typename _Tp, typename _Up>
     802             :     struct __tuple_compare<0, __i, __i, _Tp, _Up>
     803             :     {
     804             :       static constexpr bool 
     805             :       __eq(const _Tp&, const _Up&) { return true; }
     806             :      
     807             :       static constexpr bool 
     808             :       __less(const _Tp&, const _Up&) { return false; }
     809             :     };
     810             : 
     811             :   template<typename... _TElements, typename... _UElements>
     812             :     constexpr bool
     813             :     operator==(const tuple<_TElements...>& __t,
     814             :                const tuple<_UElements...>& __u)
     815             :     {
     816             :       typedef tuple<_TElements...> _Tp;
     817             :       typedef tuple<_UElements...> _Up;
     818             :       return bool(__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value,
     819             :               0, tuple_size<_Tp>::value, _Tp, _Up>::__eq(__t, __u));
     820             :     }
     821             : 
     822             :   template<typename... _TElements, typename... _UElements>
     823             :     constexpr bool
     824             :     operator<(const tuple<_TElements...>& __t,
     825             :               const tuple<_UElements...>& __u)
     826             :     {
     827             :       typedef tuple<_TElements...> _Tp;
     828             :       typedef tuple<_UElements...> _Up;
     829             :       return bool(__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value,
     830             :               0, tuple_size<_Tp>::value, _Tp, _Up>::__less(__t, __u));
     831             :     }
     832             : 
     833             :   template<typename... _TElements, typename... _UElements>
     834             :     inline constexpr bool
     835             :     operator!=(const tuple<_TElements...>& __t,
     836             :                const tuple<_UElements...>& __u)
     837             :     { return !(__t == __u); }
     838             : 
     839             :   template<typename... _TElements, typename... _UElements>
     840             :     inline constexpr bool
     841             :     operator>(const tuple<_TElements...>& __t,
     842             :               const tuple<_UElements...>& __u)
     843             :     { return __u < __t; }
     844             : 
     845             :   template<typename... _TElements, typename... _UElements>
     846             :     inline constexpr bool
     847             :     operator<=(const tuple<_TElements...>& __t,
     848             :                const tuple<_UElements...>& __u)
     849             :     { return !(__u < __t); }
     850             : 
     851             :   template<typename... _TElements, typename... _UElements>
     852             :     inline constexpr bool
     853             :     operator>=(const tuple<_TElements...>& __t,
     854             :                const tuple<_UElements...>& __u)
     855             :     { return !(__t < __u); }
     856             : 
     857             :   // NB: DR 705.
     858             :   template<typename... _Elements>
     859             :     constexpr tuple<typename __decay_and_strip<_Elements>::__type...>
     860             :     make_tuple(_Elements&&... __args)
     861             :     {
     862             :       typedef tuple<typename __decay_and_strip<_Elements>::__type...>
     863             :         __result_type;
     864             :       return __result_type(std::forward<_Elements>(__args)...);
     865             :     }
     866             : 
     867             :   template<typename... _Elements>
     868             :     tuple<_Elements&&...>
     869             :     forward_as_tuple(_Elements&&... __args) noexcept
     870             :     { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
     871             : 
     872             :   template<typename>
     873             :     struct __is_tuple_like_impl : false_type
     874             :     { };
     875             : 
     876             :   template<typename... _Tps>
     877             :     struct __is_tuple_like_impl<tuple<_Tps...>> : true_type
     878             :     { };
     879             : 
     880             :   template<typename _T1, typename _T2>
     881             :     struct __is_tuple_like_impl<pair<_T1, _T2>> : true_type
     882             :     { };
     883             : 
     884             :   template<typename _Tp, std::size_t _Nm>
     885             :     struct __is_tuple_like_impl<array<_Tp, _Nm>> : true_type
     886             :     { };
     887             : 
     888             :   // Internal type trait that allows us to sfinae-protect tuple_cat.
     889             :   template<typename _Tp>
     890             :     struct __is_tuple_like
     891             :     : public __is_tuple_like_impl<typename std::remove_cv
     892             :             <typename std::remove_reference<_Tp>::type>::type>::type
     893             :     { };
     894             : 
     895             :   // Stores a tuple of indices.  Also used by bind() to extract the elements
     896             :   // in a tuple. 
     897             :   template<std::size_t... _Indexes>
     898             :     struct _Index_tuple
     899             :     {
     900             :       typedef _Index_tuple<_Indexes..., sizeof...(_Indexes)> __next;
     901             :     };
     902             : 
     903             :   // Builds an _Index_tuple<0, 1, 2, ..., _Num-1>.
     904             :   template<std::size_t _Num>
     905             :     struct _Build_index_tuple
     906             :     {
     907             :       typedef typename _Build_index_tuple<_Num - 1>::__type::__next __type;
     908             :     };
     909             : 
     910             :   template<>
     911             :     struct _Build_index_tuple<0>
     912             :     {
     913             :       typedef _Index_tuple<> __type;
     914             :     };
     915             : 
     916             :   template<std::size_t, typename, typename, std::size_t>
     917             :     struct __make_tuple_impl;
     918             : 
     919             :   template<std::size_t _Idx, typename _Tuple, typename... _Tp,
     920             :            std::size_t _Nm>
     921             :     struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm>
     922             :     {
     923             :       typedef typename __make_tuple_impl<_Idx + 1, tuple<_Tp...,
     924             :         typename std::tuple_element<_Idx, _Tuple>::type>, _Tuple, _Nm>::__type
     925             :       __type;
     926             :     };
     927             : 
     928             :   template<std::size_t _Nm, typename _Tuple, typename... _Tp>
     929             :     struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm>
     930             :     {
     931             :       typedef tuple<_Tp...> __type;
     932             :     };
     933             : 
     934             :   template<typename _Tuple>
     935             :     struct __do_make_tuple
     936             :     : public __make_tuple_impl<0, tuple<>, _Tuple,
     937             :                                std::tuple_size<_Tuple>::value>
     938             :     { };
     939             : 
     940             :   // Returns the std::tuple equivalent of a tuple-like type.
     941             :   template<typename _Tuple>
     942             :     struct __make_tuple
     943             :     : public __do_make_tuple<typename std::remove_cv
     944             :             <typename std::remove_reference<_Tuple>::type>::type>
     945             :     { };
     946             : 
     947             :   // Combines several std::tuple's into a single one.
     948             :   template<typename...>
     949             :     struct __combine_tuples;
     950             : 
     951             :   template<>
     952             :     struct __combine_tuples<>
     953             :     {
     954             :       typedef tuple<> __type;
     955             :     };
     956             : 
     957             :   template<typename... _Ts>
     958             :     struct __combine_tuples<tuple<_Ts...>>
     959             :     {
     960             :       typedef tuple<_Ts...> __type;
     961             :     };
     962             : 
     963             :   template<typename... _T1s, typename... _T2s, typename... _Rem>
     964             :     struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...>
     965             :     {
     966             :       typedef typename __combine_tuples<tuple<_T1s..., _T2s...>,
     967             :                                         _Rem...>::__type __type;
     968             :     };
     969             : 
     970             :   // Computes the result type of tuple_cat given a set of tuple-like types.
     971             :   template<typename... _Tpls>
     972             :     struct __tuple_cat_result
     973             :     {
     974             :       typedef typename __combine_tuples
     975             :         <typename __make_tuple<_Tpls>::__type...>::__type __type;
     976             :     };
     977             : 
     978             :   // Helper to determine the index set for the first tuple-like
     979             :   // type of a given set.
     980             :   template<typename...>
     981             :     struct __make_1st_indices;
     982             : 
     983             :   template<>
     984             :     struct __make_1st_indices<>
     985             :     {
     986             :       typedef std::_Index_tuple<> __type;
     987             :     };
     988             : 
     989             :   template<typename _Tp, typename... _Tpls>
     990             :     struct __make_1st_indices<_Tp, _Tpls...>
     991             :     {
     992             :       typedef typename std::_Build_index_tuple<std::tuple_size<
     993             :         typename std::remove_reference<_Tp>::type>::value>::__type __type;
     994             :     };
     995             : 
     996             :   // Performs the actual concatenation by step-wise expanding tuple-like
     997             :   // objects into the elements,  which are finally forwarded into the
     998             :   // result tuple.
     999             :   template<typename _Ret, typename _Indices, typename... _Tpls>
    1000             :     struct __tuple_concater;
    1001             : 
    1002             :   template<typename _Ret, std::size_t... _Is, typename _Tp, typename... _Tpls>
    1003             :     struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...>
    1004             :     {
    1005             :       template<typename... _Us>
    1006             :         static constexpr _Ret
    1007             :         _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us)
    1008             :         {
    1009             :           typedef typename __make_1st_indices<_Tpls...>::__type __idx;
    1010             :           typedef __tuple_concater<_Ret, __idx, _Tpls...>      __next;
    1011             :           return __next::_S_do(std::forward<_Tpls>(__tps)...,
    1012             :                                std::forward<_Us>(__us)...,
    1013             :                                std::get<_Is>(std::forward<_Tp>(__tp))...);
    1014             :         }
    1015             :     };
    1016             : 
    1017             :   template<typename _Ret>
    1018             :     struct __tuple_concater<_Ret, std::_Index_tuple<>>
    1019             :     {
    1020             :       template<typename... _Us>
    1021             :         static constexpr _Ret
    1022             :         _S_do(_Us&&... __us)
    1023             :         {
    1024             :           return _Ret(std::forward<_Us>(__us)...);
    1025             :         }
    1026             :     };
    1027             : 
    1028             :   /// tuple_cat
    1029             :   template<typename... _Tpls, typename = typename
    1030             :            enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type>
    1031             :     constexpr auto
    1032             :     tuple_cat(_Tpls&&... __tpls)
    1033             :     -> typename __tuple_cat_result<_Tpls...>::__type
    1034             :     {
    1035             :       typedef typename __tuple_cat_result<_Tpls...>::__type __ret;
    1036             :       typedef typename __make_1st_indices<_Tpls...>::__type __idx;
    1037             :       typedef __tuple_concater<__ret, __idx, _Tpls...> __concater;
    1038             :       return __concater::_S_do(std::forward<_Tpls>(__tpls)...);
    1039             :     }
    1040             : 
    1041             :   /// tie
    1042             :   template<typename... _Elements>
    1043             :     inline tuple<_Elements&...>
    1044             :     tie(_Elements&... __args) noexcept
    1045             :     { return tuple<_Elements&...>(__args...); }
    1046             : 
    1047             :   /// swap
    1048             :   template<typename... _Elements>
    1049             :     inline void 
    1050             :     swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
    1051             :     noexcept(noexcept(__x.swap(__y)))
    1052             :     { __x.swap(__y); }
    1053             : 
    1054             :   // A class (and instance) which can be used in 'tie' when an element
    1055             :   // of a tuple is not required
    1056             :   struct _Swallow_assign
    1057             :   {
    1058             :     template<class _Tp>
    1059             :       const _Swallow_assign&
    1060             :       operator=(const _Tp&) const
    1061             :       { return *this; }
    1062             :   };
    1063             : 
    1064             :   const _Swallow_assign ignore{};
    1065             : 
    1066             :   /// Partial specialization for tuples
    1067             :   template<typename... _Types, typename _Alloc>
    1068             :     struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { };
    1069             : 
    1070             :   // See stl_pair.h...
    1071             :   template<class _T1, class _T2>
    1072             :     template<typename... _Args1, typename... _Args2>
    1073             :       inline
    1074             :       pair<_T1, _T2>::
    1075             :       pair(piecewise_construct_t,
    1076             :            tuple<_Args1...> __first, tuple<_Args2...> __second)
    1077          13 :       : pair(__first, __second,
    1078             :              typename _Build_index_tuple<sizeof...(_Args1)>::__type(),
    1079             :              typename _Build_index_tuple<sizeof...(_Args2)>::__type())
    1080          13 :       { }
    1081             : 
    1082             :   template<class _T1, class _T2>
    1083             :     template<typename... _Args1, std::size_t... _Indexes1,
    1084             :              typename... _Args2, std::size_t... _Indexes2>
    1085             :       inline
    1086             :       pair<_T1, _T2>::
    1087             :       pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2,
    1088             :            _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)
    1089          13 :       : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...),
    1090          13 :         second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
    1091          13 :       { }
    1092             : 
    1093             :   /// @}
    1094             : 
    1095             : _GLIBCXX_END_NAMESPACE_VERSION
    1096             : } // namespace std
    1097             : 
    1098             : #endif // C++11
    1099             : 
    1100             : #endif // _GLIBCXX_TUPLE

Generated by: LCOV version 1.11