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