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                   && !is_same<typename decay<_U1>::type,
00928                               allocator_arg_t>::value,
00929         bool>::type = true>
00930         constexpr tuple(_U1&& __a1, _U2&& __a2)
00931         : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
00932 
00933       template<typename _U1, typename _U2, typename
00934         enable_if<_TMC::template
00935                     _MoveConstructibleTuple<_U1, _U2>()
00936                   && !_TMC::template
00937                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>()
00938                   && !is_same<typename decay<_U1>::type,
00939                               allocator_arg_t>::value,
00940         bool>::type = false>
00941         explicit constexpr tuple(_U1&& __a1, _U2&& __a2)
00942         : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
00943 
00944       constexpr tuple(const tuple&) = default;
00945 
00946       constexpr tuple(tuple&&) = default;
00947 
00948       template<typename _U1, typename _U2, typename
00949         enable_if<_TMC::template
00950                     _ConstructibleTuple<_U1, _U2>()
00951                   && _TMC::template
00952                     _ImplicitlyConvertibleTuple<_U1, _U2>(),
00953         bool>::type = true>
00954         constexpr tuple(const tuple<_U1, _U2>& __in)
00955         : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
00956 
00957       template<typename _U1, typename _U2, typename
00958         enable_if<_TMC::template
00959                     _ConstructibleTuple<_U1, _U2>()
00960                   && !_TMC::template
00961                     _ImplicitlyConvertibleTuple<_U1, _U2>(),
00962         bool>::type = false>
00963         explicit constexpr tuple(const tuple<_U1, _U2>& __in)
00964         : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
00965 
00966       template<typename _U1, typename _U2, typename
00967         enable_if<_TMC::template
00968                     _MoveConstructibleTuple<_U1, _U2>()
00969                   && _TMC::template
00970                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
00971         bool>::type = true>
00972         constexpr tuple(tuple<_U1, _U2>&& __in)
00973         : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
00974 
00975       template<typename _U1, typename _U2, typename
00976         enable_if<_TMC::template
00977                     _MoveConstructibleTuple<_U1, _U2>()
00978                   && !_TMC::template
00979                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
00980         bool>::type = false>
00981         explicit constexpr tuple(tuple<_U1, _U2>&& __in)
00982         : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
00983 
00984       template<typename _U1, typename _U2, typename
00985         enable_if<_TMC::template
00986                     _ConstructibleTuple<_U1, _U2>()
00987                   && _TMC::template
00988                     _ImplicitlyConvertibleTuple<_U1, _U2>(),
00989         bool>::type = true>
00990         constexpr tuple(const pair<_U1, _U2>& __in)
00991         : _Inherited(__in.first, __in.second) { }
00992 
00993       template<typename _U1, typename _U2, typename
00994         enable_if<_TMC::template
00995                     _ConstructibleTuple<_U1, _U2>()
00996                   && !_TMC::template
00997                     _ImplicitlyConvertibleTuple<_U1, _U2>(),
00998         bool>::type = false>
00999         explicit constexpr tuple(const pair<_U1, _U2>& __in)
01000         : _Inherited(__in.first, __in.second) { }
01001 
01002       template<typename _U1, typename _U2, typename
01003         enable_if<_TMC::template
01004                     _MoveConstructibleTuple<_U1, _U2>()
01005                   && _TMC::template
01006                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
01007         bool>::type = true>
01008         constexpr tuple(pair<_U1, _U2>&& __in)
01009         : _Inherited(std::forward<_U1>(__in.first),
01010                      std::forward<_U2>(__in.second)) { }
01011 
01012       template<typename _U1, typename _U2, typename
01013         enable_if<_TMC::template
01014                     _MoveConstructibleTuple<_U1, _U2>()
01015                   && !_TMC::template
01016                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
01017         bool>::type = false>
01018         explicit constexpr tuple(pair<_U1, _U2>&& __in)
01019         : _Inherited(std::forward<_U1>(__in.first),
01020                      std::forward<_U2>(__in.second)) { }
01021 
01022       // Allocator-extended constructors.
01023 
01024       template<typename _Alloc>
01025         tuple(allocator_arg_t __tag, const _Alloc& __a)
01026         : _Inherited(__tag, __a) { }
01027 
01028       template<typename _Alloc, typename _Dummy = void,
01029                typename enable_if<
01030                  _TCC<_Dummy>::template
01031                    _ConstructibleTuple<_T1, _T2>()
01032                  && _TCC<_Dummy>::template
01033                    _ImplicitlyConvertibleTuple<_T1, _T2>(),
01034                bool>::type=true>
01035 
01036         tuple(allocator_arg_t __tag, const _Alloc& __a,
01037               const _T1& __a1, const _T2& __a2)
01038         : _Inherited(__tag, __a, __a1, __a2) { }
01039 
01040       template<typename _Alloc, typename _Dummy = void,
01041                typename enable_if<
01042                  _TCC<_Dummy>::template
01043                    _ConstructibleTuple<_T1, _T2>()
01044                  && !_TCC<_Dummy>::template
01045                    _ImplicitlyConvertibleTuple<_T1, _T2>(),
01046                bool>::type=false>
01047 
01048         explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
01049               const _T1& __a1, const _T2& __a2)
01050         : _Inherited(__tag, __a, __a1, __a2) { }
01051 
01052       template<typename _Alloc, typename _U1, typename _U2, typename
01053         enable_if<_TMC::template
01054                     _MoveConstructibleTuple<_U1, _U2>()
01055                   && _TMC::template
01056                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
01057         bool>::type = true>
01058         tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2)
01059         : _Inherited(__tag, __a, std::forward<_U1>(__a1),
01060                      std::forward<_U2>(__a2)) { }
01061 
01062       template<typename _Alloc, typename _U1, typename _U2, typename
01063         enable_if<_TMC::template
01064                     _MoveConstructibleTuple<_U1, _U2>()
01065                   && !_TMC::template
01066                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
01067         bool>::type = false>
01068         explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
01069                        _U1&& __a1, _U2&& __a2)
01070         : _Inherited(__tag, __a, std::forward<_U1>(__a1),
01071                      std::forward<_U2>(__a2)) { }
01072 
01073       template<typename _Alloc>
01074         tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in)
01075         : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { }
01076 
01077       template<typename _Alloc>
01078         tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in)
01079         : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { }
01080 
01081       template<typename _Alloc, typename _U1, typename _U2, typename
01082         enable_if<_TMC::template
01083                     _ConstructibleTuple<_U1, _U2>()
01084                   && _TMC::template
01085                     _ImplicitlyConvertibleTuple<_U1, _U2>(),
01086         bool>::type = true>
01087         tuple(allocator_arg_t __tag, const _Alloc& __a,
01088               const tuple<_U1, _U2>& __in)
01089         : _Inherited(__tag, __a,
01090                      static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
01091         { }
01092 
01093       template<typename _Alloc, typename _U1, typename _U2, typename
01094         enable_if<_TMC::template
01095                     _ConstructibleTuple<_U1, _U2>()
01096                   && !_TMC::template
01097                     _ImplicitlyConvertibleTuple<_U1, _U2>(),
01098         bool>::type = false>
01099         explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
01100               const tuple<_U1, _U2>& __in)
01101         : _Inherited(__tag, __a,
01102                      static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in))
01103         { }
01104 
01105       template<typename _Alloc, typename _U1, typename _U2, typename
01106         enable_if<_TMC::template
01107                     _MoveConstructibleTuple<_U1, _U2>()
01108                   && _TMC::template
01109                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
01110         bool>::type = true>
01111         tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in)
01112         : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
01113         { }
01114 
01115       template<typename _Alloc, typename _U1, typename _U2, typename
01116         enable_if<_TMC::template
01117                     _MoveConstructibleTuple<_U1, _U2>()
01118                   && !_TMC::template
01119                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
01120         bool>::type = false>
01121         explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
01122                        tuple<_U1, _U2>&& __in)
01123         : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
01124         { }
01125 
01126       template<typename _Alloc, typename _U1, typename _U2, typename
01127         enable_if<_TMC::template
01128                     _ConstructibleTuple<_U1, _U2>()
01129                   && _TMC::template
01130                     _ImplicitlyConvertibleTuple<_U1, _U2>(),
01131         bool>::type = true>
01132         tuple(allocator_arg_t __tag, const _Alloc& __a,
01133               const pair<_U1, _U2>& __in)
01134         : _Inherited(__tag, __a, __in.first, __in.second) { }
01135 
01136       template<typename _Alloc, typename _U1, typename _U2, typename
01137         enable_if<_TMC::template
01138                     _ConstructibleTuple<_U1, _U2>()
01139                   && !_TMC::template
01140                     _ImplicitlyConvertibleTuple<_U1, _U2>(),
01141         bool>::type = false>
01142         explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
01143               const pair<_U1, _U2>& __in)
01144         : _Inherited(__tag, __a, __in.first, __in.second) { }
01145 
01146       template<typename _Alloc, typename _U1, typename _U2, typename
01147         enable_if<_TMC::template
01148                     _MoveConstructibleTuple<_U1, _U2>()
01149                   && _TMC::template
01150                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
01151         bool>::type = true>
01152         tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in)
01153         : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
01154                      std::forward<_U2>(__in.second)) { }
01155 
01156       template<typename _Alloc, typename _U1, typename _U2, typename
01157         enable_if<_TMC::template
01158                     _MoveConstructibleTuple<_U1, _U2>()
01159                   && !_TMC::template
01160                     _ImplicitlyMoveConvertibleTuple<_U1, _U2>(),
01161         bool>::type = false>
01162         explicit tuple(allocator_arg_t __tag, const _Alloc& __a,
01163                        pair<_U1, _U2>&& __in)
01164         : _Inherited(__tag, __a, std::forward<_U1>(__in.first),
01165                      std::forward<_U2>(__in.second)) { }
01166 
01167       tuple&
01168       operator=(const tuple& __in)
01169       {
01170         static_cast<_Inherited&>(*this) = __in;
01171         return *this;
01172       }
01173 
01174       tuple&
01175       operator=(tuple&& __in)
01176       noexcept(is_nothrow_move_assignable<_Inherited>::value)
01177       {
01178         static_cast<_Inherited&>(*this) = std::move(__in);
01179         return *this;
01180       }
01181 
01182       template<typename _U1, typename _U2>
01183         tuple&
01184         operator=(const tuple<_U1, _U2>& __in)
01185         {
01186           static_cast<_Inherited&>(*this) = __in;
01187           return *this;
01188         }
01189 
01190       template<typename _U1, typename _U2>
01191         tuple&
01192         operator=(tuple<_U1, _U2>&& __in)
01193         {
01194           static_cast<_Inherited&>(*this) = std::move(__in);
01195           return *this;
01196         }
01197 
01198       template<typename _U1, typename _U2>
01199         tuple&
01200         operator=(const pair<_U1, _U2>& __in)
01201         {
01202           this->_M_head(*this) = __in.first;
01203           this->_M_tail(*this)._M_head(*this) = __in.second;
01204           return *this;
01205         }
01206 
01207       template<typename _U1, typename _U2>
01208         tuple&
01209         operator=(pair<_U1, _U2>&& __in)
01210         {
01211           this->_M_head(*this) = std::forward<_U1>(__in.first);
01212           this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second);
01213           return *this;
01214         }
01215 
01216       void
01217       swap(tuple& __in)
01218       noexcept(noexcept(__in._M_swap(__in)))
01219       { _Inherited::_M_swap(__in); }
01220     };
01221 
01222 
01223   /**
01224    * Recursive case for tuple_element: strip off the first element in
01225    * the tuple and retrieve the (i-1)th element of the remaining tuple.
01226    */
01227   template<std::size_t __i, typename _Head, typename... _Tail>
01228     struct tuple_element<__i, tuple<_Head, _Tail...> >
01229     : tuple_element<__i - 1, tuple<_Tail...> > { };
01230 
01231   /**
01232    * Basis case for tuple_element: The first element is the one we're seeking.
01233    */
01234   template<typename _Head, typename... _Tail>
01235     struct tuple_element<0, tuple<_Head, _Tail...> >
01236     {
01237       typedef _Head type;
01238     };
01239 
01240   /// class tuple_size
01241   template<typename... _Elements>
01242     struct tuple_size<tuple<_Elements...>>
01243     : public integral_constant<std::size_t, sizeof...(_Elements)> { };
01244 
01245   template<std::size_t __i, typename _Head, typename... _Tail>
01246     constexpr _Head&
01247     __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
01248     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
01249 
01250   template<std::size_t __i, typename _Head, typename... _Tail>
01251     constexpr const _Head&
01252     __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
01253     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
01254 
01255   /// Return a reference to the ith element of a tuple.
01256   template<std::size_t __i, typename... _Elements>
01257     constexpr __tuple_element_t<__i, tuple<_Elements...>>&
01258     get(tuple<_Elements...>& __t) noexcept
01259     { return std::__get_helper<__i>(__t); }
01260 
01261   /// Return a const reference to the ith element of a const tuple.
01262   template<std::size_t __i, typename... _Elements>
01263     constexpr const __tuple_element_t<__i, tuple<_Elements...>>&
01264     get(const tuple<_Elements...>& __t) noexcept
01265     { return std::__get_helper<__i>(__t); }
01266 
01267   /// Return an rvalue reference to the ith element of a tuple rvalue.
01268   template<std::size_t __i, typename... _Elements>
01269     constexpr __tuple_element_t<__i, tuple<_Elements...>>&&
01270     get(tuple<_Elements...>&& __t) noexcept
01271     {
01272       typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type;
01273       return std::forward<__element_type&&>(std::get<__i>(__t));
01274     }
01275 
01276 #if __cplusplus > 201103L
01277 
01278 #define __cpp_lib_tuples_by_type 201304
01279 
01280   template<typename _Head, size_t __i, typename... _Tail>
01281     constexpr _Head&
01282     __get_helper2(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
01283     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
01284 
01285   template<typename _Head, size_t __i, typename... _Tail>
01286     constexpr const _Head&
01287     __get_helper2(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept
01288     { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); }
01289 
01290   /// Return a reference to the unique element of type _Tp of a tuple.
01291   template <typename _Tp, typename... _Types>
01292     constexpr _Tp&
01293     get(tuple<_Types...>& __t) noexcept
01294     { return std::__get_helper2<_Tp>(__t); }
01295 
01296   /// Return a reference to the unique element of type _Tp of a tuple rvalue.
01297   template <typename _Tp, typename... _Types>
01298     constexpr _Tp&&
01299     get(tuple<_Types...>&& __t) noexcept
01300     { return std::forward<_Tp&&>(std::__get_helper2<_Tp>(__t)); }
01301 
01302   /// Return a const reference to the unique element of type _Tp of a tuple.
01303   template <typename _Tp, typename... _Types>
01304     constexpr const _Tp&
01305     get(const tuple<_Types...>& __t) noexcept
01306     { return std::__get_helper2<_Tp>(__t); }
01307 #endif
01308 
01309   // This class performs the comparison operations on tuples
01310   template<typename _Tp, typename _Up, size_t __i, size_t __size>
01311     struct __tuple_compare
01312     {
01313       static constexpr bool
01314       __eq(const _Tp& __t, const _Up& __u)
01315       {
01316         return bool(std::get<__i>(__t) == std::get<__i>(__u))
01317           && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u);
01318       }
01319    
01320       static constexpr bool
01321       __less(const _Tp& __t, const _Up& __u)
01322       {
01323         return bool(std::get<__i>(__t) < std::get<__i>(__u))
01324           || (!bool(std::get<__i>(__u) < std::get<__i>(__t))
01325               && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u));
01326       }
01327     };
01328 
01329   template<typename _Tp, typename _Up, size_t __size>
01330     struct __tuple_compare<_Tp, _Up, __size, __size>
01331     {
01332       static constexpr bool
01333       __eq(const _Tp&, const _Up&) { return true; }
01334    
01335       static constexpr bool
01336       __less(const _Tp&, const _Up&) { return false; }
01337     };
01338 
01339   template<typename... _TElements, typename... _UElements>
01340     constexpr bool
01341     operator==(const tuple<_TElements...>& __t,
01342                const tuple<_UElements...>& __u)
01343     {
01344       static_assert(sizeof...(_TElements) == sizeof...(_UElements),
01345           "tuple objects can only be compared if they have equal sizes.");
01346       using __compare = __tuple_compare<tuple<_TElements...>,
01347                                         tuple<_UElements...>,
01348                                         0, sizeof...(_TElements)>;
01349       return __compare::__eq(__t, __u);
01350     }
01351 
01352   template<typename... _TElements, typename... _UElements>
01353     constexpr bool
01354     operator<(const tuple<_TElements...>& __t,
01355               const tuple<_UElements...>& __u)
01356     {
01357       static_assert(sizeof...(_TElements) == sizeof...(_UElements),
01358           "tuple objects can only be compared if they have equal sizes.");
01359       using __compare = __tuple_compare<tuple<_TElements...>,
01360                                         tuple<_UElements...>,
01361                                         0, sizeof...(_TElements)>;
01362       return __compare::__less(__t, __u);
01363     }
01364 
01365   template<typename... _TElements, typename... _UElements>
01366     constexpr bool
01367     operator!=(const tuple<_TElements...>& __t,
01368                const tuple<_UElements...>& __u)
01369     { return !(__t == __u); }
01370 
01371   template<typename... _TElements, typename... _UElements>
01372     constexpr bool
01373     operator>(const tuple<_TElements...>& __t,
01374               const tuple<_UElements...>& __u)
01375     { return __u < __t; }
01376 
01377   template<typename... _TElements, typename... _UElements>
01378     constexpr bool
01379     operator<=(const tuple<_TElements...>& __t,
01380                const tuple<_UElements...>& __u)
01381     { return !(__u < __t); }
01382 
01383   template<typename... _TElements, typename... _UElements>
01384     constexpr bool
01385     operator>=(const tuple<_TElements...>& __t,
01386                const tuple<_UElements...>& __u)
01387     { return !(__t < __u); }
01388 
01389   // NB: DR 705.
01390   template<typename... _Elements>
01391     constexpr tuple<typename __decay_and_strip<_Elements>::__type...>
01392     make_tuple(_Elements&&... __args)
01393     {
01394       typedef tuple<typename __decay_and_strip<_Elements>::__type...>
01395         __result_type;
01396       return __result_type(std::forward<_Elements>(__args)...);
01397     }
01398 
01399   // _GLIBCXX_RESOLVE_LIB_DEFECTS
01400   // 2275. Why is forward_as_tuple not constexpr?
01401   template<typename... _Elements>
01402     constexpr tuple<_Elements&&...>
01403     forward_as_tuple(_Elements&&... __args) noexcept
01404     { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
01405 
01406   template<typename... _Tps>
01407     struct __is_tuple_like_impl<tuple<_Tps...>> : true_type
01408     { };
01409 
01410   // Internal type trait that allows us to sfinae-protect tuple_cat.
01411   template<typename _Tp>
01412     struct __is_tuple_like
01413     : public __is_tuple_like_impl<typename std::remove_cv
01414             <typename std::remove_reference<_Tp>::type>::type>::type
01415     { };
01416 
01417   template<size_t, typename, typename, size_t>
01418     struct __make_tuple_impl;
01419 
01420   template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm>
01421     struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm>
01422     : __make_tuple_impl<_Idx + 1,
01423                         tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>,
01424                         _Tuple, _Nm>
01425     { };
01426 
01427   template<std::size_t _Nm, typename _Tuple, typename... _Tp>
01428     struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm>
01429     {
01430       typedef tuple<_Tp...> __type;
01431     };
01432 
01433   template<typename _Tuple>
01434     struct __do_make_tuple
01435     : __make_tuple_impl<0, tuple<>, _Tuple, std::tuple_size<_Tuple>::value>
01436     { };
01437 
01438   // Returns the std::tuple equivalent of a tuple-like type.
01439   template<typename _Tuple>
01440     struct __make_tuple
01441     : public __do_make_tuple<typename std::remove_cv
01442             <typename std::remove_reference<_Tuple>::type>::type>
01443     { };
01444 
01445   // Combines several std::tuple's into a single one.
01446   template<typename...>
01447     struct __combine_tuples;
01448 
01449   template<>
01450     struct __combine_tuples<>
01451     {
01452       typedef tuple<> __type;
01453     };
01454 
01455   template<typename... _Ts>
01456     struct __combine_tuples<tuple<_Ts...>>
01457     {
01458       typedef tuple<_Ts...> __type;
01459     };
01460 
01461   template<typename... _T1s, typename... _T2s, typename... _Rem>
01462     struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...>
01463     {
01464       typedef typename __combine_tuples<tuple<_T1s..., _T2s...>,
01465                                         _Rem...>::__type __type;
01466     };
01467 
01468   // Computes the result type of tuple_cat given a set of tuple-like types.
01469   template<typename... _Tpls>
01470     struct __tuple_cat_result
01471     {
01472       typedef typename __combine_tuples
01473         <typename __make_tuple<_Tpls>::__type...>::__type __type;
01474     };
01475 
01476   // Helper to determine the index set for the first tuple-like
01477   // type of a given set.
01478   template<typename...>
01479     struct __make_1st_indices;
01480 
01481   template<>
01482     struct __make_1st_indices<>
01483     {
01484       typedef std::_Index_tuple<> __type;
01485     };
01486 
01487   template<typename _Tp, typename... _Tpls>
01488     struct __make_1st_indices<_Tp, _Tpls...>
01489     {
01490       typedef typename std::_Build_index_tuple<std::tuple_size<
01491         typename std::remove_reference<_Tp>::type>::value>::__type __type;
01492     };
01493 
01494   // Performs the actual concatenation by step-wise expanding tuple-like
01495   // objects into the elements,  which are finally forwarded into the
01496   // result tuple.
01497   template<typename _Ret, typename _Indices, typename... _Tpls>
01498     struct __tuple_concater;
01499 
01500   template<typename _Ret, std::size_t... _Is, typename _Tp, typename... _Tpls>
01501     struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...>
01502     {
01503       template<typename... _Us>
01504         static constexpr _Ret
01505         _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us)
01506         {
01507           typedef typename __make_1st_indices<_Tpls...>::__type __idx;
01508           typedef __tuple_concater<_Ret, __idx, _Tpls...>      __next;
01509           return __next::_S_do(std::forward<_Tpls>(__tps)...,
01510                                std::forward<_Us>(__us)...,
01511                                std::get<_Is>(std::forward<_Tp>(__tp))...);
01512         }
01513     };
01514 
01515   template<typename _Ret>
01516     struct __tuple_concater<_Ret, std::_Index_tuple<>>
01517     {
01518       template<typename... _Us>
01519         static constexpr _Ret
01520         _S_do(_Us&&... __us)
01521         {
01522           return _Ret(std::forward<_Us>(__us)...);
01523         }
01524     };
01525 
01526   /// tuple_cat
01527   template<typename... _Tpls, typename = typename
01528            enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type>
01529     constexpr auto
01530     tuple_cat(_Tpls&&... __tpls)
01531     -> typename __tuple_cat_result<_Tpls...>::__type
01532     {
01533       typedef typename __tuple_cat_result<_Tpls...>::__type __ret;
01534       typedef typename __make_1st_indices<_Tpls...>::__type __idx;
01535       typedef __tuple_concater<__ret, __idx, _Tpls...> __concater;
01536       return __concater::_S_do(std::forward<_Tpls>(__tpls)...);
01537     }
01538 
01539   // _GLIBCXX_RESOLVE_LIB_DEFECTS
01540   // 2301. Why is tie not constexpr?
01541   /// tie
01542   template<typename... _Elements>
01543     constexpr tuple<_Elements&...>
01544     tie(_Elements&... __args) noexcept
01545     { return tuple<_Elements&...>(__args...); }
01546 
01547   /// swap
01548   template<typename... _Elements>
01549     inline void 
01550     swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
01551     noexcept(noexcept(__x.swap(__y)))
01552     { __x.swap(__y); }
01553 
01554   // A class (and instance) which can be used in 'tie' when an element
01555   // of a tuple is not required
01556   struct _Swallow_assign
01557   {
01558     template<class _Tp>
01559       const _Swallow_assign&
01560       operator=(const _Tp&) const
01561       { return *this; }
01562   };
01563 
01564   const _Swallow_assign ignore{};
01565 
01566   /// Partial specialization for tuples
01567   template<typename... _Types, typename _Alloc>
01568     struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { };
01569 
01570   // See stl_pair.h...
01571   template<class _T1, class _T2>
01572     template<typename... _Args1, typename... _Args2>
01573       inline
01574       pair<_T1, _T2>::
01575       pair(piecewise_construct_t,
01576            tuple<_Args1...> __first, tuple<_Args2...> __second)
01577       : pair(__first, __second,
01578              typename _Build_index_tuple<sizeof...(_Args1)>::__type(),
01579              typename _Build_index_tuple<sizeof...(_Args2)>::__type())
01580       { }
01581 
01582   template<class _T1, class _T2>
01583     template<typename... _Args1, std::size_t... _Indexes1,
01584              typename... _Args2, std::size_t... _Indexes2>
01585       inline
01586       pair<_T1, _T2>::
01587       pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2,
01588            _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>)
01589       : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...),
01590         second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
01591       { }
01592 
01593   /// @}
01594 
01595 _GLIBCXX_END_NAMESPACE_VERSION
01596 } // namespace std
01597 
01598 #endif // C++11
01599 
01600 #endif // _GLIBCXX_TUPLE