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