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