libstdc++
|
00001 // <tuple> -*- C++ -*- 00002 00003 // Copyright (C) 2007-2013 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 /// Finds the size of a given tuple type. 00716 template<typename _Tp> 00717 struct tuple_size; 00718 00719 template<typename _Tp> 00720 struct tuple_size<const _Tp> 00721 : public integral_constant< 00722 typename remove_cv<decltype(tuple_size<_Tp>::value)>::type, 00723 tuple_size<_Tp>::value> { }; 00724 00725 template<typename _Tp> 00726 struct tuple_size<volatile _Tp> 00727 : public integral_constant< 00728 typename remove_cv<decltype(tuple_size<_Tp>::value)>::type, 00729 tuple_size<_Tp>::value> { }; 00730 00731 template<typename _Tp> 00732 struct tuple_size<const volatile _Tp> 00733 : public integral_constant< 00734 typename remove_cv<decltype(tuple_size<_Tp>::value)>::type, 00735 tuple_size<_Tp>::value> { }; 00736 00737 /// class tuple_size 00738 template<typename... _Elements> 00739 struct tuple_size<tuple<_Elements...>> 00740 : public integral_constant<std::size_t, sizeof...(_Elements)> { }; 00741 00742 template<std::size_t __i, typename _Head, typename... _Tail> 00743 constexpr typename __add_ref<_Head>::type 00744 __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 00745 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 00746 00747 template<std::size_t __i, typename _Head, typename... _Tail> 00748 constexpr typename __add_c_ref<_Head>::type 00749 __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 00750 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 00751 00752 // Return a reference (const reference, rvalue reference) to the ith element 00753 // of a tuple. Any const or non-const ref elements are returned with their 00754 // original type. 00755 template<std::size_t __i, typename... _Elements> 00756 constexpr typename __add_ref< 00757 typename tuple_element<__i, tuple<_Elements...>>::type 00758 >::type 00759 get(tuple<_Elements...>& __t) noexcept 00760 { return std::__get_helper<__i>(__t); } 00761 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 template<std::size_t __i, typename... _Elements> 00770 constexpr typename __add_r_ref< 00771 typename tuple_element<__i, tuple<_Elements...>>::type 00772 >::type 00773 get(tuple<_Elements...>&& __t) noexcept 00774 { return std::forward<typename tuple_element<__i, 00775 tuple<_Elements...>>::type&&>(get<__i>(__t)); } 00776 00777 // This class helps construct the various comparison operations on tuples 00778 template<std::size_t __check_equal_size, std::size_t __i, std::size_t __j, 00779 typename _Tp, typename _Up> 00780 struct __tuple_compare; 00781 00782 template<std::size_t __i, std::size_t __j, typename _Tp, typename _Up> 00783 struct __tuple_compare<0, __i, __j, _Tp, _Up> 00784 { 00785 static constexpr bool 00786 __eq(const _Tp& __t, const _Up& __u) 00787 { 00788 return (get<__i>(__t) == get<__i>(__u) && 00789 __tuple_compare<0, __i + 1, __j, _Tp, _Up>::__eq(__t, __u)); 00790 } 00791 00792 static constexpr bool 00793 __less(const _Tp& __t, const _Up& __u) 00794 { 00795 return ((get<__i>(__t) < get<__i>(__u)) 00796 || !(get<__i>(__u) < get<__i>(__t)) && 00797 __tuple_compare<0, __i + 1, __j, _Tp, _Up>::__less(__t, __u)); 00798 } 00799 }; 00800 00801 template<std::size_t __i, typename _Tp, typename _Up> 00802 struct __tuple_compare<0, __i, __i, _Tp, _Up> 00803 { 00804 static constexpr bool 00805 __eq(const _Tp&, const _Up&) { return true; } 00806 00807 static constexpr bool 00808 __less(const _Tp&, const _Up&) { return false; } 00809 }; 00810 00811 template<typename... _TElements, typename... _UElements> 00812 constexpr bool 00813 operator==(const tuple<_TElements...>& __t, 00814 const tuple<_UElements...>& __u) 00815 { 00816 typedef tuple<_TElements...> _Tp; 00817 typedef tuple<_UElements...> _Up; 00818 return bool(__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value, 00819 0, tuple_size<_Tp>::value, _Tp, _Up>::__eq(__t, __u)); 00820 } 00821 00822 template<typename... _TElements, typename... _UElements> 00823 constexpr bool 00824 operator<(const tuple<_TElements...>& __t, 00825 const tuple<_UElements...>& __u) 00826 { 00827 typedef tuple<_TElements...> _Tp; 00828 typedef tuple<_UElements...> _Up; 00829 return bool(__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value, 00830 0, tuple_size<_Tp>::value, _Tp, _Up>::__less(__t, __u)); 00831 } 00832 00833 template<typename... _TElements, typename... _UElements> 00834 inline constexpr bool 00835 operator!=(const tuple<_TElements...>& __t, 00836 const tuple<_UElements...>& __u) 00837 { return !(__t == __u); } 00838 00839 template<typename... _TElements, typename... _UElements> 00840 inline constexpr bool 00841 operator>(const tuple<_TElements...>& __t, 00842 const tuple<_UElements...>& __u) 00843 { return __u < __t; } 00844 00845 template<typename... _TElements, typename... _UElements> 00846 inline constexpr bool 00847 operator<=(const tuple<_TElements...>& __t, 00848 const tuple<_UElements...>& __u) 00849 { return !(__u < __t); } 00850 00851 template<typename... _TElements, typename... _UElements> 00852 inline constexpr bool 00853 operator>=(const tuple<_TElements...>& __t, 00854 const tuple<_UElements...>& __u) 00855 { return !(__t < __u); } 00856 00857 // NB: DR 705. 00858 template<typename... _Elements> 00859 constexpr tuple<typename __decay_and_strip<_Elements>::__type...> 00860 make_tuple(_Elements&&... __args) 00861 { 00862 typedef tuple<typename __decay_and_strip<_Elements>::__type...> 00863 __result_type; 00864 return __result_type(std::forward<_Elements>(__args)...); 00865 } 00866 00867 template<typename... _Elements> 00868 tuple<_Elements&&...> 00869 forward_as_tuple(_Elements&&... __args) noexcept 00870 { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); } 00871 00872 template<typename> 00873 struct __is_tuple_like_impl : false_type 00874 { }; 00875 00876 template<typename... _Tps> 00877 struct __is_tuple_like_impl<tuple<_Tps...>> : true_type 00878 { }; 00879 00880 template<typename _T1, typename _T2> 00881 struct __is_tuple_like_impl<pair<_T1, _T2>> : true_type 00882 { }; 00883 00884 template<typename _Tp, std::size_t _Nm> 00885 struct __is_tuple_like_impl<array<_Tp, _Nm>> : true_type 00886 { }; 00887 00888 // Internal type trait that allows us to sfinae-protect tuple_cat. 00889 template<typename _Tp> 00890 struct __is_tuple_like 00891 : public __is_tuple_like_impl<typename std::remove_cv 00892 <typename std::remove_reference<_Tp>::type>::type>::type 00893 { }; 00894 00895 // Stores a tuple of indices. Also used by bind() to extract the elements 00896 // in a tuple. 00897 template<std::size_t... _Indexes> 00898 struct _Index_tuple 00899 { 00900 typedef _Index_tuple<_Indexes..., sizeof...(_Indexes)> __next; 00901 }; 00902 00903 // Builds an _Index_tuple<0, 1, 2, ..., _Num-1>. 00904 template<std::size_t _Num> 00905 struct _Build_index_tuple 00906 { 00907 typedef typename _Build_index_tuple<_Num - 1>::__type::__next __type; 00908 }; 00909 00910 template<> 00911 struct _Build_index_tuple<0> 00912 { 00913 typedef _Index_tuple<> __type; 00914 }; 00915 00916 template<std::size_t, typename, typename, std::size_t> 00917 struct __make_tuple_impl; 00918 00919 template<std::size_t _Idx, typename _Tuple, typename... _Tp, 00920 std::size_t _Nm> 00921 struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm> 00922 { 00923 typedef typename __make_tuple_impl<_Idx + 1, tuple<_Tp..., 00924 typename std::tuple_element<_Idx, _Tuple>::type>, _Tuple, _Nm>::__type 00925 __type; 00926 }; 00927 00928 template<std::size_t _Nm, typename _Tuple, typename... _Tp> 00929 struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm> 00930 { 00931 typedef tuple<_Tp...> __type; 00932 }; 00933 00934 template<typename _Tuple> 00935 struct __do_make_tuple 00936 : public __make_tuple_impl<0, tuple<>, _Tuple, 00937 std::tuple_size<_Tuple>::value> 00938 { }; 00939 00940 // Returns the std::tuple equivalent of a tuple-like type. 00941 template<typename _Tuple> 00942 struct __make_tuple 00943 : public __do_make_tuple<typename std::remove_cv 00944 <typename std::remove_reference<_Tuple>::type>::type> 00945 { }; 00946 00947 // Combines several std::tuple's into a single one. 00948 template<typename...> 00949 struct __combine_tuples; 00950 00951 template<> 00952 struct __combine_tuples<> 00953 { 00954 typedef tuple<> __type; 00955 }; 00956 00957 template<typename... _Ts> 00958 struct __combine_tuples<tuple<_Ts...>> 00959 { 00960 typedef tuple<_Ts...> __type; 00961 }; 00962 00963 template<typename... _T1s, typename... _T2s, typename... _Rem> 00964 struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...> 00965 { 00966 typedef typename __combine_tuples<tuple<_T1s..., _T2s...>, 00967 _Rem...>::__type __type; 00968 }; 00969 00970 // Computes the result type of tuple_cat given a set of tuple-like types. 00971 template<typename... _Tpls> 00972 struct __tuple_cat_result 00973 { 00974 typedef typename __combine_tuples 00975 <typename __make_tuple<_Tpls>::__type...>::__type __type; 00976 }; 00977 00978 // Helper to determine the index set for the first tuple-like 00979 // type of a given set. 00980 template<typename...> 00981 struct __make_1st_indices; 00982 00983 template<> 00984 struct __make_1st_indices<> 00985 { 00986 typedef std::_Index_tuple<> __type; 00987 }; 00988 00989 template<typename _Tp, typename... _Tpls> 00990 struct __make_1st_indices<_Tp, _Tpls...> 00991 { 00992 typedef typename std::_Build_index_tuple<std::tuple_size< 00993 typename std::remove_reference<_Tp>::type>::value>::__type __type; 00994 }; 00995 00996 // Performs the actual concatenation by step-wise expanding tuple-like 00997 // objects into the elements, which are finally forwarded into the 00998 // result tuple. 00999 template<typename _Ret, typename _Indices, typename... _Tpls> 01000 struct __tuple_concater; 01001 01002 template<typename _Ret, std::size_t... _Is, typename _Tp, typename... _Tpls> 01003 struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...> 01004 { 01005 template<typename... _Us> 01006 static constexpr _Ret 01007 _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us) 01008 { 01009 typedef typename __make_1st_indices<_Tpls...>::__type __idx; 01010 typedef __tuple_concater<_Ret, __idx, _Tpls...> __next; 01011 return __next::_S_do(std::forward<_Tpls>(__tps)..., 01012 std::forward<_Us>(__us)..., 01013 std::get<_Is>(std::forward<_Tp>(__tp))...); 01014 } 01015 }; 01016 01017 template<typename _Ret> 01018 struct __tuple_concater<_Ret, std::_Index_tuple<>> 01019 { 01020 template<typename... _Us> 01021 static constexpr _Ret 01022 _S_do(_Us&&... __us) 01023 { 01024 return _Ret(std::forward<_Us>(__us)...); 01025 } 01026 }; 01027 01028 /// tuple_cat 01029 template<typename... _Tpls, typename = typename 01030 enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type> 01031 constexpr auto 01032 tuple_cat(_Tpls&&... __tpls) 01033 -> typename __tuple_cat_result<_Tpls...>::__type 01034 { 01035 typedef typename __tuple_cat_result<_Tpls...>::__type __ret; 01036 typedef typename __make_1st_indices<_Tpls...>::__type __idx; 01037 typedef __tuple_concater<__ret, __idx, _Tpls...> __concater; 01038 return __concater::_S_do(std::forward<_Tpls>(__tpls)...); 01039 } 01040 01041 /// tie 01042 template<typename... _Elements> 01043 inline tuple<_Elements&...> 01044 tie(_Elements&... __args) noexcept 01045 { return tuple<_Elements&...>(__args...); } 01046 01047 /// swap 01048 template<typename... _Elements> 01049 inline void 01050 swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y) 01051 noexcept(noexcept(__x.swap(__y))) 01052 { __x.swap(__y); } 01053 01054 // A class (and instance) which can be used in 'tie' when an element 01055 // of a tuple is not required 01056 struct _Swallow_assign 01057 { 01058 template<class _Tp> 01059 const _Swallow_assign& 01060 operator=(const _Tp&) const 01061 { return *this; } 01062 }; 01063 01064 const _Swallow_assign ignore{}; 01065 01066 /// Partial specialization for tuples 01067 template<typename... _Types, typename _Alloc> 01068 struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { }; 01069 01070 // See stl_pair.h... 01071 template<class _T1, class _T2> 01072 template<typename... _Args1, typename... _Args2> 01073 inline 01074 pair<_T1, _T2>:: 01075 pair(piecewise_construct_t, 01076 tuple<_Args1...> __first, tuple<_Args2...> __second) 01077 : pair(__first, __second, 01078 typename _Build_index_tuple<sizeof...(_Args1)>::__type(), 01079 typename _Build_index_tuple<sizeof...(_Args2)>::__type()) 01080 { } 01081 01082 template<class _T1, class _T2> 01083 template<typename... _Args1, std::size_t... _Indexes1, 01084 typename... _Args2, std::size_t... _Indexes2> 01085 inline 01086 pair<_T1, _T2>:: 01087 pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2, 01088 _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>) 01089 : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...), 01090 second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...) 01091 { } 01092 01093 /// @} 01094 01095 _GLIBCXX_END_NAMESPACE_VERSION 01096 } // namespace std 01097 01098 #endif // C++11 01099 01100 #endif // _GLIBCXX_TUPLE