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>,
00611                                 __not_<is_same<typename decay<_U1>::type,
00612                                                allocator_arg_t>>>
00613                          ::value>::type>
00614         explicit
00615         constexpr tuple(_U1&& __a1, _U2&& __a2)
00616         : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
00617 
00618       constexpr tuple(const tuple&) = default;
00619 
00620       constexpr tuple(tuple&&) = default;
00621 
00622       template<typename _U1, typename _U2, typename = typename
00623         enable_if<__and_<is_convertible<const _U1&, _T1>,
00624                          is_convertible<const _U2&, _T2>>::value>::type>
00625         constexpr tuple(const tuple<_U1, _U2>& __in)
00626         : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
00627 
00628       template<typename _U1, typename _U2, typename = typename
00629                enable_if<__and_<is_convertible<_U1, _T1>,
00630                                 is_convertible<_U2, _T2>>::value>::type>
00631         constexpr tuple(tuple<_U1, _U2>&& __in)
00632         : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
00633 
00634       template<typename _U1, typename _U2, typename = typename
00635         enable_if<__and_<is_convertible<const _U1&, _T1>,
00636                          is_convertible<const _U2&, _T2>>::value>::type>
00637         constexpr tuple(const pair<_U1, _U2>& __in)
00638         : _Inherited(__in.first, __in.second) { }
00639 
00640       template<typename _U1, typename _U2, typename = typename
00641                enable_if<__and_<is_convertible<_U1, _T1>,
00642                                 is_convertible<_U2, _T2>>::value>::type>
00643         constexpr tuple(pair<_U1, _U2>&& __in)
00644         : _Inherited(std::forward<_U1>(__in.first),
00645                      std::forward<_U2>(__in.second)) { }
00646 
00647       // Allocator-extended constructors.
00648 
00649       template<typename _Alloc>
00650         tuple(allocator_arg_t __tag, const _Alloc& __a)
00651         : _Inherited(__tag, __a) { }
00652 
00653       template<typename _Alloc>
00654         tuple(allocator_arg_t __tag, const _Alloc& __a,
00655               const _T1& __a1, const _T2& __a2)
00656         : _Inherited(__tag, __a, __a1, __a2) { }
00657 
00658       template<typename _Alloc, typename _U1, typename _U2>
00659         tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2)
00660         : _Inherited(__tag, __a, std::forward<_U1>(__a1),
00661                      std::forward<_U2>(__a2)) { }
00662 
00663       template<typename _Alloc>
00664         tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
00665         : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
00666 
00667       template<typename _Alloc>
00668         tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
00669         : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
00670 
00671       template<typename _Alloc, typename _U1, typename _U2>
00672         tuple(allocator_arg_t __tag, const _Alloc& __a,
00673               const tuple<_U1, _U2>& __in)
00674         : _Inherited(__tag, __a,
00675                      static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
00676         { }
00677 
00678       template<typename _Alloc, typename _U1, typename _U2>
00679         tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
00680         : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
00681         { }
00682 
00683       template<typename _Alloc, typename _U1, typename _U2>
00684         tuple(allocator_arg_t __tag, const _Alloc& __a,
00685               const pair<_U1, _U2>& __in)
00686         : _Inherited(__tag, __a, __in.first, __in.second) { }
00687 
00688       template<typename _Alloc, typename _U1, typename _U2>
00689         tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
00690         : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
00691                      std::forward<_U2>(__in.second)) { }
00692 
00693       tuple&
00694       operator=(const tuple& __in)
00695       {
00696         static_cast<_Inherited&>(*this) = __in;
00697         return *this;
00698       }
00699 
00700       tuple&
00701       operator=(tuple&& __in)
00702       noexcept(is_nothrow_move_assignable<_Inherited>::value)
00703       {
00704         static_cast<_Inherited&>(*this) = std::move(__in);
00705         return *this;
00706       }
00707 
00708       template<typename _U1, typename _U2>
00709         tuple&
00710         operator=(const tuple<_U1, _U2>& __in)
00711         {
00712           static_cast<_Inherited&>(*this) = __in;
00713           return *this;
00714         }
00715 
00716       template<typename _U1, typename _U2>
00717         tuple&
00718         operator=(tuple<_U1, _U2>&& __in)
00719         {
00720           static_cast<_Inherited&>(*this) = std::move(__in);
00721           return *this;
00722         }
00723 
00724       template<typename _U1, typename _U2>
00725         tuple&
00726         operator=(const pair<_U1, _U2>& __in)
00727         {
00728           this->_M_head(*this) = __in.first;
00729           this->_M_tail(*this)._M_head(*this) = __in.second;
00730           return *this;
00731         }
00732 
00733       template<typename _U1, typename _U2>
00734         tuple&
00735         operator=(pair<_U1, _U2>&& __in)
00736         {
00737           this->_M_head(*this) = std::forward<_U1>(__in.first);
00738           this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second);
00739           return *this;
00740         }
00741 
00742       void
00743       swap(tuple& __in)
00744       noexcept(noexcept(__in._M_swap(__in)))
00745       { _Inherited::_M_swap(__in); }
00746     };
00747 
00748 
00749   /// Gives the type of the ith element of a given tuple type.
00750   template<std::size_t __i, typename _Tp>
00751     struct tuple_element;
00752 
00753   /**
00754    * Recursive case for tuple_element: strip off the first element in
00755    * the tuple and retrieve the (i-1)th element of the remaining tuple.
00756    */
00757   template<std::size_t __i, typename _Head, typename... _Tail>
00758     struct tuple_element<__i, tuple<_Head, _Tail...> >
00759     : tuple_element<__i - 1, tuple<_Tail...> > { };
00760 
00761   /**
00762    * Basis case for tuple_element: The first element is the one we're seeking.
00763    */
00764   template<typename _Head, typename... _Tail>
00765     struct tuple_element<0, tuple<_Head, _Tail...> >
00766     {
00767       typedef _Head type;
00768     };
00769 
00770   // Duplicate of C++14's tuple_element_t for internal use in C++11 mode
00771   template<std::size_t __i, typename _Tp>
00772     using __tuple_element_t = typename tuple_element<__i, _Tp>::type;
00773 
00774   template<std::size_t __i, typename _Tp>
00775     struct tuple_element<__i, const _Tp>
00776     {
00777       typedef typename add_const<__tuple_element_t<__i, _Tp>>::type type;
00778     };
00779 
00780   template<std::size_t __i, typename _Tp>
00781     struct tuple_element<__i, volatile _Tp>
00782     {
00783       typedef typename add_volatile<__tuple_element_t<__i, _Tp>>::type type;
00784     };
00785 
00786   template<std::size_t __i, typename _Tp>
00787     struct tuple_element<__i, const volatile _Tp>
00788     {
00789       typedef typename add_cv<__tuple_element_t<__i, _Tp>>::type type;
00790     };
00791 
00792 #if __cplusplus > 201103L
00793 #define __cpp_lib_tuple_element_t 201402
00794 
00795   template<std::size_t __i, typename _Tp>
00796     using tuple_element_t = typename tuple_element<__i, _Tp>::type;
00797 #endif
00798 
00799   /// Finds the size of a given tuple type.
00800   template<typename _Tp>
00801     struct tuple_size;
00802 
00803   // _GLIBCXX_RESOLVE_LIB_DEFECTS
00804   // 2313. tuple_size should always derive from integral_constant<size_t, N>
00805   template<typename _Tp>
00806     struct tuple_size<const _Tp>
00807     : integral_constant<size_t, tuple_size<_Tp>::value> { };
00808 
00809   template<typename _Tp>
00810     struct tuple_size<volatile _Tp>
00811     : integral_constant<size_t, tuple_size<_Tp>::value> { };
00812 
00813   template<typename _Tp>
00814     struct tuple_size<const volatile _Tp>
00815     : integral_constant<size_t, tuple_size<_Tp>::value> { };
00816 
00817   /// class tuple_size
00818   template<typename... _Elements>
00819     struct tuple_size<tuple<_Elements...>>
00820     : public integral_constant<std::size_t, sizeof...(_Elements)> { };
00821 
00822   template<std::size_t __i, typename _Head, typename... _Tail>
00823     constexpr _Head&
00824     __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
00825     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
00826 
00827   template<std::size_t __i, typename _Head, typename... _Tail>
00828     constexpr const _Head&
00829     __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
00830     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
00831 
00832   /// Return a reference to the ith element of a tuple.
00833   template<std::size_t __i, typename... _Elements>
00834     constexpr __tuple_element_t<__i, tuple<_Elements...>>&
00835     get(tuple<_Elements...>& __t) noexcept
00836     { return std::__get_helper<__i>(__t); }
00837 
00838   /// Return a const reference to the ith element of a const tuple.
00839   template<std::size_t __i, typename... _Elements>
00840     constexpr const __tuple_element_t<__i, tuple<_Elements...>>&
00841     get(const tuple<_Elements...>& __t) noexcept
00842     { return std::__get_helper<__i>(__t); }
00843 
00844   /// Return an rvalue reference to the ith element of a tuple rvalue.
00845   template<std::size_t __i, typename... _Elements>
00846     constexpr __tuple_element_t<__i, tuple<_Elements...>>&&
00847     get(tuple<_Elements...>&& __t) noexcept
00848     {
00849       typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
00850       return std::forward<__element_type&&>(std::get<__i>(__t));
00851     }
00852 
00853 #if __cplusplus > 201103L
00854 
00855 #define __cpp_lib_tuples_by_type 201304
00856 
00857   template<typename _Head, size_t __i, typename... _Tail>
00858     constexpr _Head&
00859     __get_helper2(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
00860     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
00861 
00862   template<typename _Head, size_t __i, typename... _Tail>
00863     constexpr const _Head&
00864     __get_helper2(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
00865     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
00866 
00867   /// Return a reference to the unique element of type _Tp of a tuple.
00868   template <typename _Tp, typename... _Types>
00869     constexpr _Tp&
00870     get(tuple<_Types...>& __t) noexcept
00871     { return std::__get_helper2<_Tp>(__t); }
00872 
00873   /// Return a reference to the unique element of type _Tp of a tuple rvalue.
00874   template <typename _Tp, typename... _Types>
00875     constexpr _Tp&&
00876     get(tuple<_Types...>&& __t) noexcept
00877     { return std::forward<_Tp&&>(std::__get_helper2<_Tp>(__t)); }
00878 
00879   /// Return a const reference to the unique element of type _Tp of a tuple.
00880   template <typename _Tp, typename... _Types>
00881     constexpr const _Tp&
00882     get(const tuple<_Types...>& __t) noexcept
00883     { return std::__get_helper2<_Tp>(__t); }
00884 #endif
00885 
00886   // This class performs the comparison operations on tuples
00887   template<typename _Tp, typename _Up, size_t __i, size_t __size>
00888     struct __tuple_compare
00889     {
00890       static constexpr bool
00891       __eq(const _Tp& __t, const _Up& __u)
00892       {
00893         return bool(std::get<__i>(__t) == std::get<__i>(__u))
00894           && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u);
00895       }
00896    
00897       static constexpr bool
00898       __less(const _Tp& __t, const _Up& __u)
00899       {
00900         return bool(std::get<__i>(__t) < std::get<__i>(__u))
00901           || (!bool(std::get<__i>(__u) < std::get<__i>(__t))
00902               && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u));
00903       }
00904     };
00905 
00906   template<typename _Tp, typename _Up, size_t __size>
00907     struct __tuple_compare<_Tp, _Up, __size, __size>
00908     {
00909       static constexpr bool
00910       __eq(const _Tp&, const _Up&) { return true; }
00911    
00912       static constexpr bool
00913       __less(const _Tp&, const _Up&) { return false; }
00914     };
00915 
00916   template<typename... _TElements, typename... _UElements>
00917     constexpr bool
00918     operator==(const tuple<_TElements...>& __t,
00919                const tuple<_UElements...>& __u)
00920     {
00921       static_assert(sizeof...(_TElements) == sizeof...(_UElements),
00922           "tuple objects can only be compared if they have equal sizes.");
00923       using __compare = __tuple_compare<tuple<_TElements...>,
00924                                         tuple<_UElements...>,
00925                                         0, sizeof...(_TElements)>;
00926       return __compare::__eq(__t, __u);
00927     }
00928 
00929   template<typename... _TElements, typename... _UElements>
00930     constexpr bool
00931     operator<(const tuple<_TElements...>& __t,
00932               const tuple<_UElements...>& __u)
00933     {
00934       static_assert(sizeof...(_TElements) == sizeof...(_UElements),
00935           "tuple objects can only be compared if they have equal sizes.");
00936       using __compare = __tuple_compare<tuple<_TElements...>,
00937                                         tuple<_UElements...>,
00938                                         0, sizeof...(_TElements)>;
00939       return __compare::__less(__t, __u);
00940     }
00941 
00942   template<typename... _TElements, typename... _UElements>
00943     constexpr bool
00944     operator!=(const tuple<_TElements...>& __t,
00945                const tuple<_UElements...>& __u)
00946     { return !(__t == __u); }
00947 
00948   template<typename... _TElements, typename... _UElements>
00949     constexpr bool
00950     operator>(const tuple<_TElements...>& __t,
00951               const tuple<_UElements...>& __u)
00952     { return __u < __t; }
00953 
00954   template<typename... _TElements, typename... _UElements>
00955     constexpr bool
00956     operator<=(const tuple<_TElements...>& __t,
00957                const tuple<_UElements...>& __u)
00958     { return !(__u < __t); }
00959 
00960   template<typename... _TElements, typename... _UElements>
00961     constexpr bool
00962     operator>=(const tuple<_TElements...>& __t,
00963                const tuple<_UElements...>& __u)
00964     { return !(__t < __u); }
00965 
00966   // NB: DR 705.
00967   template<typename... _Elements>
00968     constexpr tuple<typename __decay_and_strip<_Elements>::__type...>
00969     make_tuple(_Elements&&... __args)
00970     {
00971       typedef tuple<typename __decay_and_strip<_Elements>::__type...>
00972         __result_type;
00973       return __result_type(std::forward<_Elements>(__args)...);
00974     }
00975 
00976   template<typename... _Elements>
00977     tuple<_Elements&&...>
00978     forward_as_tuple(_Elements&&... __args) noexcept
00979     { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
00980 
00981   template<typename>
00982     struct __is_tuple_like_impl : false_type
00983     { };
00984 
00985   template<typename... _Tps>
00986     struct __is_tuple_like_impl<tuple<_Tps...>> : true_type
00987     { };
00988 
00989   template<typename _T1, typename _T2>
00990     struct __is_tuple_like_impl<pair<_T1, _T2>> : true_type
00991     { };
00992 
00993   template<typename _Tp, std::size_t _Nm>
00994     struct __is_tuple_like_impl<array<_Tp, _Nm>> : true_type
00995     { };
00996 
00997   // Internal type trait that allows us to sfinae-protect tuple_cat.
00998   template<typename _Tp>
00999     struct __is_tuple_like
01000     : public __is_tuple_like_impl<typename std::remove_cv
01001             <typename std::remove_reference<_Tp>::type>::type>::type
01002     { };
01003 
01004   template<size_t, typename, typename, size_t>
01005     struct __make_tuple_impl;
01006 
01007   template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm>
01008     struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm>
01009     : __make_tuple_impl<_Idx + 1,
01010                         tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>,
01011                         _Tuple, _Nm>
01012     { };
01013 
01014   template<std::size_t _Nm, typename _Tuple, typename... _Tp>
01015     struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm>
01016     {
01017       typedef tuple<_Tp...> __type;
01018     };
01019 
01020   template<typename _Tuple>
01021     struct __do_make_tuple
01022     : __make_tuple_impl<0, tuple<>, _Tuple, std::tuple_size<_Tuple>::value>
01023     { };
01024 
01025   // Returns the std::tuple equivalent of a tuple-like type.
01026   template<typename _Tuple>
01027     struct __make_tuple
01028     : public __do_make_tuple<typename std::remove_cv
01029             <typename std::remove_reference<_Tuple>::type>::type>
01030     { };
01031 
01032   // Combines several std::tuple's into a single one.
01033   template<typename...>
01034     struct __combine_tuples;
01035 
01036   template<>
01037     struct __combine_tuples<>
01038     {
01039       typedef tuple<> __type;
01040     };
01041 
01042   template<typename... _Ts>
01043     struct __combine_tuples<tuple<_Ts...>>
01044     {
01045       typedef tuple<_Ts...> __type;
01046     };
01047 
01048   template<typename... _T1s, typename... _T2s, typename... _Rem>
01049     struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...>
01050     {
01051       typedef typename __combine_tuples<tuple<_T1s..., _T2s...>,
01052                                         _Rem...>::__type __type;
01053     };
01054 
01055   // Computes the result type of tuple_cat given a set of tuple-like types.
01056   template<typename... _Tpls>
01057     struct __tuple_cat_result
01058     {
01059       typedef typename __combine_tuples
01060         <typename __make_tuple<_Tpls>::__type...>::__type __type;
01061     };
01062 
01063   // Helper to determine the index set for the first tuple-like
01064   // type of a given set.
01065   template<typename...>
01066     struct __make_1st_indices;
01067 
01068   template<>
01069     struct __make_1st_indices<>
01070     {
01071       typedef std::_Index_tuple<> __type;
01072     };
01073 
01074   template<typename _Tp, typename... _Tpls>
01075     struct __make_1st_indices<_Tp, _Tpls...>
01076     {
01077       typedef typename std::_Build_index_tuple<std::tuple_size<
01078         typename std::remove_reference<_Tp>::type>::value>::__type __type;
01079     };
01080 
01081   // Performs the actual concatenation by step-wise expanding tuple-like
01082   // objects into the elements,  which are finally forwarded into the
01083   // result tuple.
01084   template<typename _Ret, typename _Indices, typename... _Tpls>
01085     struct __tuple_concater;
01086 
01087   template<typename _Ret, std::size_t... _Is, typename _Tp, typename... _Tpls>
01088     struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...>
01089     {
01090       template<typename... _Us>
01091         static constexpr _Ret
01092         _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us)
01093         {
01094           typedef typename __make_1st_indices<_Tpls...>::__type __idx;
01095           typedef __tuple_concater<_Ret, __idx, _Tpls...>      __next;
01096           return __next::_S_do(std::forward<_Tpls>(__tps)...,
01097                                std::forward<_Us>(__us)...,
01098                                std::get<_Is>(std::forward<_Tp>(__tp))...);
01099         }
01100     };
01101 
01102   template<typename _Ret>
01103     struct __tuple_concater<_Ret, std::_Index_tuple<>>
01104     {
01105       template<typename... _Us>
01106         static constexpr _Ret
01107         _S_do(_Us&&... __us)
01108         {
01109           return _Ret(std::forward<_Us>(__us)...);
01110         }
01111     };
01112 
01113   /// tuple_cat
01114   template<typename... _Tpls, typename = typename
01115            enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type>
01116     constexpr auto
01117     tuple_cat(_Tpls&&... __tpls)
01118     -> typename __tuple_cat_result<_Tpls...>::__type
01119     {
01120       typedef typename __tuple_cat_result<_Tpls...>::__type __ret;
01121       typedef typename __make_1st_indices<_Tpls...>::__type __idx;
01122       typedef __tuple_concater<__ret, __idx, _Tpls...> __concater;
01123       return __concater::_S_do(std::forward<_Tpls>(__tpls)...);
01124     }
01125 
01126   /// tie
01127   template<typename... _Elements>
01128     inline tuple<_Elements&...>
01129     tie(_Elements&... __args) noexcept
01130     { return tuple<_Elements&...>(__args...); }
01131 
01132   /// swap
01133   template<typename... _Elements>
01134     inline void 
01135     swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
01136     noexcept(noexcept(__x.swap(__y)))
01137     { __x.swap(__y); }
01138 
01139   // A class (and instance) which can be used in 'tie' when an element
01140   // of a tuple is not required
01141   struct _Swallow_assign
01142   {
01143     template<class _Tp>
01144       const _Swallow_assign&
01145       operator=(const _Tp&) const
01146       { return *this; }
01147   };
01148 
01149   const _Swallow_assign ignore{};
01150 
01151   /// Partial specialization for tuples
01152   template<typename... _Types, typename _Alloc>
01153     struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { };
01154 
01155   // See stl_pair.h...
01156   template<class _T1, class _T2>
01157     template<typename... _Args1, typename... _Args2>
01158       inline
01159       pair<_T1, _T2>::
01160       pair(piecewise_construct_t,
01161            tuple<_Args1...> __first, tuple<_Args2...> __second)
01162       : pair(__first, __second,
01163              typename _Build_index_tuple<sizeof...(_Args1)>::__type(),
01164              typename _Build_index_tuple<sizeof...(_Args2)>::__type())
01165       { }
01166 
01167   template<class _T1, class _T2>
01168     template<typename... _Args1, std::size_t... _Indexes1,
01169              typename... _Args2, std::size_t... _Indexes2>
01170       inline
01171       pair<_T1, _T2>::
01172       pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2,
01173            _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)
01174       : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...),
01175         second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
01176       { }
01177 
01178   /// @}
01179 
01180 _GLIBCXX_END_NAMESPACE_VERSION
01181 } // namespace std
01182 
01183 #endif // C++11
01184 
01185 #endif // _GLIBCXX_TUPLE