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