libstdc++
tuple
Go to the documentation of this file.
00001 // <tuple> -*- C++ -*-
00002 
00003 // Copyright (C) 2007-2016 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(__is_nothrow_swappable<_Head>::value
00328                && noexcept(_M_tail(__in)._M_swap(_M_tail(__in))))
00329       {
00330         using std::swap;
00331         swap(_M_head(*this), _M_head(__in));
00332         _Inherited::_M_swap(_M_tail(__in));
00333       }
00334     };
00335 
00336   // Basis case of inheritance recursion.
00337   template<std::size_t _Idx, typename _Head>
00338     struct _Tuple_impl<_Idx, _Head>
00339     : private _Head_base<_Idx, _Head, __empty_not_final<_Head>::value>
00340     {
00341       template<std::size_t, typename...> friend class _Tuple_impl;
00342 
00343       typedef _Head_base<_Idx, _Head, __empty_not_final<_Head>::value> _Base;
00344 
00345       static constexpr _Head&
00346       _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
00347 
00348       static constexpr const _Head&
00349       _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); }
00350 
00351       constexpr _Tuple_impl()
00352       : _Base() { }
00353 
00354       explicit
00355       constexpr _Tuple_impl(const _Head& __head)
00356       : _Base(__head) { }
00357 
00358       template<typename _UHead>
00359         explicit
00360         constexpr _Tuple_impl(_UHead&& __head)
00361         : _Base(std::forward<_UHead>(__head)) { }
00362 
00363       constexpr _Tuple_impl(const _Tuple_impl&) = default;
00364 
00365       constexpr
00366       _Tuple_impl(_Tuple_impl&& __in)
00367       noexcept(is_nothrow_move_constructible<_Head>::value)
00368       : _Base(std::forward<_Head>(_M_head(__in))) { }
00369 
00370       template<typename _UHead>
00371         constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in)
00372         : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in)) { }
00373 
00374       template<typename _UHead>
00375         constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in)
00376         : _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
00377         { }
00378 
00379       template<typename _Alloc>
00380         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
00381         : _Base(__tag, __use_alloc<_Head>(__a)) { }
00382 
00383       template<typename _Alloc>
00384         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
00385                     const _Head& __head)
00386         : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { }
00387 
00388       template<typename _Alloc, typename _UHead>
00389         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
00390                     _UHead&& __head)
00391         : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
00392                 std::forward<_UHead>(__head)) { }
00393 
00394       template<typename _Alloc>
00395         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
00396                     const _Tuple_impl& __in)
00397         : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { }
00398 
00399       template<typename _Alloc>
00400         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
00401                     _Tuple_impl&& __in)
00402         : _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
00403                 std::forward<_Head>(_M_head(__in))) { }
00404 
00405       template<typename _Alloc, typename _UHead>
00406         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
00407                     const _Tuple_impl<_Idx, _UHead>& __in)
00408         : _Base(__use_alloc<_Head, _Alloc, _Head>(__a),
00409                 _Tuple_impl<_Idx, _UHead>::_M_head(__in)) { }
00410 
00411       template<typename _Alloc, typename _UHead>
00412         _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
00413                     _Tuple_impl<_Idx, _UHead>&& __in)
00414         : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a),
00415                 std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
00416         { }
00417 
00418       _Tuple_impl&
00419       operator=(const _Tuple_impl& __in)
00420       {
00421         _M_head(*this) = _M_head(__in);
00422         return *this;
00423       }
00424 
00425       _Tuple_impl&
00426       operator=(_Tuple_impl&& __in)
00427       noexcept(is_nothrow_move_assignable<_Head>::value)
00428       {
00429         _M_head(*this) = std::forward<_Head>(_M_head(__in));
00430         return *this;
00431       }
00432 
00433       template<typename _UHead>
00434         _Tuple_impl&
00435         operator=(const _Tuple_impl<_Idx, _UHead>& __in)
00436         {
00437           _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in);
00438           return *this;
00439         }
00440 
00441       template<typename _UHead>
00442         _Tuple_impl&
00443         operator=(_Tuple_impl<_Idx, _UHead>&& __in)
00444         {
00445           _M_head(*this)
00446             = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in));
00447           return *this;
00448         }
00449 
00450     protected:
00451       void
00452       _M_swap(_Tuple_impl& __in)
00453       noexcept(__is_nothrow_swappable<_Head>::value)
00454       {
00455         using std::swap;
00456         swap(_M_head(*this), _M_head(__in));
00457       }
00458     };
00459 
00460   template<typename... _Elements>
00461     class tuple;
00462 
00463   // Concept utility functions, reused in conditionally-explicit
00464   // constructors.
00465   template<bool, typename... _Elements>
00466   struct _TC
00467   {
00468     template<typename... _UElements>
00469     static constexpr bool _ConstructibleTuple()
00470     {
00471       return __and_<is_constructible<_Elements, const _UElements&>...>::value;
00472     }
00473 
00474     template<typename... _UElements>
00475     static constexpr bool _ImplicitlyConvertibleTuple()
00476     {
00477       return __and_<is_convertible<const _UElements&, _Elements>...>::value;
00478     }
00479 
00480     template<typename... _UElements>
00481     static constexpr bool _MoveConstructibleTuple()
00482     {
00483       return __and_<is_constructible<_Elements, _UElements&&>...>::value;
00484     }
00485 
00486     template<typename... _UElements>
00487     static constexpr bool _ImplicitlyMoveConvertibleTuple()
00488     {
00489       return __and_<is_convertible<_UElements&&, _Elements>...>::value;
00490     }
00491 
00492     template<typename _SrcTuple>
00493     static constexpr bool _NonNestedTuple()
00494     {
00495       return  __and_<__not_<is_same<tuple<_Elements...>,
00496                                    typename remove_cv<
00497                                      typename remove_reference<_SrcTuple>::type
00498                                    >::type>>,
00499                      __not_<is_convertible<_SrcTuple, _Elements...>>,
00500                      __not_<is_constructible<_Elements..., _SrcTuple>>
00501               >::value;
00502     }
00503     template<typename... _UElements>
00504     static constexpr bool _NotSameTuple()
00505     {
00506       return  __not_<is_same<tuple<_Elements...>,
00507                              typename remove_const<
00508                                typename remove_reference<_UElements...>::type
00509                                >::type>>::value;
00510     }
00511   };
00512 
00513   template<typename... _Elements>
00514   struct _TC<false, _Elements...>
00515   {
00516     template<typename... _UElements>
00517     static constexpr bool _ConstructibleTuple()
00518     {
00519       return false;
00520     }
00521 
00522     template<typename... _UElements>
00523     static constexpr bool _ImplicitlyConvertibleTuple()
00524     {
00525       return false;
00526     }
00527 
00528     template<typename... _UElements>
00529     static constexpr bool _MoveConstructibleTuple()
00530     {
00531       return false;
00532     }
00533 
00534     template<typename... _UElements>
00535     static constexpr bool _ImplicitlyMoveConvertibleTuple()
00536     {
00537       return false;
00538     }
00539 
00540     template<typename... _UElements>
00541     static constexpr bool _NonNestedTuple()
00542     {
00543       return true;
00544     }
00545     template<typename... _UElements>
00546     static constexpr bool _NotSameTuple()
00547     {
00548       return  true;
00549     }
00550   };
00551 
00552   /// Primary class template, tuple
00553   template<typename... _Elements> 
00554     class tuple : public _Tuple_impl<0, _Elements...>
00555     {
00556       typedef _Tuple_impl<0, _Elements...> _Inherited;
00557 
00558       // Used for constraining the default constructor so
00559       // that it becomes dependent on the constraints.
00560       template<typename _Dummy>
00561       struct _TC2
00562       {
00563         static constexpr bool _DefaultConstructibleTuple()
00564         {
00565           return __and_<is_default_constructible<_Elements>...>::value;
00566         }
00567         static constexpr bool _ImplicitlyDefaultConstructibleTuple()
00568         {
00569           return __and_<__is_implicitly_default_constructible<_Elements>...>
00570             ::value;
00571         }
00572       };
00573 
00574     public:
00575       template<typename _Dummy = void,
00576                typename enable_if<_TC2<_Dummy>::
00577                                     _ImplicitlyDefaultConstructibleTuple(),
00578                                   bool>::type = true>
00579       constexpr tuple()
00580       : _Inherited() { }
00581 
00582       template<typename _Dummy = void,
00583                typename enable_if<_TC2<_Dummy>::
00584                                     _DefaultConstructibleTuple()
00585                                   &&
00586                                   !_TC2<_Dummy>::
00587                                     _ImplicitlyDefaultConstructibleTuple(),
00588                                   bool>::type = false>
00589       explicit constexpr tuple()
00590       : _Inherited() { }
00591 
00592       // Shortcut for the cases where constructors taking _Elements...
00593       // need to be constrained.
00594       template<typename _Dummy> using _TCC =
00595         _TC<is_same<_Dummy, void>::value,
00596             _Elements...>;
00597 
00598       template<typename _Dummy = void,
00599                typename enable_if<
00600                  _TCC<_Dummy>::template
00601                    _ConstructibleTuple<_Elements...>()
00602                  && _TCC<_Dummy>::template
00603                    _ImplicitlyConvertibleTuple<_Elements...>()
00604                  && (sizeof...(_Elements) >= 1),
00605                bool>::type=true>
00606         constexpr tuple(const _Elements&... __elements)
00607       : _Inherited(__elements...) { }
00608 
00609       template<typename _Dummy = void,
00610                typename enable_if<
00611                  _TCC<_Dummy>::template
00612                    _ConstructibleTuple<_Elements...>()
00613                  && !_TCC<_Dummy>::template
00614                    _ImplicitlyConvertibleTuple<_Elements...>()
00615                  && (sizeof...(_Elements) >= 1),
00616                bool>::type=false>
00617       explicit constexpr tuple(const _Elements&... __elements)
00618       : _Inherited(__elements...) { }
00619 
00620       // Shortcut for the cases where constructors taking _UElements...
00621       // need to be constrained.
00622       template<typename... _UElements> using _TMC =
00623                   _TC<(sizeof...(_Elements) == sizeof...(_UElements)),
00624                       _Elements...>;
00625 
00626       template<typename... _UElements, typename
00627                enable_if<
00628                   _TC<sizeof...(_UElements) == 1, _Elements...>::template
00629                     _NotSameTuple<_UElements...>()
00630                   && _TMC<_UElements...>::template
00631                     _MoveConstructibleTuple<_UElements...>()
00632                   && _TMC<_UElements...>::template
00633                     _ImplicitlyMoveConvertibleTuple<_UElements...>()
00634                   && (sizeof...(_Elements) >= 1),
00635         bool>::type=true>
00636         constexpr tuple(_UElements&&... __elements)
00637         : _Inherited(std::forward<_UElements>(__elements)...) { }
00638 
00639       template<typename... _UElements, typename
00640         enable_if<
00641                   _TC<sizeof...(_UElements) == 1, _Elements...>::template
00642                     _NotSameTuple<_UElements...>()
00643                   && _TMC<_UElements...>::template
00644                     _MoveConstructibleTuple<_UElements...>()
00645                   && !_TMC<_UElements...>::template
00646                     _ImplicitlyMoveConvertibleTuple<_UElements...>()
00647                   && (sizeof...(_Elements) >= 1),
00648         bool>::type=false>
00649         explicit constexpr tuple(_UElements&&... __elements)
00650         : _Inherited(std::forward<_UElements>(__elements)...) { }
00651 
00652       constexpr tuple(const tuple&) = default;
00653 
00654       constexpr tuple(tuple&&) = default; 
00655 
00656       // Shortcut for the cases where constructors taking tuples
00657       // must avoid creating temporaries.
00658       template<typename _Dummy> using _TNTC =
00659         _TC<is_same<_Dummy, void>::value && sizeof...(_Elements) == 1,
00660             _Elements...>;
00661 
00662       template<typename... _UElements, typename _Dummy = void, typename
00663         enable_if<_TMC<_UElements...>::template
00664                     _ConstructibleTuple<_UElements...>()
00665                   && _TMC<_UElements...>::template
00666                     _ImplicitlyConvertibleTuple<_UElements...>()
00667                   && _TNTC<_Dummy>::template
00668                     _NonNestedTuple<const tuple<_UElements...>&>(),
00669         bool>::type=true>
00670         constexpr tuple(const tuple<_UElements...>& __in)
00671         : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
00672         { }
00673 
00674       template<typename... _UElements, typename _Dummy = void, typename
00675         enable_if<_TMC<_UElements...>::template
00676                     _ConstructibleTuple<_UElements...>()
00677                   && !_TMC<_UElements...>::template
00678                     _ImplicitlyConvertibleTuple<_UElements...>()
00679                   && _TNTC<_Dummy>::template
00680                     _NonNestedTuple<const tuple<_UElements...>&>(),
00681         bool>::type=false>
00682         explicit constexpr tuple(const tuple<_UElements...>& __in)
00683         : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
00684         { }
00685 
00686       template<typename... _UElements, typename _Dummy = void, typename
00687         enable_if<_TMC<_UElements...>::template
00688                     _MoveConstructibleTuple<_UElements...>()
00689                   && _TMC<_UElements...>::template
00690                     _ImplicitlyMoveConvertibleTuple<_UElements...>()
00691                   && _TNTC<_Dummy>::template
00692                     _NonNestedTuple<tuple<_UElements...>&&>(),
00693         bool>::type=true>
00694         constexpr tuple(tuple<_UElements...>&& __in)
00695         : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
00696 
00697       template<typename... _UElements, typename _Dummy = void, typename
00698         enable_if<_TMC<_UElements...>::template
00699                     _MoveConstructibleTuple<_UElements...>()
00700                   && !_TMC<_UElements...>::template
00701                     _ImplicitlyMoveConvertibleTuple<_UElements...>()
00702                   && _TNTC<_Dummy>::template
00703                     _NonNestedTuple<tuple<_UElements...>&&>(),
00704         bool>::type=false>
00705         explicit constexpr tuple(tuple<_UElements...>&& __in)
00706         : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
00707 
00708       // Allocator-extended constructors.
00709 
00710       template<typename _Alloc>
00711         tuple(allocator_arg_t __tag, const _Alloc& __a)
00712         : _Inherited(__tag, __a) { }
00713 
00714       template<typename _Alloc, typename _Dummy = void,
00715                typename enable_if<
00716                  _TCC<_Dummy>::template
00717                    _ConstructibleTuple<_Elements...>()
00718                  && _TCC<_Dummy>::template
00719                    _ImplicitlyConvertibleTuple<_Elements...>(),
00720                bool>::type=true>
00721         tuple(allocator_arg_t __tag, const _Alloc& __a,
00722               const _Elements&... __elements)
00723         : _Inherited(__tag, __a, __elements...) { }
00724 
00725       template<typename _Alloc, typename _Dummy = void,
00726                typename enable_if<
00727                  _TCC<_Dummy>::template
00728                    _ConstructibleTuple<_Elements...>()
00729                  && !_TCC<_Dummy>::template
00730                    _ImplicitlyConvertibleTuple<_Elements...>(),
00731                bool>::type=false>
00732         explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
00733                        const _Elements&... __elements)
00734         : _Inherited(__tag, __a, __elements...) { }
00735 
00736       template<typename _Alloc, typename... _UElements, typename
00737         enable_if<_TMC<_UElements...>::template
00738                     _MoveConstructibleTuple<_UElements...>()
00739                   && _TMC<_UElements...>::template
00740                     _ImplicitlyMoveConvertibleTuple<_UElements...>(),
00741         bool>::type=true>
00742         tuple(allocator_arg_t __tag, const _Alloc& __a,
00743               _UElements&&... __elements)
00744         : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
00745         { }
00746 
00747       template<typename _Alloc, typename... _UElements, typename
00748         enable_if<_TMC<_UElements...>::template
00749                     _MoveConstructibleTuple<_UElements...>()
00750                   && !_TMC<_UElements...>::template
00751                     _ImplicitlyMoveConvertibleTuple<_UElements...>(),
00752         bool>::type=false>
00753         explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
00754               _UElements&&... __elements)
00755         : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...)
00756         { }
00757 
00758       template<typename _Alloc>
00759         tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
00760         : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
00761 
00762       template<typename _Alloc>
00763         tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
00764         : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
00765 
00766       template<typename _Alloc, typename... _UElements, typename
00767         enable_if<_TMC<_UElements...>::template
00768                     _ConstructibleTuple<_UElements...>()
00769                   && _TMC<_UElements...>::template
00770                     _ImplicitlyConvertibleTuple<_UElements...>(),
00771         bool>::type=true>
00772         tuple(allocator_arg_t __tag, const _Alloc& __a,
00773               const tuple<_UElements...>& __in)
00774         : _Inherited(__tag, __a,
00775                      static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
00776         { }
00777 
00778       template<typename _Alloc, typename... _UElements, typename
00779         enable_if<_TMC<_UElements...>::template
00780                     _ConstructibleTuple<_UElements...>()
00781                   && !_TMC<_UElements...>::template
00782                     _ImplicitlyConvertibleTuple<_UElements...>(),
00783         bool>::type=false>
00784         explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
00785               const tuple<_UElements...>& __in)
00786         : _Inherited(__tag, __a,
00787                      static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
00788         { }
00789 
00790       template<typename _Alloc, typename... _UElements, typename
00791         enable_if<_TMC<_UElements...>::template
00792                     _MoveConstructibleTuple<_UElements...>()
00793                   && _TMC<_UElements...>::template
00794                     _ImplicitlyMoveConvertibleTuple<_UElements...>(),
00795         bool>::type=true>
00796         tuple(allocator_arg_t __tag, const _Alloc& __a,
00797               tuple<_UElements...>&& __in)
00798         : _Inherited(__tag, __a,
00799                      static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
00800         { }
00801 
00802       template<typename _Alloc, typename... _UElements, typename
00803         enable_if<_TMC<_UElements...>::template
00804                     _MoveConstructibleTuple<_UElements...>()
00805                   && !_TMC<_UElements...>::template
00806                     _ImplicitlyMoveConvertibleTuple<_UElements...>(),
00807         bool>::type=false>
00808         explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
00809               tuple<_UElements...>&& __in)
00810         : _Inherited(__tag, __a,
00811                      static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
00812         { }
00813 
00814       tuple&
00815       operator=(const tuple& __in)
00816       {
00817         static_cast<_Inherited&>(*this) = __in;
00818         return *this;
00819       }
00820 
00821       tuple&
00822       operator=(tuple&& __in)
00823       noexcept(is_nothrow_move_assignable<_Inherited>::value)
00824       {
00825         static_cast<_Inherited&>(*this) = std::move(__in);
00826         return *this;
00827       }
00828 
00829       template<typename... _UElements, typename = typename
00830                enable_if<sizeof...(_UElements)
00831                          == sizeof...(_Elements)>::type>
00832         tuple&
00833         operator=(const tuple<_UElements...>& __in)
00834         {
00835           static_cast<_Inherited&>(*this) = __in;
00836           return *this;
00837         }
00838 
00839       template<typename... _UElements, typename = typename
00840                enable_if<sizeof...(_UElements)
00841                          == sizeof...(_Elements)>::type>
00842         tuple&
00843         operator=(tuple<_UElements...>&& __in)
00844         {
00845           static_cast<_Inherited&>(*this) = std::move(__in);
00846           return *this;
00847         }
00848 
00849       void
00850       swap(tuple& __in)
00851       noexcept(noexcept(__in._M_swap(__in)))
00852       { _Inherited::_M_swap(__in); }
00853     };
00854 
00855   // Explicit specialization, zero-element tuple.
00856   template<>
00857     class tuple<>
00858     {
00859     public:
00860       void swap(tuple&) noexcept { /* no-op */ }
00861     };
00862 
00863   /// Partial specialization, 2-element tuple.
00864   /// Includes construction and assignment from a pair.
00865   template<typename _T1, typename _T2>
00866     class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
00867     {
00868       typedef _Tuple_impl<0, _T1, _T2> _Inherited;
00869 
00870     public:
00871       template <typename _U1 = _T1,
00872                 typename _U2 = _T2,
00873                 typename enable_if<__and_<
00874                                      __is_implicitly_default_constructible<_U1>,
00875                                      __is_implicitly_default_constructible<_U2>>
00876                                    ::value, bool>::type = true>
00877 
00878       constexpr tuple()
00879       : _Inherited() { }
00880 
00881       template <typename _U1 = _T1,
00882                 typename _U2 = _T2,
00883                 typename enable_if<
00884                   __and_<
00885                     is_default_constructible<_U1>,
00886                     is_default_constructible<_U2>,
00887                     __not_<
00888                       __and_<__is_implicitly_default_constructible<_U1>,
00889                              __is_implicitly_default_constructible<_U2>>>>
00890                   ::value, bool>::type = false>
00891 
00892       explicit constexpr tuple()
00893       : _Inherited() { }
00894 
00895       // Shortcut for the cases where constructors taking _T1, _T2
00896       // need to be constrained.
00897       template<typename _Dummy> using _TCC =
00898         _TC<is_same<_Dummy, void>::value, _T1, _T2>;
00899 
00900       template<typename _Dummy = void, typename
00901                enable_if<_TCC<_Dummy>::template
00902                            _ConstructibleTuple<_T1, _T2>()
00903                          && _TCC<_Dummy>::template
00904                            _ImplicitlyConvertibleTuple<_T1, _T2>(),
00905         bool>::type = true>
00906         constexpr tuple(const _T1& __a1, const _T2& __a2)
00907         : _Inherited(__a1, __a2) { }
00908 
00909       template<typename _Dummy = void, typename
00910                enable_if<_TCC<_Dummy>::template
00911                            _ConstructibleTuple<_T1, _T2>()
00912                          && !_TCC<_Dummy>::template
00913                            _ImplicitlyConvertibleTuple<_T1, _T2>(),
00914         bool>::type = false>
00915         explicit constexpr tuple(const _T1& __a1, const _T2& __a2)
00916         : _Inherited(__a1, __a2) { }
00917 
00918       // Shortcut for the cases where constructors taking _U1, _U2
00919       // need to be constrained.
00920       using _TMC = _TC<true, _T1, _T2>;
00921 
00922       template<typename _U1, typename _U2, typename
00923         enable_if<_TMC::template
00924                     _MoveConstructibleTuple<_U1, _U2>()
00925                   && _TMC::template
00926                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
00927         bool>::type = true>
00928         constexpr tuple(_U1&& __a1, _U2&& __a2)
00929         : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
00930 
00931       template<typename _U1, typename _U2, typename
00932         enable_if<_TMC::template
00933                     _MoveConstructibleTuple<_U1, _U2>()
00934                   && !_TMC::template
00935                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
00936         bool>::type = false>
00937         explicit constexpr tuple(_U1&& __a1, _U2&& __a2)
00938         : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
00939 
00940       constexpr tuple(const tuple&) = default;
00941 
00942       constexpr tuple(tuple&&) = default;
00943 
00944       template<typename _U1, typename _U2, typename
00945         enable_if<_TMC::template
00946                     _ConstructibleTuple<_U1, _U2>()
00947                   && _TMC::template
00948                     _ImplicitlyConvertibleTuple<_U1, _U2>(),
00949         bool>::type = true>
00950         constexpr tuple(const tuple<_U1, _U2>& __in)
00951         : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
00952 
00953       template<typename _U1, typename _U2, typename
00954         enable_if<_TMC::template
00955                     _ConstructibleTuple<_U1, _U2>()
00956                   && !_TMC::template
00957                     _ImplicitlyConvertibleTuple<_U1, _U2>(),
00958         bool>::type = false>
00959         explicit constexpr tuple(const tuple<_U1, _U2>& __in)
00960         : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
00961 
00962       template<typename _U1, typename _U2, typename
00963         enable_if<_TMC::template
00964                     _MoveConstructibleTuple<_U1, _U2>()
00965                   && _TMC::template
00966                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
00967         bool>::type = true>
00968         constexpr tuple(tuple<_U1, _U2>&& __in)
00969         : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
00970 
00971       template<typename _U1, typename _U2, typename
00972         enable_if<_TMC::template
00973                     _MoveConstructibleTuple<_U1, _U2>()
00974                   && !_TMC::template
00975                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
00976         bool>::type = false>
00977         explicit constexpr tuple(tuple<_U1, _U2>&& __in)
00978         : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
00979 
00980       template<typename _U1, typename _U2, typename
00981         enable_if<_TMC::template
00982                     _ConstructibleTuple<_U1, _U2>()
00983                   && _TMC::template
00984                     _ImplicitlyConvertibleTuple<_U1, _U2>(),
00985         bool>::type = true>
00986         constexpr tuple(const pair<_U1, _U2>& __in)
00987         : _Inherited(__in.first, __in.second) { }
00988 
00989       template<typename _U1, typename _U2, typename
00990         enable_if<_TMC::template
00991                     _ConstructibleTuple<_U1, _U2>()
00992                   && !_TMC::template
00993                     _ImplicitlyConvertibleTuple<_U1, _U2>(),
00994         bool>::type = false>
00995         explicit constexpr tuple(const pair<_U1, _U2>& __in)
00996         : _Inherited(__in.first, __in.second) { }
00997 
00998       template<typename _U1, typename _U2, typename
00999         enable_if<_TMC::template
01000                     _MoveConstructibleTuple<_U1, _U2>()
01001                   && _TMC::template
01002                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
01003         bool>::type = true>
01004         constexpr tuple(pair<_U1, _U2>&& __in)
01005         : _Inherited(std::forward<_U1>(__in.first),
01006                      std::forward<_U2>(__in.second)) { }
01007 
01008       template<typename _U1, typename _U2, typename
01009         enable_if<_TMC::template
01010                     _MoveConstructibleTuple<_U1, _U2>()
01011                   && !_TMC::template
01012                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
01013         bool>::type = false>
01014         explicit constexpr tuple(pair<_U1, _U2>&& __in)
01015         : _Inherited(std::forward<_U1>(__in.first),
01016                      std::forward<_U2>(__in.second)) { }
01017 
01018       // Allocator-extended constructors.
01019 
01020       template<typename _Alloc>
01021         tuple(allocator_arg_t __tag, const _Alloc& __a)
01022         : _Inherited(__tag, __a) { }
01023 
01024       template<typename _Alloc, typename _Dummy = void,
01025                typename enable_if<
01026                  _TCC<_Dummy>::template
01027                    _ConstructibleTuple<_T1, _T2>()
01028                  && _TCC<_Dummy>::template
01029                    _ImplicitlyConvertibleTuple<_T1, _T2>(),
01030                bool>::type=true>
01031 
01032         tuple(allocator_arg_t __tag, const _Alloc& __a,
01033               const _T1& __a1, const _T2& __a2)
01034         : _Inherited(__tag, __a, __a1, __a2) { }
01035 
01036       template<typename _Alloc, typename _Dummy = void,
01037                typename enable_if<
01038                  _TCC<_Dummy>::template
01039                    _ConstructibleTuple<_T1, _T2>()
01040                  && !_TCC<_Dummy>::template
01041                    _ImplicitlyConvertibleTuple<_T1, _T2>(),
01042                bool>::type=false>
01043 
01044         explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
01045               const _T1& __a1, const _T2& __a2)
01046         : _Inherited(__tag, __a, __a1, __a2) { }
01047 
01048       template<typename _Alloc, typename _U1, typename _U2, typename
01049         enable_if<_TMC::template
01050                     _MoveConstructibleTuple<_U1, _U2>()
01051                   && _TMC::template
01052                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
01053         bool>::type = true>
01054         tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2)
01055         : _Inherited(__tag, __a, std::forward<_U1>(__a1),
01056                      std::forward<_U2>(__a2)) { }
01057 
01058       template<typename _Alloc, typename _U1, typename _U2, typename
01059         enable_if<_TMC::template
01060                     _MoveConstructibleTuple<_U1, _U2>()
01061                   && !_TMC::template
01062                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
01063         bool>::type = false>
01064         explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
01065                        _U1&& __a1, _U2&& __a2)
01066         : _Inherited(__tag, __a, std::forward<_U1>(__a1),
01067                      std::forward<_U2>(__a2)) { }
01068 
01069       template<typename _Alloc>
01070         tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
01071         : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
01072 
01073       template<typename _Alloc>
01074         tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
01075         : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
01076 
01077       template<typename _Alloc, typename _U1, typename _U2, typename
01078         enable_if<_TMC::template
01079                     _ConstructibleTuple<_U1, _U2>()
01080                   && _TMC::template
01081                     _ImplicitlyConvertibleTuple<_U1, _U2>(),
01082         bool>::type = true>
01083         tuple(allocator_arg_t __tag, const _Alloc& __a,
01084               const tuple<_U1, _U2>& __in)
01085         : _Inherited(__tag, __a,
01086                      static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
01087         { }
01088 
01089       template<typename _Alloc, typename _U1, typename _U2, typename
01090         enable_if<_TMC::template
01091                     _ConstructibleTuple<_U1, _U2>()
01092                   && !_TMC::template
01093                     _ImplicitlyConvertibleTuple<_U1, _U2>(),
01094         bool>::type = false>
01095         explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
01096               const tuple<_U1, _U2>& __in)
01097         : _Inherited(__tag, __a,
01098                      static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
01099         { }
01100 
01101       template<typename _Alloc, typename _U1, typename _U2, typename
01102         enable_if<_TMC::template
01103                     _MoveConstructibleTuple<_U1, _U2>()
01104                   && _TMC::template
01105                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
01106         bool>::type = true>
01107         tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
01108         : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
01109         { }
01110 
01111       template<typename _Alloc, typename _U1, typename _U2, typename
01112         enable_if<_TMC::template
01113                     _MoveConstructibleTuple<_U1, _U2>()
01114                   && !_TMC::template
01115                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
01116         bool>::type = false>
01117         explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
01118                        tuple<_U1, _U2>&& __in)
01119         : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
01120         { }
01121 
01122       template<typename _Alloc, typename _U1, typename _U2, typename
01123         enable_if<_TMC::template
01124                     _ConstructibleTuple<_U1, _U2>()
01125                   && _TMC::template
01126                     _ImplicitlyConvertibleTuple<_U1, _U2>(),
01127         bool>::type = true>
01128         tuple(allocator_arg_t __tag, const _Alloc& __a,
01129               const pair<_U1, _U2>& __in)
01130         : _Inherited(__tag, __a, __in.first, __in.second) { }
01131 
01132       template<typename _Alloc, typename _U1, typename _U2, typename
01133         enable_if<_TMC::template
01134                     _ConstructibleTuple<_U1, _U2>()
01135                   && !_TMC::template
01136                     _ImplicitlyConvertibleTuple<_U1, _U2>(),
01137         bool>::type = false>
01138         explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
01139               const pair<_U1, _U2>& __in)
01140         : _Inherited(__tag, __a, __in.first, __in.second) { }
01141 
01142       template<typename _Alloc, typename _U1, typename _U2, typename
01143         enable_if<_TMC::template
01144                     _MoveConstructibleTuple<_U1, _U2>()
01145                   && _TMC::template
01146                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
01147         bool>::type = true>
01148         tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
01149         : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
01150                      std::forward<_U2>(__in.second)) { }
01151 
01152       template<typename _Alloc, typename _U1, typename _U2, typename
01153         enable_if<_TMC::template
01154                     _MoveConstructibleTuple<_U1, _U2>()
01155                   && !_TMC::template
01156                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
01157         bool>::type = false>
01158         explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
01159                        pair<_U1, _U2>&& __in)
01160         : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
01161                      std::forward<_U2>(__in.second)) { }
01162 
01163       tuple&
01164       operator=(const tuple& __in)
01165       {
01166         static_cast<_Inherited&>(*this) = __in;
01167         return *this;
01168       }
01169 
01170       tuple&
01171       operator=(tuple&& __in)
01172       noexcept(is_nothrow_move_assignable<_Inherited>::value)
01173       {
01174         static_cast<_Inherited&>(*this) = std::move(__in);
01175         return *this;
01176       }
01177 
01178       template<typename _U1, typename _U2>
01179         tuple&
01180         operator=(const tuple<_U1, _U2>& __in)
01181         {
01182           static_cast<_Inherited&>(*this) = __in;
01183           return *this;
01184         }
01185 
01186       template<typename _U1, typename _U2>
01187         tuple&
01188         operator=(tuple<_U1, _U2>&& __in)
01189         {
01190           static_cast<_Inherited&>(*this) = std::move(__in);
01191           return *this;
01192         }
01193 
01194       template<typename _U1, typename _U2>
01195         tuple&
01196         operator=(const pair<_U1, _U2>& __in)
01197         {
01198           this->_M_head(*this) = __in.first;
01199           this->_M_tail(*this)._M_head(*this) = __in.second;
01200           return *this;
01201         }
01202 
01203       template<typename _U1, typename _U2>
01204         tuple&
01205         operator=(pair<_U1, _U2>&& __in)
01206         {
01207           this->_M_head(*this) = std::forward<_U1>(__in.first);
01208           this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second);
01209           return *this;
01210         }
01211 
01212       void
01213       swap(tuple& __in)
01214       noexcept(noexcept(__in._M_swap(__in)))
01215       { _Inherited::_M_swap(__in); }
01216     };
01217 
01218 
01219   /**
01220    * Recursive case for tuple_element: strip off the first element in
01221    * the tuple and retrieve the (i-1)th element of the remaining tuple.
01222    */
01223   template<std::size_t __i, typename _Head, typename... _Tail>
01224     struct tuple_element<__i, tuple<_Head, _Tail...> >
01225     : tuple_element<__i - 1, tuple<_Tail...> > { };
01226 
01227   /**
01228    * Basis case for tuple_element: The first element is the one we're seeking.
01229    */
01230   template<typename _Head, typename... _Tail>
01231     struct tuple_element<0, tuple<_Head, _Tail...> >
01232     {
01233       typedef _Head type;
01234     };
01235 
01236   /// class tuple_size
01237   template<typename... _Elements>
01238     struct tuple_size<tuple<_Elements...>>
01239     : public integral_constant<std::size_t, sizeof...(_Elements)> { };
01240 
01241   template<std::size_t __i, typename _Head, typename... _Tail>
01242     constexpr _Head&
01243     __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
01244     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
01245 
01246   template<std::size_t __i, typename _Head, typename... _Tail>
01247     constexpr const _Head&
01248     __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
01249     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
01250 
01251   /// Return a reference to the ith element of a tuple.
01252   template<std::size_t __i, typename... _Elements>
01253     constexpr __tuple_element_t<__i, tuple<_Elements...>>&
01254     get(tuple<_Elements...>& __t) noexcept
01255     { return std::__get_helper<__i>(__t); }
01256 
01257   /// Return a const reference to the ith element of a const tuple.
01258   template<std::size_t __i, typename... _Elements>
01259     constexpr const __tuple_element_t<__i, tuple<_Elements...>>&
01260     get(const tuple<_Elements...>& __t) noexcept
01261     { return std::__get_helper<__i>(__t); }
01262 
01263   /// Return an rvalue reference to the ith element of a tuple rvalue.
01264   template<std::size_t __i, typename... _Elements>
01265     constexpr __tuple_element_t<__i, tuple<_Elements...>>&&
01266     get(tuple<_Elements...>&& __t) noexcept
01267     {
01268       typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
01269       return std::forward<__element_type&&>(std::get<__i>(__t));
01270     }
01271 
01272 #if __cplusplus > 201103L
01273 
01274 #define __cpp_lib_tuples_by_type 201304
01275 
01276   template<typename _Head, size_t __i, typename... _Tail>
01277     constexpr _Head&
01278     __get_helper2(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
01279     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
01280 
01281   template<typename _Head, size_t __i, typename... _Tail>
01282     constexpr const _Head&
01283     __get_helper2(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
01284     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
01285 
01286   /// Return a reference to the unique element of type _Tp of a tuple.
01287   template <typename _Tp, typename... _Types>
01288     constexpr _Tp&
01289     get(tuple<_Types...>& __t) noexcept
01290     { return std::__get_helper2<_Tp>(__t); }
01291 
01292   /// Return a reference to the unique element of type _Tp of a tuple rvalue.
01293   template <typename _Tp, typename... _Types>
01294     constexpr _Tp&&
01295     get(tuple<_Types...>&& __t) noexcept
01296     { return std::forward<_Tp&&>(std::__get_helper2<_Tp>(__t)); }
01297 
01298   /// Return a const reference to the unique element of type _Tp of a tuple.
01299   template <typename _Tp, typename... _Types>
01300     constexpr const _Tp&
01301     get(const tuple<_Types...>& __t) noexcept
01302     { return std::__get_helper2<_Tp>(__t); }
01303 #endif
01304 
01305   // This class performs the comparison operations on tuples
01306   template<typename _Tp, typename _Up, size_t __i, size_t __size>
01307     struct __tuple_compare
01308     {
01309       static constexpr bool
01310       __eq(const _Tp& __t, const _Up& __u)
01311       {
01312         return bool(std::get<__i>(__t) == std::get<__i>(__u))
01313           && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u);
01314       }
01315    
01316       static constexpr bool
01317       __less(const _Tp& __t, const _Up& __u)
01318       {
01319         return bool(std::get<__i>(__t) < std::get<__i>(__u))
01320           || (!bool(std::get<__i>(__u) < std::get<__i>(__t))
01321               && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u));
01322       }
01323     };
01324 
01325   template<typename _Tp, typename _Up, size_t __size>
01326     struct __tuple_compare<_Tp, _Up, __size, __size>
01327     {
01328       static constexpr bool
01329       __eq(const _Tp&, const _Up&) { return true; }
01330    
01331       static constexpr bool
01332       __less(const _Tp&, const _Up&) { return false; }
01333     };
01334 
01335   template<typename... _TElements, typename... _UElements>
01336     constexpr bool
01337     operator==(const tuple<_TElements...>& __t,
01338                const tuple<_UElements...>& __u)
01339     {
01340       static_assert(sizeof...(_TElements) == sizeof...(_UElements),
01341           "tuple objects can only be compared if they have equal sizes.");
01342       using __compare = __tuple_compare<tuple<_TElements...>,
01343                                         tuple<_UElements...>,
01344                                         0, sizeof...(_TElements)>;
01345       return __compare::__eq(__t, __u);
01346     }
01347 
01348   template<typename... _TElements, typename... _UElements>
01349     constexpr bool
01350     operator<(const tuple<_TElements...>& __t,
01351               const tuple<_UElements...>& __u)
01352     {
01353       static_assert(sizeof...(_TElements) == sizeof...(_UElements),
01354           "tuple objects can only be compared if they have equal sizes.");
01355       using __compare = __tuple_compare<tuple<_TElements...>,
01356                                         tuple<_UElements...>,
01357                                         0, sizeof...(_TElements)>;
01358       return __compare::__less(__t, __u);
01359     }
01360 
01361   template<typename... _TElements, typename... _UElements>
01362     constexpr bool
01363     operator!=(const tuple<_TElements...>& __t,
01364                const tuple<_UElements...>& __u)
01365     { return !(__t == __u); }
01366 
01367   template<typename... _TElements, typename... _UElements>
01368     constexpr bool
01369     operator>(const tuple<_TElements...>& __t,
01370               const tuple<_UElements...>& __u)
01371     { return __u < __t; }
01372 
01373   template<typename... _TElements, typename... _UElements>
01374     constexpr bool
01375     operator<=(const tuple<_TElements...>& __t,
01376                const tuple<_UElements...>& __u)
01377     { return !(__u < __t); }
01378 
01379   template<typename... _TElements, typename... _UElements>
01380     constexpr bool
01381     operator>=(const tuple<_TElements...>& __t,
01382                const tuple<_UElements...>& __u)
01383     { return !(__t < __u); }
01384 
01385   // NB: DR 705.
01386   template<typename... _Elements>
01387     constexpr tuple<typename __decay_and_strip<_Elements>::__type...>
01388     make_tuple(_Elements&&... __args)
01389     {
01390       typedef tuple<typename __decay_and_strip<_Elements>::__type...>
01391         __result_type;
01392       return __result_type(std::forward<_Elements>(__args)...);
01393     }
01394 
01395   // _GLIBCXX_RESOLVE_LIB_DEFECTS
01396   // 2275. Why is forward_as_tuple not constexpr?
01397   template<typename... _Elements>
01398     constexpr tuple<_Elements&&...>
01399     forward_as_tuple(_Elements&&... __args) noexcept
01400     { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
01401 
01402   template<typename... _Tps>
01403     struct __is_tuple_like_impl<tuple<_Tps...>> : true_type
01404     { };
01405 
01406   // Internal type trait that allows us to sfinae-protect tuple_cat.
01407   template<typename _Tp>
01408     struct __is_tuple_like
01409     : public __is_tuple_like_impl<typename std::remove_cv
01410             <typename std::remove_reference<_Tp>::type>::type>::type
01411     { };
01412 
01413   template<size_t, typename, typename, size_t>
01414     struct __make_tuple_impl;
01415 
01416   template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm>
01417     struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm>
01418     : __make_tuple_impl<_Idx + 1,
01419                         tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>,
01420                         _Tuple, _Nm>
01421     { };
01422 
01423   template<std::size_t _Nm, typename _Tuple, typename... _Tp>
01424     struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm>
01425     {
01426       typedef tuple<_Tp...> __type;
01427     };
01428 
01429   template<typename _Tuple>
01430     struct __do_make_tuple
01431     : __make_tuple_impl<0, tuple<>, _Tuple, std::tuple_size<_Tuple>::value>
01432     { };
01433 
01434   // Returns the std::tuple equivalent of a tuple-like type.
01435   template<typename _Tuple>
01436     struct __make_tuple
01437     : public __do_make_tuple<typename std::remove_cv
01438             <typename std::remove_reference<_Tuple>::type>::type>
01439     { };
01440 
01441   // Combines several std::tuple's into a single one.
01442   template<typename...>
01443     struct __combine_tuples;
01444 
01445   template<>
01446     struct __combine_tuples<>
01447     {
01448       typedef tuple<> __type;
01449     };
01450 
01451   template<typename... _Ts>
01452     struct __combine_tuples<tuple<_Ts...>>
01453     {
01454       typedef tuple<_Ts...> __type;
01455     };
01456 
01457   template<typename... _T1s, typename... _T2s, typename... _Rem>
01458     struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...>
01459     {
01460       typedef typename __combine_tuples<tuple<_T1s..., _T2s...>,
01461                                         _Rem...>::__type __type;
01462     };
01463 
01464   // Computes the result type of tuple_cat given a set of tuple-like types.
01465   template<typename... _Tpls>
01466     struct __tuple_cat_result
01467     {
01468       typedef typename __combine_tuples
01469         <typename __make_tuple<_Tpls>::__type...>::__type __type;
01470     };
01471 
01472   // Helper to determine the index set for the first tuple-like
01473   // type of a given set.
01474   template<typename...>
01475     struct __make_1st_indices;
01476 
01477   template<>
01478     struct __make_1st_indices<>
01479     {
01480       typedef std::_Index_tuple<> __type;
01481     };
01482 
01483   template<typename _Tp, typename... _Tpls>
01484     struct __make_1st_indices<_Tp, _Tpls...>
01485     {
01486       typedef typename std::_Build_index_tuple<std::tuple_size<
01487         typename std::remove_reference<_Tp>::type>::value>::__type __type;
01488     };
01489 
01490   // Performs the actual concatenation by step-wise expanding tuple-like
01491   // objects into the elements,  which are finally forwarded into the
01492   // result tuple.
01493   template<typename _Ret, typename _Indices, typename... _Tpls>
01494     struct __tuple_concater;
01495 
01496   template<typename _Ret, std::size_t... _Is, typename _Tp, typename... _Tpls>
01497     struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...>
01498     {
01499       template<typename... _Us>
01500         static constexpr _Ret
01501         _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us)
01502         {
01503           typedef typename __make_1st_indices<_Tpls...>::__type __idx;
01504           typedef __tuple_concater<_Ret, __idx, _Tpls...>      __next;
01505           return __next::_S_do(std::forward<_Tpls>(__tps)...,
01506                                std::forward<_Us>(__us)...,
01507                                std::get<_Is>(std::forward<_Tp>(__tp))...);
01508         }
01509     };
01510 
01511   template<typename _Ret>
01512     struct __tuple_concater<_Ret, std::_Index_tuple<>>
01513     {
01514       template<typename... _Us>
01515         static constexpr _Ret
01516         _S_do(_Us&&... __us)
01517         {
01518           return _Ret(std::forward<_Us>(__us)...);
01519         }
01520     };
01521 
01522   /// tuple_cat
01523   template<typename... _Tpls, typename = typename
01524            enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type>
01525     constexpr auto
01526     tuple_cat(_Tpls&&... __tpls)
01527     -> typename __tuple_cat_result<_Tpls...>::__type
01528     {
01529       typedef typename __tuple_cat_result<_Tpls...>::__type __ret;
01530       typedef typename __make_1st_indices<_Tpls...>::__type __idx;
01531       typedef __tuple_concater<__ret, __idx, _Tpls...> __concater;
01532       return __concater::_S_do(std::forward<_Tpls>(__tpls)...);
01533     }
01534 
01535   // _GLIBCXX_RESOLVE_LIB_DEFECTS
01536   // 2301. Why is tie not constexpr?
01537   /// tie
01538   template<typename... _Elements>
01539     constexpr tuple<_Elements&...>
01540     tie(_Elements&... __args) noexcept
01541     { return tuple<_Elements&...>(__args...); }
01542 
01543   /// swap
01544   template<typename... _Elements>
01545     inline void 
01546     swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
01547     noexcept(noexcept(__x.swap(__y)))
01548     { __x.swap(__y); }
01549 
01550   // A class (and instance) which can be used in 'tie' when an element
01551   // of a tuple is not required
01552   struct _Swallow_assign
01553   {
01554     template<class _Tp>
01555       const _Swallow_assign&
01556       operator=(const _Tp&) const
01557       { return *this; }
01558   };
01559 
01560   const _Swallow_assign ignore{};
01561 
01562   /// Partial specialization for tuples
01563   template<typename... _Types, typename _Alloc>
01564     struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { };
01565 
01566   // See stl_pair.h...
01567   template<class _T1, class _T2>
01568     template<typename... _Args1, typename... _Args2>
01569       inline
01570       pair<_T1, _T2>::
01571       pair(piecewise_construct_t,
01572            tuple<_Args1...> __first, tuple<_Args2...> __second)
01573       : pair(__first, __second,
01574              typename _Build_index_tuple<sizeof...(_Args1)>::__type(),
01575              typename _Build_index_tuple<sizeof...(_Args2)>::__type())
01576       { }
01577 
01578   template<class _T1, class _T2>
01579     template<typename... _Args1, std::size_t... _Indexes1,
01580              typename... _Args2, std::size_t... _Indexes2>
01581       inline
01582       pair<_T1, _T2>::
01583       pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2,
01584            _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)
01585       : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...),
01586         second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
01587       { }
01588 
01589   /// @}
01590 
01591 _GLIBCXX_END_NAMESPACE_VERSION
01592 } // namespace std
01593 
01594 #endif // C++11
01595 
01596 #endif // _GLIBCXX_TUPLE