LCOV - code coverage report
Current view: top level - c++/5 - tuple (source / functions) Hit Total Coverage
Test: lcov-run.info Lines: 1 2 50.0 %
Date: 2019-02-15 00:00:25 Functions: 0 0 -
Branches: 0 0 -

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

Generated by: LCOV version 1.12