libstdc++
tuple
Go to the documentation of this file.
00001 // <tuple> -*- C++ -*-
00002 
00003 // Copyright (C) 2007-2015 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 3, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /** @file include/tuple
00026  *  This is a Standard C++ Library header.
00027  */
00028 
00029 #ifndef _GLIBCXX_TUPLE
00030 #define _GLIBCXX_TUPLE 1
00031 
00032 #pragma GCC system_header
00033 
00034 #if __cplusplus < 201103L
00035 # include <bits/c++0x_warning.h>
00036 #else
00037 
00038 #include <utility>
00039 #include <array>
00040 #include <bits/uses_allocator.h>
00041 
00042 namespace std _GLIBCXX_VISIBILITY(default)
00043 {
00044 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00045 
00046   /**
00047    *  @addtogroup utilities
00048    *  @{
00049    */
00050 
00051   template<std::size_t _Idx, typename _Head, bool _IsEmptyNotFinal>
00052     struct _Head_base;
00053 
00054   template<std::size_t _Idx, typename _Head>
00055     struct _Head_base<_Idx, _Head, true>
00056     : public _Head
00057     {
00058       constexpr _Head_base()
00059       : _Head() { }
00060 
00061       constexpr _Head_base(const _Head& __h)
00062       : _Head(__h) { }
00063 
00064       constexpr _Head_base(const _Head_base&) = default;
00065       constexpr _Head_base(_Head_base&&) = default;
00066 
00067       template<typename _UHead>
00068         constexpr _Head_base(_UHead&& __h)
00069         : _Head(std::forward<_UHead>(__h)) { }
00070 
00071       _Head_base(allocator_arg_t, __uses_alloc0)
00072       : _Head() { }
00073 
00074       template<typename _Alloc>
00075         _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
00076         : _Head(allocator_arg, *__a._M_a) { }
00077 
00078       template<typename _Alloc>
00079         _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
00080         : _Head(*__a._M_a) { }
00081 
00082       template<typename _UHead>
00083         _Head_base(__uses_alloc0, _UHead&& __uhead)
00084         : _Head(std::forward<_UHead>(__uhead)) { }
00085 
00086       template<typename _Alloc, typename _UHead>
00087         _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
00088         : _Head(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { }
00089 
00090       template<typename _Alloc, typename _UHead>
00091         _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
00092         : _Head(std::forward<_UHead>(__uhead), *__a._M_a) { }
00093 
00094       static constexpr _Head&
00095       _M_head(_Head_base& __b) noexcept { return __b; }
00096 
00097       static constexpr const _Head&
00098       _M_head(const _Head_base& __b) noexcept { return __b; }
00099     };
00100 
00101   template<std::size_t _Idx, typename _Head>
00102     struct _Head_base<_Idx, _Head, false>
00103     {
00104       constexpr _Head_base()
00105       : _M_head_impl() { }
00106 
00107       constexpr _Head_base(const _Head& __h)
00108       : _M_head_impl(__h) { }
00109 
00110       constexpr _Head_base(const _Head_base&) = default;
00111       constexpr _Head_base(_Head_base&&) = default;
00112 
00113       template<typename _UHead>
00114         constexpr _Head_base(_UHead&& __h)
00115         : _M_head_impl(std::forward<_UHead>(__h)) { }
00116 
00117       _Head_base(allocator_arg_t, __uses_alloc0)
00118       : _M_head_impl() { }
00119 
00120       template<typename _Alloc>
00121         _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a)
00122         : _M_head_impl(allocator_arg, *__a._M_a) { }
00123 
00124       template<typename _Alloc>
00125         _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a)
00126         : _M_head_impl(*__a._M_a) { }
00127 
00128       template<typename _UHead>
00129         _Head_base(__uses_alloc0, _UHead&& __uhead)
00130         : _M_head_impl(std::forward<_UHead>(__uhead)) { }
00131 
00132       template<typename _Alloc, typename _UHead>
00133         _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead)
00134         : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead))
00135         { }
00136 
00137       template<typename _Alloc, typename _UHead>
00138         _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead)
00139         : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { }
00140 
00141       static constexpr _Head&
00142       _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; }
00143 
00144       static constexpr const _Head&
00145       _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; }
00146 
00147       _Head _M_head_impl;
00148     };
00149 
00150   /**
00151    * Contains the actual implementation of the @c tuple template, stored
00152    * as a recursive inheritance hierarchy from the first element (most
00153    * derived class) to the last (least derived class). The @c Idx
00154    * parameter gives the 0-based index of the element stored at this
00155    * point in the hierarchy; we use it to implement a constant-time
00156    * get() operation.
00157    */
00158   template<std::size_t _Idx, typename... _Elements>
00159     struct _Tuple_impl; 
00160 
00161   template<typename _Tp>
00162     struct __is_empty_non_tuple : is_empty<_Tp> { };
00163 
00164   // Using EBO for elements that are tuples causes ambiguous base errors.
00165   template<typename _El0, typename... _El>
00166     struct __is_empty_non_tuple<tuple<_El0, _El...>> : false_type { };
00167 
00168   // Use the Empty Base-class Optimization for empty, non-final types.
00169   template<typename _Tp>
00170     using __empty_not_final
00171     = typename conditional<__is_final(_Tp), false_type,
00172                            __is_empty_non_tuple<_Tp>>::type;
00173 
00174   /**
00175    * Recursive tuple implementation. Here we store the @c Head element
00176    * and derive from a @c Tuple_impl containing the remaining elements
00177    * (which contains the @c Tail).
00178    */
00179   template<std::size_t _Idx, typename _Head, typename... _Tail>
00180     struct _Tuple_impl<_Idx, _Head, _Tail...>
00181     : public _Tuple_impl<_Idx + 1, _Tail...>,
00182       private _Head_base<_Idx, _Head, __empty_not_final<_Head>::value>
00183     {
00184       template<std::size_t, typename...> friend class _Tuple_impl;
00185 
00186       typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
00187       typedef _Head_base<_Idx, _Head, __empty_not_final<_Head>::value> _Base;
00188 
00189       static constexpr _Head&  
00190       _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
00191 
00192       static constexpr const _Head&
00193       _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
00194 
00195       static constexpr _Inherited&
00196       _M_tail(_Tuple_impl& __t) noexcept { return __t; }
00197 
00198       static constexpr const _Inherited&
00199       _M_tail(const _Tuple_impl& __t) noexcept { return __t; }
00200 
00201       constexpr _Tuple_impl()
00202       : _Inherited(), _Base() { }
00203 
00204       explicit 
00205       constexpr _Tuple_impl(const _Head& __head, const _Tail&... __tail)
00206       : _Inherited(__tail...), _Base(__head) { }
00207 
00208       template<typename _UHead, typename... _UTail, typename = typename
00209                enable_if<sizeof...(_Tail) == sizeof...(_UTail)>::type> 
00210         explicit
00211         constexpr _Tuple_impl(_UHead&& __head, _UTail&&... __tail)
00212         : _Inherited(std::forward<_UTail>(__tail)...),
00213           _Base(std::forward<_UHead>(__head)) { }
00214 
00215       constexpr _Tuple_impl(const _Tuple_impl&) = default;
00216 
00217       constexpr
00218       _Tuple_impl(_Tuple_impl&& __in)
00219       noexcept(__and_<is_nothrow_move_constructible<_Head>,
00220                       is_nothrow_move_constructible<_Inherited>>::value)
00221       : _Inherited(std::move(_M_tail(__in))), 
00222         _Base(std::forward<_Head>(_M_head(__in))) { }
00223 
00224       template<typename... _UElements>
00225         constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in)
00226         : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
00227           _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { }
00228 
00229       template<typename _UHead, typename... _UTails>
00230         constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
00231         : _Inherited(std::move
00232                      (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
00233           _Base(std::forward<_UHead>
00234                 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { }
00235 
00236       template<typename _Alloc>
00237         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
00238         : _Inherited(__tag, __a),
00239           _Base(__tag, __use_alloc<_Head>(__a)) { }
00240 
00241       template<typename _Alloc>
00242         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
00243                     const _Head& __head, const _Tail&... __tail)
00244         : _Inherited(__tag, __a, __tail...),
00245           _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { }
00246 
00247       template<typename _Alloc, typename _UHead, typename... _UTail,
00248                typename = typename enable_if<sizeof...(_Tail)
00249                                              == sizeof...(_UTail)>::type>
00250         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
00251                     _UHead&& __head, _UTail&&... __tail)
00252         : _Inherited(__tag, __a, std::forward<_UTail>(__tail)...),
00253           _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
00254                 std::forward<_UHead>(__head)) { }
00255 
00256       template<typename _Alloc>
00257         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
00258                     const _Tuple_impl& __in)
00259         : _Inherited(__tag, __a, _M_tail(__in)), 
00260           _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { }
00261 
00262       template<typename _Alloc>
00263         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
00264                     _Tuple_impl&& __in)
00265         : _Inherited(__tag, __a, std::move(_M_tail(__in))), 
00266           _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
00267                 std::forward<_Head>(_M_head(__in))) { }
00268 
00269       template<typename _Alloc, typename... _UElements>
00270         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
00271                     const _Tuple_impl<_Idx, _UElements...>& __in)
00272         : _Inherited(__tag, __a,
00273                      _Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
00274           _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
00275                 _Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { }
00276 
00277       template<typename _Alloc, typename _UHead, typename... _UTails>
00278         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
00279                     _Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
00280         : _Inherited(__tag, __a, std::move
00281                      (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
00282           _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
00283                 std::forward<_UHead>
00284                 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { }
00285 
00286       _Tuple_impl&
00287       operator=(const _Tuple_impl& __in)
00288       {
00289         _M_head(*this) = _M_head(__in);
00290         _M_tail(*this) = _M_tail(__in);
00291         return *this;
00292       }
00293 
00294       _Tuple_impl&
00295       operator=(_Tuple_impl&& __in)
00296       noexcept(__and_<is_nothrow_move_assignable<_Head>,
00297                       is_nothrow_move_assignable<_Inherited>>::value)
00298       {
00299         _M_head(*this) = std::forward<_Head>(_M_head(__in));
00300         _M_tail(*this) = std::move(_M_tail(__in));
00301         return *this;
00302       }
00303 
00304       template<typename... _UElements>
00305         _Tuple_impl&
00306         operator=(const _Tuple_impl<_Idx, _UElements...>& __in)
00307         {
00308           _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in);
00309           _M_tail(*this) = _Tuple_impl<_Idx, _UElements...>::_M_tail(__in);
00310           return *this;
00311         }
00312 
00313       template<typename _UHead, typename... _UTails>
00314         _Tuple_impl&
00315         operator=(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
00316         {
00317           _M_head(*this) = std::forward<_UHead>
00318             (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in));
00319           _M_tail(*this) = std::move
00320             (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in));
00321           return *this;
00322         }
00323 
00324     protected:
00325       void
00326       _M_swap(_Tuple_impl& __in)
00327       noexcept(noexcept(swap(std::declval<_Head&>(),
00328                              std::declval<_Head&>()))
00329                && noexcept(_M_tail(__in)._M_swap(_M_tail(__in))))
00330       {
00331         using std::swap;
00332         swap(_M_head(*this), _M_head(__in));
00333         _Inherited::_M_swap(_M_tail(__in));
00334       }
00335     };
00336 
00337   // Basis case of inheritance recursion.
00338   template<std::size_t _Idx, typename _Head>
00339     struct _Tuple_impl<_Idx, _Head>
00340     : private _Head_base<_Idx, _Head, __empty_not_final<_Head>::value>
00341     {
00342       template<std::size_t, typename...> friend class _Tuple_impl;
00343 
00344       typedef _Head_base<_Idx, _Head, __empty_not_final<_Head>::value> _Base;
00345 
00346       static constexpr _Head&
00347       _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
00348 
00349       static constexpr const _Head&
00350       _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
00351 
00352       constexpr _Tuple_impl()
00353       : _Base() { }
00354 
00355       explicit
00356       constexpr _Tuple_impl(const _Head& __head)
00357       : _Base(__head) { }
00358 
00359       template<typename _UHead>
00360         explicit
00361         constexpr _Tuple_impl(_UHead&& __head)
00362         : _Base(std::forward<_UHead>(__head)) { }
00363 
00364       constexpr _Tuple_impl(const _Tuple_impl&) = default;
00365 
00366       constexpr
00367       _Tuple_impl(_Tuple_impl&& __in)
00368       noexcept(is_nothrow_move_constructible<_Head>::value)
00369       : _Base(std::forward<_Head>(_M_head(__in))) { }
00370 
00371       template<typename _UHead>
00372         constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in)
00373         : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in)) { }
00374 
00375       template<typename _UHead>
00376         constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in)
00377         : _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
00378         { }
00379 
00380       template<typename _Alloc>
00381         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
00382         : _Base(__tag, __use_alloc<_Head>(__a)) { }
00383 
00384       template<typename _Alloc>
00385         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
00386                     const _Head& __head)
00387         : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { }
00388 
00389       template<typename _Alloc, typename _UHead>
00390         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
00391                     _UHead&& __head)
00392         : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
00393                 std::forward<_UHead>(__head)) { }
00394 
00395       template<typename _Alloc>
00396         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
00397                     const _Tuple_impl& __in)
00398         : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { }
00399 
00400       template<typename _Alloc>
00401         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
00402                     _Tuple_impl&& __in)
00403         : _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
00404                 std::forward<_Head>(_M_head(__in))) { }
00405 
00406       template<typename _Alloc, typename _UHead>
00407         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
00408                     const _Tuple_impl<_Idx, _UHead>& __in)
00409         : _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
00410                 _Tuple_impl<_Idx, _UHead>::_M_head(__in)) { }
00411 
00412       template<typename _Alloc, typename _UHead>
00413         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
00414                     _Tuple_impl<_Idx, _UHead>&& __in)
00415         : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
00416                 std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
00417         { }
00418 
00419       _Tuple_impl&
00420       operator=(const _Tuple_impl& __in)
00421       {
00422         _M_head(*this) = _M_head(__in);
00423         return *this;
00424       }
00425 
00426       _Tuple_impl&
00427       operator=(_Tuple_impl&& __in)
00428       noexcept(is_nothrow_move_assignable<_Head>::value)
00429       {
00430         _M_head(*this) = std::forward<_Head>(_M_head(__in));
00431         return *this;
00432       }
00433 
00434       template<typename _UHead>
00435         _Tuple_impl&
00436         operator=(const _Tuple_impl<_Idx, _UHead>& __in)
00437         {
00438           _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in);
00439           return *this;
00440         }
00441 
00442       template<typename _UHead>
00443         _Tuple_impl&
00444         operator=(_Tuple_impl<_Idx, _UHead>&& __in)
00445         {
00446           _M_head(*this)
00447             = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in));
00448           return *this;
00449         }
00450 
00451     protected:
00452       void
00453       _M_swap(_Tuple_impl& __in)
00454       noexcept(noexcept(swap(std::declval<_Head&>(), std::declval<_Head&>())))
00455       {
00456         using std::swap;
00457         swap(_M_head(*this), _M_head(__in));
00458       }
00459     };
00460 
00461   /// Primary class template, tuple
00462   template<typename... _Elements> 
00463     class tuple : public _Tuple_impl<0, _Elements...>
00464     {
00465       typedef _Tuple_impl<0, _Elements...> _Inherited;
00466 
00467     public:
00468       constexpr tuple()
00469       : _Inherited() { }
00470 
00471       explicit
00472       constexpr tuple(const _Elements&... __elements)
00473       : _Inherited(__elements...) { }
00474 
00475       template<typename... _UElements, typename = typename
00476         enable_if<__and_<is_convertible<_UElements,
00477                                         _Elements>...>::value>::type>
00478         explicit
00479         constexpr tuple(_UElements&&... __elements)
00480         : _Inherited(std::forward<_UElements>(__elements)...) { }
00481 
00482       constexpr tuple(const tuple&) = default;
00483 
00484       constexpr tuple(tuple&&) = default; 
00485 
00486       template<typename... _UElements, typename = typename
00487         enable_if<__and_<is_convertible<const _UElements&,
00488                                         _Elements>...>::value>::type>
00489         constexpr tuple(const tuple<_UElements...>& __in)
00490         : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
00491         { }
00492 
00493       template<typename... _UElements, typename = typename
00494         enable_if<__and_<is_convertible<_UElements,
00495                                         _Elements>...>::value>::type>
00496         constexpr tuple(tuple<_UElements...>&& __in)
00497         : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
00498 
00499       // Allocator-extended constructors.
00500 
00501       template<typename _Alloc>
00502         tuple(allocator_arg_t __tag, const _Alloc& __a)
00503         : _Inherited(__tag, __a) { }
00504 
00505       template<typename _Alloc>
00506         tuple(allocator_arg_t __tag, const _Alloc& __a,
00507               const _Elements&... __elements)
00508         : _Inherited(__tag, __a, __elements...) { }
00509 
00510       template<typename _Alloc, typename... _UElements, typename = typename
00511                enable_if<sizeof...(_UElements)
00512                          == sizeof...(_Elements)>::type>
00513         tuple(allocator_arg_t __tag, const _Alloc& __a,
00514               _UElements&&... __elements)
00515         : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
00516         { }
00517 
00518       template<typename _Alloc>
00519         tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
00520         : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
00521 
00522       template<typename _Alloc>
00523         tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
00524         : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
00525 
00526       template<typename _Alloc, typename... _UElements, typename = typename
00527                enable_if<sizeof...(_UElements)
00528                          == sizeof...(_Elements)>::type>
00529         tuple(allocator_arg_t __tag, const _Alloc& __a,
00530               const tuple<_UElements...>& __in)
00531         : _Inherited(__tag, __a,
00532                      static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
00533         { }
00534 
00535       template<typename _Alloc, typename... _UElements, typename = typename
00536                enable_if<sizeof...(_UElements)
00537                          == sizeof...(_Elements)>::type>
00538         tuple(allocator_arg_t __tag, const _Alloc& __a,
00539               tuple<_UElements...>&& __in)
00540         : _Inherited(__tag, __a,
00541                      static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
00542         { }
00543 
00544       tuple&
00545       operator=(const tuple& __in)
00546       {
00547         static_cast<_Inherited&>(*this) = __in;
00548         return *this;
00549       }
00550 
00551       tuple&
00552       operator=(tuple&& __in)
00553       noexcept(is_nothrow_move_assignable<_Inherited>::value)
00554       {
00555         static_cast<_Inherited&>(*this) = std::move(__in);
00556         return *this;
00557       }
00558 
00559       template<typename... _UElements, typename = typename
00560                enable_if<sizeof...(_UElements)
00561                          == sizeof...(_Elements)>::type>
00562         tuple&
00563         operator=(const tuple<_UElements...>& __in)
00564         {
00565           static_cast<_Inherited&>(*this) = __in;
00566           return *this;
00567         }
00568 
00569       template<typename... _UElements, typename = typename
00570                enable_if<sizeof...(_UElements)
00571                          == sizeof...(_Elements)>::type>
00572         tuple&
00573         operator=(tuple<_UElements...>&& __in)
00574         {
00575           static_cast<_Inherited&>(*this) = std::move(__in);
00576           return *this;
00577         }
00578 
00579       void
00580       swap(tuple& __in)
00581       noexcept(noexcept(__in._M_swap(__in)))
00582       { _Inherited::_M_swap(__in); }
00583     };
00584 
00585   // Explicit specialization, zero-element tuple.
00586   template<>  
00587     class tuple<>
00588     {
00589     public:
00590       void swap(tuple&) noexcept { /* no-op */ }
00591     };
00592 
00593   /// Partial specialization, 2-element tuple.
00594   /// Includes construction and assignment from a pair.
00595   template<typename _T1, typename _T2>
00596     class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
00597     {
00598       typedef _Tuple_impl<0, _T1, _T2> _Inherited;
00599 
00600     public:
00601       constexpr tuple()
00602       : _Inherited() { }
00603 
00604       explicit
00605       constexpr tuple(const _T1& __a1, const _T2& __a2)
00606       : _Inherited(__a1, __a2) { }
00607 
00608       template<typename _U1, typename _U2, typename = typename
00609                enable_if<__and_<is_convertible<_U1, _T1>,
00610                                 is_convertible<_U2, _T2>>::value>::type>
00611         explicit
00612         constexpr tuple(_U1&& __a1, _U2&& __a2)
00613         : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
00614 
00615       constexpr tuple(const tuple&) = default;
00616 
00617       constexpr tuple(tuple&&) = default;
00618 
00619       template<typename _U1, typename _U2, typename = typename
00620         enable_if<__and_<is_convertible<const _U1&, _T1>,
00621                          is_convertible<const _U2&, _T2>>::value>::type>
00622         constexpr tuple(const tuple<_U1, _U2>& __in)
00623         : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
00624 
00625       template<typename _U1, typename _U2, typename = typename
00626                enable_if<__and_<is_convertible<_U1, _T1>,
00627                                 is_convertible<_U2, _T2>>::value>::type>
00628         constexpr tuple(tuple<_U1, _U2>&& __in)
00629         : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
00630 
00631       template<typename _U1, typename _U2, typename = typename
00632         enable_if<__and_<is_convertible<const _U1&, _T1>,
00633                          is_convertible<const _U2&, _T2>>::value>::type>
00634         constexpr tuple(const pair<_U1, _U2>& __in)
00635         : _Inherited(__in.first, __in.second) { }
00636 
00637       template<typename _U1, typename _U2, typename = typename
00638                enable_if<__and_<is_convertible<_U1, _T1>,
00639                                 is_convertible<_U2, _T2>>::value>::type>
00640         constexpr tuple(pair<_U1, _U2>&& __in)
00641         : _Inherited(std::forward<_U1>(__in.first),
00642                      std::forward<_U2>(__in.second)) { }
00643 
00644       // Allocator-extended constructors.
00645 
00646       template<typename _Alloc>
00647         tuple(allocator_arg_t __tag, const _Alloc& __a)
00648         : _Inherited(__tag, __a) { }
00649 
00650       template<typename _Alloc>
00651         tuple(allocator_arg_t __tag, const _Alloc& __a,
00652               const _T1& __a1, const _T2& __a2)
00653         : _Inherited(__tag, __a, __a1, __a2) { }
00654 
00655       template<typename _Alloc, typename _U1, typename _U2>
00656         tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2)
00657         : _Inherited(__tag, __a, std::forward<_U1>(__a1),
00658                      std::forward<_U2>(__a2)) { }
00659 
00660       template<typename _Alloc>
00661         tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
00662         : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
00663 
00664       template<typename _Alloc>
00665         tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
00666         : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
00667 
00668       template<typename _Alloc, typename _U1, typename _U2>
00669         tuple(allocator_arg_t __tag, const _Alloc& __a,
00670               const tuple<_U1, _U2>& __in)
00671         : _Inherited(__tag, __a,
00672                      static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
00673         { }
00674 
00675       template<typename _Alloc, typename _U1, typename _U2>
00676         tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
00677         : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
00678         { }
00679 
00680       template<typename _Alloc, typename _U1, typename _U2>
00681         tuple(allocator_arg_t __tag, const _Alloc& __a,
00682               const pair<_U1, _U2>& __in)
00683         : _Inherited(__tag, __a, __in.first, __in.second) { }
00684 
00685       template<typename _Alloc, typename _U1, typename _U2>
00686         tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
00687         : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
00688                      std::forward<_U2>(__in.second)) { }
00689 
00690       tuple&
00691       operator=(const tuple& __in)
00692       {
00693         static_cast<_Inherited&>(*this) = __in;
00694         return *this;
00695       }
00696 
00697       tuple&
00698       operator=(tuple&& __in)
00699       noexcept(is_nothrow_move_assignable<_Inherited>::value)
00700       {
00701         static_cast<_Inherited&>(*this) = std::move(__in);
00702         return *this;
00703       }
00704 
00705       template<typename _U1, typename _U2>
00706         tuple&
00707         operator=(const tuple<_U1, _U2>& __in)
00708         {
00709           static_cast<_Inherited&>(*this) = __in;
00710           return *this;
00711         }
00712 
00713       template<typename _U1, typename _U2>
00714         tuple&
00715         operator=(tuple<_U1, _U2>&& __in)
00716         {
00717           static_cast<_Inherited&>(*this) = std::move(__in);
00718           return *this;
00719         }
00720 
00721       template<typename _U1, typename _U2>
00722         tuple&
00723         operator=(const pair<_U1, _U2>& __in)
00724         {
00725           this->_M_head(*this) = __in.first;
00726           this->_M_tail(*this)._M_head(*this) = __in.second;
00727           return *this;
00728         }
00729 
00730       template<typename _U1, typename _U2>
00731         tuple&
00732         operator=(pair<_U1, _U2>&& __in)
00733         {
00734           this->_M_head(*this) = std::forward<_U1>(__in.first);
00735           this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second);
00736           return *this;
00737         }
00738 
00739       void
00740       swap(tuple& __in)
00741       noexcept(noexcept(__in._M_swap(__in)))
00742       { _Inherited::_M_swap(__in); }
00743     };
00744 
00745 
00746   /// Gives the type of the ith element of a given tuple type.
00747   template<std::size_t __i, typename _Tp>
00748     struct tuple_element;
00749 
00750   /**
00751    * Recursive case for tuple_element: strip off the first element in
00752    * the tuple and retrieve the (i-1)th element of the remaining tuple.
00753    */
00754   template<std::size_t __i, typename _Head, typename... _Tail>
00755     struct tuple_element<__i, tuple<_Head, _Tail...> >
00756     : tuple_element<__i - 1, tuple<_Tail...> > { };
00757 
00758   /**
00759    * Basis case for tuple_element: The first element is the one we're seeking.
00760    */
00761   template<typename _Head, typename... _Tail>
00762     struct tuple_element<0, tuple<_Head, _Tail...> >
00763     {
00764       typedef _Head type;
00765     };
00766 
00767   // Duplicate of C++14's tuple_element_t for internal use in C++11 mode
00768   template<std::size_t __i, typename _Tp>
00769     using __tuple_element_t = typename tuple_element<__i, _Tp>::type;
00770 
00771   template<std::size_t __i, typename _Tp>
00772     struct tuple_element<__i, const _Tp>
00773     {
00774       typedef typename add_const<__tuple_element_t<__i, _Tp>>::type type;
00775     };
00776 
00777   template<std::size_t __i, typename _Tp>
00778     struct tuple_element<__i, volatile _Tp>
00779     {
00780       typedef typename add_volatile<__tuple_element_t<__i, _Tp>>::type type;
00781     };
00782 
00783   template<std::size_t __i, typename _Tp>
00784     struct tuple_element<__i, const volatile _Tp>
00785     {
00786       typedef typename add_cv<__tuple_element_t<__i, _Tp>>::type type;
00787     };
00788 
00789 #if __cplusplus > 201103L
00790 #define __cpp_lib_tuple_element_t 201402
00791 
00792   template<std::size_t __i, typename _Tp>
00793     using tuple_element_t = typename tuple_element<__i, _Tp>::type;
00794 #endif
00795 
00796   /// Finds the size of a given tuple type.
00797   template<typename _Tp>
00798     struct tuple_size;
00799 
00800   // _GLIBCXX_RESOLVE_LIB_DEFECTS
00801   // 2313. tuple_size should always derive from integral_constant<size_t, N>
00802   template<typename _Tp>
00803     struct tuple_size<const _Tp>
00804     : integral_constant<size_t, tuple_size<_Tp>::value> { };
00805 
00806   template<typename _Tp>
00807     struct tuple_size<volatile _Tp>
00808     : integral_constant<size_t, tuple_size<_Tp>::value> { };
00809 
00810   template<typename _Tp>
00811     struct tuple_size<const volatile _Tp>
00812     : integral_constant<size_t, tuple_size<_Tp>::value> { };
00813 
00814   /// class tuple_size
00815   template<typename... _Elements>
00816     struct tuple_size<tuple<_Elements...>>
00817     : public integral_constant<std::size_t, sizeof...(_Elements)> { };
00818 
00819   template<std::size_t __i, typename _Head, typename... _Tail>
00820     constexpr _Head&
00821     __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
00822     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
00823 
00824   template<std::size_t __i, typename _Head, typename... _Tail>
00825     constexpr const _Head&
00826     __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
00827     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
00828 
00829   /// Return a reference to the ith element of a tuple.
00830   template<std::size_t __i, typename... _Elements>
00831     constexpr __tuple_element_t<__i, tuple<_Elements...>>&
00832     get(tuple<_Elements...>& __t) noexcept
00833     { return std::__get_helper<__i>(__t); }
00834 
00835   /// Return a const reference to the ith element of a const tuple.
00836   template<std::size_t __i, typename... _Elements>
00837     constexpr const __tuple_element_t<__i, tuple<_Elements...>>&
00838     get(const tuple<_Elements...>& __t) noexcept
00839     { return std::__get_helper<__i>(__t); }
00840 
00841   /// Return an rvalue reference to the ith element of a tuple rvalue.
00842   template<std::size_t __i, typename... _Elements>
00843     constexpr __tuple_element_t<__i, tuple<_Elements...>>&&
00844     get(tuple<_Elements...>&& __t) noexcept
00845     {
00846       typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
00847       return std::forward<__element_type&&>(std::get<__i>(__t));
00848     }
00849 
00850 #if __cplusplus > 201103L
00851 
00852 #define __cpp_lib_tuples_by_type 201304
00853 
00854   template<typename _Head, size_t __i, typename... _Tail>
00855     constexpr _Head&
00856     __get_helper2(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
00857     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
00858 
00859   template<typename _Head, size_t __i, typename... _Tail>
00860     constexpr const _Head&
00861     __get_helper2(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
00862     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
00863 
00864   /// Return a reference to the unique element of type _Tp of a tuple.
00865   template <typename _Tp, typename... _Types>
00866     constexpr _Tp&
00867     get(tuple<_Types...>& __t) noexcept
00868     { return std::__get_helper2<_Tp>(__t); }
00869 
00870   /// Return a reference to the unique element of type _Tp of a tuple rvalue.
00871   template <typename _Tp, typename... _Types>
00872     constexpr _Tp&&
00873     get(tuple<_Types...>&& __t) noexcept
00874     { return std::forward<_Tp&&>(std::__get_helper2<_Tp>(__t)); }
00875 
00876   /// Return a const reference to the unique element of type _Tp of a tuple.
00877   template <typename _Tp, typename... _Types>
00878     constexpr const _Tp&
00879     get(const tuple<_Types...>& __t) noexcept
00880     { return std::__get_helper2<_Tp>(__t); }
00881 #endif
00882 
00883   // This class performs the comparison operations on tuples
00884   template<typename _Tp, typename _Up, size_t __i, size_t __size>
00885     struct __tuple_compare
00886     {
00887       static constexpr bool
00888       __eq(const _Tp& __t, const _Up& __u)
00889       {
00890         return bool(std::get<__i>(__t) == std::get<__i>(__u))
00891           && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u);
00892       }
00893    
00894       static constexpr bool
00895       __less(const _Tp& __t, const _Up& __u)
00896       {
00897         return bool(std::get<__i>(__t) < std::get<__i>(__u))
00898           || (!bool(std::get<__i>(__u) < std::get<__i>(__t))
00899               && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u));
00900       }
00901     };
00902 
00903   template<typename _Tp, typename _Up, size_t __size>
00904     struct __tuple_compare<_Tp, _Up, __size, __size>
00905     {
00906       static constexpr bool
00907       __eq(const _Tp&, const _Up&) { return true; }
00908    
00909       static constexpr bool
00910       __less(const _Tp&, const _Up&) { return false; }
00911     };
00912 
00913   template<typename... _TElements, typename... _UElements>
00914     constexpr bool
00915     operator==(const tuple<_TElements...>& __t,
00916                const tuple<_UElements...>& __u)
00917     {
00918       static_assert(sizeof...(_TElements) == sizeof...(_UElements),
00919           "tuple objects can only be compared if they have equal sizes.");
00920       using __compare = __tuple_compare<tuple<_TElements...>,
00921                                         tuple<_UElements...>,
00922                                         0, sizeof...(_TElements)>;
00923       return __compare::__eq(__t, __u);
00924     }
00925 
00926   template<typename... _TElements, typename... _UElements>
00927     constexpr bool
00928     operator<(const tuple<_TElements...>& __t,
00929               const tuple<_UElements...>& __u)
00930     {
00931       static_assert(sizeof...(_TElements) == sizeof...(_UElements),
00932           "tuple objects can only be compared if they have equal sizes.");
00933       using __compare = __tuple_compare<tuple<_TElements...>,
00934                                         tuple<_UElements...>,
00935                                         0, sizeof...(_TElements)>;
00936       return __compare::__less(__t, __u);
00937     }
00938 
00939   template<typename... _TElements, typename... _UElements>
00940     constexpr bool
00941     operator!=(const tuple<_TElements...>& __t,
00942                const tuple<_UElements...>& __u)
00943     { return !(__t == __u); }
00944 
00945   template<typename... _TElements, typename... _UElements>
00946     constexpr bool
00947     operator>(const tuple<_TElements...>& __t,
00948               const tuple<_UElements...>& __u)
00949     { return __u < __t; }
00950 
00951   template<typename... _TElements, typename... _UElements>
00952     constexpr bool
00953     operator<=(const tuple<_TElements...>& __t,
00954                const tuple<_UElements...>& __u)
00955     { return !(__u < __t); }
00956 
00957   template<typename... _TElements, typename... _UElements>
00958     constexpr bool
00959     operator>=(const tuple<_TElements...>& __t,
00960                const tuple<_UElements...>& __u)
00961     { return !(__t < __u); }
00962 
00963   // NB: DR 705.
00964   template<typename... _Elements>
00965     constexpr tuple<typename __decay_and_strip<_Elements>::__type...>
00966     make_tuple(_Elements&&... __args)
00967     {
00968       typedef tuple<typename __decay_and_strip<_Elements>::__type...>
00969         __result_type;
00970       return __result_type(std::forward<_Elements>(__args)...);
00971     }
00972 
00973   template<typename... _Elements>
00974     tuple<_Elements&&...>
00975     forward_as_tuple(_Elements&&... __args) noexcept
00976     { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
00977 
00978   template<typename>
00979     struct __is_tuple_like_impl : false_type
00980     { };
00981 
00982   template<typename... _Tps>
00983     struct __is_tuple_like_impl<tuple<_Tps...>> : true_type
00984     { };
00985 
00986   template<typename _T1, typename _T2>
00987     struct __is_tuple_like_impl<pair<_T1, _T2>> : true_type
00988     { };
00989 
00990   template<typename _Tp, std::size_t _Nm>
00991     struct __is_tuple_like_impl<array<_Tp, _Nm>> : true_type
00992     { };
00993 
00994   // Internal type trait that allows us to sfinae-protect tuple_cat.
00995   template<typename _Tp>
00996     struct __is_tuple_like
00997     : public __is_tuple_like_impl<typename std::remove_cv
00998             <typename std::remove_reference<_Tp>::type>::type>::type
00999     { };
01000 
01001   template<size_t, typename, typename, size_t>
01002     struct __make_tuple_impl;
01003 
01004   template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm>
01005     struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm>
01006     : __make_tuple_impl<_Idx + 1,
01007                         tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>,
01008                         _Tuple, _Nm>
01009     { };
01010 
01011   template<std::size_t _Nm, typename _Tuple, typename... _Tp>
01012     struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm>
01013     {
01014       typedef tuple<_Tp...> __type;
01015     };
01016 
01017   template<typename _Tuple>
01018     struct __do_make_tuple
01019     : __make_tuple_impl<0, tuple<>, _Tuple, std::tuple_size<_Tuple>::value>
01020     { };
01021 
01022   // Returns the std::tuple equivalent of a tuple-like type.
01023   template<typename _Tuple>
01024     struct __make_tuple
01025     : public __do_make_tuple<typename std::remove_cv
01026             <typename std::remove_reference<_Tuple>::type>::type>
01027     { };
01028 
01029   // Combines several std::tuple's into a single one.
01030   template<typename...>
01031     struct __combine_tuples;
01032 
01033   template<>
01034     struct __combine_tuples<>
01035     {
01036       typedef tuple<> __type;
01037     };
01038 
01039   template<typename... _Ts>
01040     struct __combine_tuples<tuple<_Ts...>>
01041     {
01042       typedef tuple<_Ts...> __type;
01043     };
01044 
01045   template<typename... _T1s, typename... _T2s, typename... _Rem>
01046     struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...>
01047     {
01048       typedef typename __combine_tuples<tuple<_T1s..., _T2s...>,
01049                                         _Rem...>::__type __type;
01050     };
01051 
01052   // Computes the result type of tuple_cat given a set of tuple-like types.
01053   template<typename... _Tpls>
01054     struct __tuple_cat_result
01055     {
01056       typedef typename __combine_tuples
01057         <typename __make_tuple<_Tpls>::__type...>::__type __type;
01058     };
01059 
01060   // Helper to determine the index set for the first tuple-like
01061   // type of a given set.
01062   template<typename...>
01063     struct __make_1st_indices;
01064 
01065   template<>
01066     struct __make_1st_indices<>
01067     {
01068       typedef std::_Index_tuple<> __type;
01069     };
01070 
01071   template<typename _Tp, typename... _Tpls>
01072     struct __make_1st_indices<_Tp, _Tpls...>
01073     {
01074       typedef typename std::_Build_index_tuple<std::tuple_size<
01075         typename std::remove_reference<_Tp>::type>::value>::__type __type;
01076     };
01077 
01078   // Performs the actual concatenation by step-wise expanding tuple-like
01079   // objects into the elements,  which are finally forwarded into the
01080   // result tuple.
01081   template<typename _Ret, typename _Indices, typename... _Tpls>
01082     struct __tuple_concater;
01083 
01084   template<typename _Ret, std::size_t... _Is, typename _Tp, typename... _Tpls>
01085     struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...>
01086     {
01087       template<typename... _Us>
01088         static constexpr _Ret
01089         _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us)
01090         {
01091           typedef typename __make_1st_indices<_Tpls...>::__type __idx;
01092           typedef __tuple_concater<_Ret, __idx, _Tpls...>      __next;
01093           return __next::_S_do(std::forward<_Tpls>(__tps)...,
01094                                std::forward<_Us>(__us)...,
01095                                std::get<_Is>(std::forward<_Tp>(__tp))...);
01096         }
01097     };
01098 
01099   template<typename _Ret>
01100     struct __tuple_concater<_Ret, std::_Index_tuple<>>
01101     {
01102       template<typename... _Us>
01103         static constexpr _Ret
01104         _S_do(_Us&&... __us)
01105         {
01106           return _Ret(std::forward<_Us>(__us)...);
01107         }
01108     };
01109 
01110   /// tuple_cat
01111   template<typename... _Tpls, typename = typename
01112            enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type>
01113     constexpr auto
01114     tuple_cat(_Tpls&&... __tpls)
01115     -> typename __tuple_cat_result<_Tpls...>::__type
01116     {
01117       typedef typename __tuple_cat_result<_Tpls...>::__type __ret;
01118       typedef typename __make_1st_indices<_Tpls...>::__type __idx;
01119       typedef __tuple_concater<__ret, __idx, _Tpls...> __concater;
01120       return __concater::_S_do(std::forward<_Tpls>(__tpls)...);
01121     }
01122 
01123   /// tie
01124   template<typename... _Elements>
01125     inline tuple<_Elements&...>
01126     tie(_Elements&... __args) noexcept
01127     { return tuple<_Elements&...>(__args...); }
01128 
01129   /// swap
01130   template<typename... _Elements>
01131     inline void 
01132     swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
01133     noexcept(noexcept(__x.swap(__y)))
01134     { __x.swap(__y); }
01135 
01136   // A class (and instance) which can be used in 'tie' when an element
01137   // of a tuple is not required
01138   struct _Swallow_assign
01139   {
01140     template<class _Tp>
01141       const _Swallow_assign&
01142       operator=(const _Tp&) const
01143       { return *this; }
01144   };
01145 
01146   const _Swallow_assign ignore{};
01147 
01148   /// Partial specialization for tuples
01149   template<typename... _Types, typename _Alloc>
01150     struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { };
01151 
01152   // See stl_pair.h...
01153   template<class _T1, class _T2>
01154     template<typename... _Args1, typename... _Args2>
01155       inline
01156       pair<_T1, _T2>::
01157       pair(piecewise_construct_t,
01158            tuple<_Args1...> __first, tuple<_Args2...> __second)
01159       : pair(__first, __second,
01160              typename _Build_index_tuple<sizeof...(_Args1)>::__type(),
01161              typename _Build_index_tuple<sizeof...(_Args2)>::__type())
01162       { }
01163 
01164   template<class _T1, class _T2>
01165     template<typename... _Args1, std::size_t... _Indexes1,
01166              typename... _Args2, std::size_t... _Indexes2>
01167       inline
01168       pair<_T1, _T2>::
01169       pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2,
01170            _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)
01171       : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...),
01172         second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
01173       { }
01174 
01175   /// @}
01176 
01177 _GLIBCXX_END_NAMESPACE_VERSION
01178 } // namespace std
01179 
01180 #endif // C++11
01181 
01182 #endif // _GLIBCXX_TUPLE