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