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