libstdc++
|
00001 // <tuple> -*- C++ -*- 00002 00003 // Copyright (C) 2007-2016 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 template<std::size_t _Idx, typename _Head, bool _IsEmptyNotFinal> 00052 struct _Head_base; 00053 00054 template<std::size_t _Idx, typename _Head> 00055 struct _Head_base<_Idx, _Head, true> 00056 : public _Head 00057 { 00058 constexpr _Head_base() 00059 : _Head() { } 00060 00061 constexpr _Head_base(const _Head& __h) 00062 : _Head(__h) { } 00063 00064 constexpr _Head_base(const _Head_base&) = default; 00065 constexpr _Head_base(_Head_base&&) = default; 00066 00067 template<typename _UHead> 00068 constexpr _Head_base(_UHead&& __h) 00069 : _Head(std::forward<_UHead>(__h)) { } 00070 00071 _Head_base(allocator_arg_t, __uses_alloc0) 00072 : _Head() { } 00073 00074 template<typename _Alloc> 00075 _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a) 00076 : _Head(allocator_arg, *__a._M_a) { } 00077 00078 template<typename _Alloc> 00079 _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a) 00080 : _Head(*__a._M_a) { } 00081 00082 template<typename _UHead> 00083 _Head_base(__uses_alloc0, _UHead&& __uhead) 00084 : _Head(std::forward<_UHead>(__uhead)) { } 00085 00086 template<typename _Alloc, typename _UHead> 00087 _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead) 00088 : _Head(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) { } 00089 00090 template<typename _Alloc, typename _UHead> 00091 _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead) 00092 : _Head(std::forward<_UHead>(__uhead), *__a._M_a) { } 00093 00094 static constexpr _Head& 00095 _M_head(_Head_base& __b) noexcept { return __b; } 00096 00097 static constexpr const _Head& 00098 _M_head(const _Head_base& __b) noexcept { return __b; } 00099 }; 00100 00101 template<std::size_t _Idx, typename _Head> 00102 struct _Head_base<_Idx, _Head, false> 00103 { 00104 constexpr _Head_base() 00105 : _M_head_impl() { } 00106 00107 constexpr _Head_base(const _Head& __h) 00108 : _M_head_impl(__h) { } 00109 00110 constexpr _Head_base(const _Head_base&) = default; 00111 constexpr _Head_base(_Head_base&&) = default; 00112 00113 template<typename _UHead> 00114 constexpr _Head_base(_UHead&& __h) 00115 : _M_head_impl(std::forward<_UHead>(__h)) { } 00116 00117 _Head_base(allocator_arg_t, __uses_alloc0) 00118 : _M_head_impl() { } 00119 00120 template<typename _Alloc> 00121 _Head_base(allocator_arg_t, __uses_alloc1<_Alloc> __a) 00122 : _M_head_impl(allocator_arg, *__a._M_a) { } 00123 00124 template<typename _Alloc> 00125 _Head_base(allocator_arg_t, __uses_alloc2<_Alloc> __a) 00126 : _M_head_impl(*__a._M_a) { } 00127 00128 template<typename _UHead> 00129 _Head_base(__uses_alloc0, _UHead&& __uhead) 00130 : _M_head_impl(std::forward<_UHead>(__uhead)) { } 00131 00132 template<typename _Alloc, typename _UHead> 00133 _Head_base(__uses_alloc1<_Alloc> __a, _UHead&& __uhead) 00134 : _M_head_impl(allocator_arg, *__a._M_a, std::forward<_UHead>(__uhead)) 00135 { } 00136 00137 template<typename _Alloc, typename _UHead> 00138 _Head_base(__uses_alloc2<_Alloc> __a, _UHead&& __uhead) 00139 : _M_head_impl(std::forward<_UHead>(__uhead), *__a._M_a) { } 00140 00141 static constexpr _Head& 00142 _M_head(_Head_base& __b) noexcept { return __b._M_head_impl; } 00143 00144 static constexpr const _Head& 00145 _M_head(const _Head_base& __b) noexcept { return __b._M_head_impl; } 00146 00147 _Head _M_head_impl; 00148 }; 00149 00150 /** 00151 * Contains the actual implementation of the @c tuple template, stored 00152 * as a recursive inheritance hierarchy from the first element (most 00153 * derived class) to the last (least derived class). The @c Idx 00154 * parameter gives the 0-based index of the element stored at this 00155 * point in the hierarchy; we use it to implement a constant-time 00156 * get() operation. 00157 */ 00158 template<std::size_t _Idx, typename... _Elements> 00159 struct _Tuple_impl; 00160 00161 template<typename _Tp> 00162 struct __is_empty_non_tuple : is_empty<_Tp> { }; 00163 00164 // Using EBO for elements that are tuples causes ambiguous base errors. 00165 template<typename _El0, typename... _El> 00166 struct __is_empty_non_tuple<tuple<_El0, _El...>> : false_type { }; 00167 00168 // Use the Empty Base-class Optimization for empty, non-final types. 00169 template<typename _Tp> 00170 using __empty_not_final 00171 = typename conditional<__is_final(_Tp), false_type, 00172 __is_empty_non_tuple<_Tp>>::type; 00173 00174 /** 00175 * Recursive tuple implementation. Here we store the @c Head element 00176 * and derive from a @c Tuple_impl containing the remaining elements 00177 * (which contains the @c Tail). 00178 */ 00179 template<std::size_t _Idx, typename _Head, typename... _Tail> 00180 struct _Tuple_impl<_Idx, _Head, _Tail...> 00181 : public _Tuple_impl<_Idx + 1, _Tail...>, 00182 private _Head_base<_Idx, _Head, __empty_not_final<_Head>::value> 00183 { 00184 template<std::size_t, typename...> friend class _Tuple_impl; 00185 00186 typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited; 00187 typedef _Head_base<_Idx, _Head, __empty_not_final<_Head>::value> _Base; 00188 00189 static constexpr _Head& 00190 _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } 00191 00192 static constexpr const _Head& 00193 _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } 00194 00195 static constexpr _Inherited& 00196 _M_tail(_Tuple_impl& __t) noexcept { return __t; } 00197 00198 static constexpr const _Inherited& 00199 _M_tail(const _Tuple_impl& __t) noexcept { return __t; } 00200 00201 constexpr _Tuple_impl() 00202 : _Inherited(), _Base() { } 00203 00204 explicit 00205 constexpr _Tuple_impl(const _Head& __head, const _Tail&... __tail) 00206 : _Inherited(__tail...), _Base(__head) { } 00207 00208 template<typename _UHead, typename... _UTail, typename = typename 00209 enable_if<sizeof...(_Tail) == sizeof...(_UTail)>::type> 00210 explicit 00211 constexpr _Tuple_impl(_UHead&& __head, _UTail&&... __tail) 00212 : _Inherited(std::forward<_UTail>(__tail)...), 00213 _Base(std::forward<_UHead>(__head)) { } 00214 00215 constexpr _Tuple_impl(const _Tuple_impl&) = default; 00216 00217 constexpr 00218 _Tuple_impl(_Tuple_impl&& __in) 00219 noexcept(__and_<is_nothrow_move_constructible<_Head>, 00220 is_nothrow_move_constructible<_Inherited>>::value) 00221 : _Inherited(std::move(_M_tail(__in))), 00222 _Base(std::forward<_Head>(_M_head(__in))) { } 00223 00224 template<typename... _UElements> 00225 constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in) 00226 : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)), 00227 _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { } 00228 00229 template<typename _UHead, typename... _UTails> 00230 constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) 00231 : _Inherited(std::move 00232 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))), 00233 _Base(std::forward<_UHead> 00234 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { } 00235 00236 template<typename _Alloc> 00237 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a) 00238 : _Inherited(__tag, __a), 00239 _Base(__tag, __use_alloc<_Head>(__a)) { } 00240 00241 template<typename _Alloc> 00242 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 00243 const _Head& __head, const _Tail&... __tail) 00244 : _Inherited(__tag, __a, __tail...), 00245 _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { } 00246 00247 template<typename _Alloc, typename _UHead, typename... _UTail, 00248 typename = typename enable_if<sizeof...(_Tail) 00249 == sizeof...(_UTail)>::type> 00250 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 00251 _UHead&& __head, _UTail&&... __tail) 00252 : _Inherited(__tag, __a, std::forward<_UTail>(__tail)...), 00253 _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), 00254 std::forward<_UHead>(__head)) { } 00255 00256 template<typename _Alloc> 00257 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 00258 const _Tuple_impl& __in) 00259 : _Inherited(__tag, __a, _M_tail(__in)), 00260 _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { } 00261 00262 template<typename _Alloc> 00263 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 00264 _Tuple_impl&& __in) 00265 : _Inherited(__tag, __a, std::move(_M_tail(__in))), 00266 _Base(__use_alloc<_Head, _Alloc, _Head>(__a), 00267 std::forward<_Head>(_M_head(__in))) { } 00268 00269 template<typename _Alloc, typename... _UElements> 00270 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 00271 const _Tuple_impl<_Idx, _UElements...>& __in) 00272 : _Inherited(__tag, __a, 00273 _Tuple_impl<_Idx, _UElements...>::_M_tail(__in)), 00274 _Base(__use_alloc<_Head, _Alloc, _Head>(__a), 00275 _Tuple_impl<_Idx, _UElements...>::_M_head(__in)) { } 00276 00277 template<typename _Alloc, typename _UHead, typename... _UTails> 00278 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 00279 _Tuple_impl<_Idx, _UHead, _UTails...>&& __in) 00280 : _Inherited(__tag, __a, std::move 00281 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))), 00282 _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), 00283 std::forward<_UHead> 00284 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))) { } 00285 00286 _Tuple_impl& 00287 operator=(const _Tuple_impl& __in) 00288 { 00289 _M_head(*this) = _M_head(__in); 00290 _M_tail(*this) = _M_tail(__in); 00291 return *this; 00292 } 00293 00294 _Tuple_impl& 00295 operator=(_Tuple_impl&& __in) 00296 noexcept(__and_<is_nothrow_move_assignable<_Head>, 00297 is_nothrow_move_assignable<_Inherited>>::value) 00298 { 00299 _M_head(*this) = std::forward<_Head>(_M_head(__in)); 00300 _M_tail(*this) = std::move(_M_tail(__in)); 00301 return *this; 00302 } 00303 00304 template<typename... _UElements> 00305 _Tuple_impl& 00306 operator=(const _Tuple_impl<_Idx, _UElements...>& __in) 00307 { 00308 _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in); 00309 _M_tail(*this) = _Tuple_impl<_Idx, _UElements...>::_M_tail(__in); 00310 return *this; 00311 } 00312 00313 template<typename _UHead, typename... _UTails> 00314 _Tuple_impl& 00315 operator=(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) 00316 { 00317 _M_head(*this) = std::forward<_UHead> 00318 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)); 00319 _M_tail(*this) = std::move 00320 (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)); 00321 return *this; 00322 } 00323 00324 protected: 00325 void 00326 _M_swap(_Tuple_impl& __in) 00327 noexcept(__is_nothrow_swappable<_Head>::value 00328 && noexcept(_M_tail(__in)._M_swap(_M_tail(__in)))) 00329 { 00330 using std::swap; 00331 swap(_M_head(*this), _M_head(__in)); 00332 _Inherited::_M_swap(_M_tail(__in)); 00333 } 00334 }; 00335 00336 // Basis case of inheritance recursion. 00337 template<std::size_t _Idx, typename _Head> 00338 struct _Tuple_impl<_Idx, _Head> 00339 : private _Head_base<_Idx, _Head, __empty_not_final<_Head>::value> 00340 { 00341 template<std::size_t, typename...> friend class _Tuple_impl; 00342 00343 typedef _Head_base<_Idx, _Head, __empty_not_final<_Head>::value> _Base; 00344 00345 static constexpr _Head& 00346 _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } 00347 00348 static constexpr const _Head& 00349 _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } 00350 00351 constexpr _Tuple_impl() 00352 : _Base() { } 00353 00354 explicit 00355 constexpr _Tuple_impl(const _Head& __head) 00356 : _Base(__head) { } 00357 00358 template<typename _UHead> 00359 explicit 00360 constexpr _Tuple_impl(_UHead&& __head) 00361 : _Base(std::forward<_UHead>(__head)) { } 00362 00363 constexpr _Tuple_impl(const _Tuple_impl&) = default; 00364 00365 constexpr 00366 _Tuple_impl(_Tuple_impl&& __in) 00367 noexcept(is_nothrow_move_constructible<_Head>::value) 00368 : _Base(std::forward<_Head>(_M_head(__in))) { } 00369 00370 template<typename _UHead> 00371 constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in) 00372 : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in)) { } 00373 00374 template<typename _UHead> 00375 constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in) 00376 : _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in))) 00377 { } 00378 00379 template<typename _Alloc> 00380 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a) 00381 : _Base(__tag, __use_alloc<_Head>(__a)) { } 00382 00383 template<typename _Alloc> 00384 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 00385 const _Head& __head) 00386 : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { } 00387 00388 template<typename _Alloc, typename _UHead> 00389 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 00390 _UHead&& __head) 00391 : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), 00392 std::forward<_UHead>(__head)) { } 00393 00394 template<typename _Alloc> 00395 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 00396 const _Tuple_impl& __in) 00397 : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { } 00398 00399 template<typename _Alloc> 00400 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 00401 _Tuple_impl&& __in) 00402 : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), 00403 std::forward<_Head>(_M_head(__in))) { } 00404 00405 template<typename _Alloc, typename _UHead> 00406 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 00407 const _Tuple_impl<_Idx, _UHead>& __in) 00408 : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), 00409 _Tuple_impl<_Idx, _UHead>::_M_head(__in)) { } 00410 00411 template<typename _Alloc, typename _UHead> 00412 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 00413 _Tuple_impl<_Idx, _UHead>&& __in) 00414 : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), 00415 std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in))) 00416 { } 00417 00418 _Tuple_impl& 00419 operator=(const _Tuple_impl& __in) 00420 { 00421 _M_head(*this) = _M_head(__in); 00422 return *this; 00423 } 00424 00425 _Tuple_impl& 00426 operator=(_Tuple_impl&& __in) 00427 noexcept(is_nothrow_move_assignable<_Head>::value) 00428 { 00429 _M_head(*this) = std::forward<_Head>(_M_head(__in)); 00430 return *this; 00431 } 00432 00433 template<typename _UHead> 00434 _Tuple_impl& 00435 operator=(const _Tuple_impl<_Idx, _UHead>& __in) 00436 { 00437 _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in); 00438 return *this; 00439 } 00440 00441 template<typename _UHead> 00442 _Tuple_impl& 00443 operator=(_Tuple_impl<_Idx, _UHead>&& __in) 00444 { 00445 _M_head(*this) 00446 = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)); 00447 return *this; 00448 } 00449 00450 protected: 00451 void 00452 _M_swap(_Tuple_impl& __in) 00453 noexcept(__is_nothrow_swappable<_Head>::value) 00454 { 00455 using std::swap; 00456 swap(_M_head(*this), _M_head(__in)); 00457 } 00458 }; 00459 00460 template<typename... _Elements> 00461 class tuple; 00462 00463 // Concept utility functions, reused in conditionally-explicit 00464 // constructors. 00465 template<bool, typename... _Elements> 00466 struct _TC 00467 { 00468 template<typename... _UElements> 00469 static constexpr bool _ConstructibleTuple() 00470 { 00471 return __and_<is_constructible<_Elements, const _UElements&>...>::value; 00472 } 00473 00474 template<typename... _UElements> 00475 static constexpr bool _ImplicitlyConvertibleTuple() 00476 { 00477 return __and_<is_convertible<const _UElements&, _Elements>...>::value; 00478 } 00479 00480 template<typename... _UElements> 00481 static constexpr bool _MoveConstructibleTuple() 00482 { 00483 return __and_<is_constructible<_Elements, _UElements&&>...>::value; 00484 } 00485 00486 template<typename... _UElements> 00487 static constexpr bool _ImplicitlyMoveConvertibleTuple() 00488 { 00489 return __and_<is_convertible<_UElements&&, _Elements>...>::value; 00490 } 00491 00492 template<typename _SrcTuple> 00493 static constexpr bool _NonNestedTuple() 00494 { 00495 return __and_<__not_<is_same<tuple<_Elements...>, 00496 typename remove_cv< 00497 typename remove_reference<_SrcTuple>::type 00498 >::type>>, 00499 __not_<is_convertible<_SrcTuple, _Elements...>>, 00500 __not_<is_constructible<_Elements..., _SrcTuple>> 00501 >::value; 00502 } 00503 template<typename... _UElements> 00504 static constexpr bool _NotSameTuple() 00505 { 00506 return __not_<is_same<tuple<_Elements...>, 00507 typename remove_const< 00508 typename remove_reference<_UElements...>::type 00509 >::type>>::value; 00510 } 00511 }; 00512 00513 template<typename... _Elements> 00514 struct _TC<false, _Elements...> 00515 { 00516 template<typename... _UElements> 00517 static constexpr bool _ConstructibleTuple() 00518 { 00519 return false; 00520 } 00521 00522 template<typename... _UElements> 00523 static constexpr bool _ImplicitlyConvertibleTuple() 00524 { 00525 return false; 00526 } 00527 00528 template<typename... _UElements> 00529 static constexpr bool _MoveConstructibleTuple() 00530 { 00531 return false; 00532 } 00533 00534 template<typename... _UElements> 00535 static constexpr bool _ImplicitlyMoveConvertibleTuple() 00536 { 00537 return false; 00538 } 00539 00540 template<typename... _UElements> 00541 static constexpr bool _NonNestedTuple() 00542 { 00543 return true; 00544 } 00545 template<typename... _UElements> 00546 static constexpr bool _NotSameTuple() 00547 { 00548 return true; 00549 } 00550 }; 00551 00552 /// Primary class template, tuple 00553 template<typename... _Elements> 00554 class tuple : public _Tuple_impl<0, _Elements...> 00555 { 00556 typedef _Tuple_impl<0, _Elements...> _Inherited; 00557 00558 // Used for constraining the default constructor so 00559 // that it becomes dependent on the constraints. 00560 template<typename _Dummy> 00561 struct _TC2 00562 { 00563 static constexpr bool _DefaultConstructibleTuple() 00564 { 00565 return __and_<is_default_constructible<_Elements>...>::value; 00566 } 00567 static constexpr bool _ImplicitlyDefaultConstructibleTuple() 00568 { 00569 return __and_<__is_implicitly_default_constructible<_Elements>...> 00570 ::value; 00571 } 00572 }; 00573 00574 public: 00575 template<typename _Dummy = void, 00576 typename enable_if<_TC2<_Dummy>:: 00577 _ImplicitlyDefaultConstructibleTuple(), 00578 bool>::type = true> 00579 constexpr tuple() 00580 : _Inherited() { } 00581 00582 template<typename _Dummy = void, 00583 typename enable_if<_TC2<_Dummy>:: 00584 _DefaultConstructibleTuple() 00585 && 00586 !_TC2<_Dummy>:: 00587 _ImplicitlyDefaultConstructibleTuple(), 00588 bool>::type = false> 00589 explicit constexpr tuple() 00590 : _Inherited() { } 00591 00592 // Shortcut for the cases where constructors taking _Elements... 00593 // need to be constrained. 00594 template<typename _Dummy> using _TCC = 00595 _TC<is_same<_Dummy, void>::value, 00596 _Elements...>; 00597 00598 template<typename _Dummy = void, 00599 typename enable_if< 00600 _TCC<_Dummy>::template 00601 _ConstructibleTuple<_Elements...>() 00602 && _TCC<_Dummy>::template 00603 _ImplicitlyConvertibleTuple<_Elements...>() 00604 && (sizeof...(_Elements) >= 1), 00605 bool>::type=true> 00606 constexpr tuple(const _Elements&... __elements) 00607 : _Inherited(__elements...) { } 00608 00609 template<typename _Dummy = void, 00610 typename enable_if< 00611 _TCC<_Dummy>::template 00612 _ConstructibleTuple<_Elements...>() 00613 && !_TCC<_Dummy>::template 00614 _ImplicitlyConvertibleTuple<_Elements...>() 00615 && (sizeof...(_Elements) >= 1), 00616 bool>::type=false> 00617 explicit constexpr tuple(const _Elements&... __elements) 00618 : _Inherited(__elements...) { } 00619 00620 // Shortcut for the cases where constructors taking _UElements... 00621 // need to be constrained. 00622 template<typename... _UElements> using _TMC = 00623 _TC<(sizeof...(_Elements) == sizeof...(_UElements)), 00624 _Elements...>; 00625 00626 template<typename... _UElements, typename 00627 enable_if< 00628 _TC<sizeof...(_UElements) == 1, _Elements...>::template 00629 _NotSameTuple<_UElements...>() 00630 && _TMC<_UElements...>::template 00631 _MoveConstructibleTuple<_UElements...>() 00632 && _TMC<_UElements...>::template 00633 _ImplicitlyMoveConvertibleTuple<_UElements...>() 00634 && (sizeof...(_Elements) >= 1), 00635 bool>::type=true> 00636 constexpr tuple(_UElements&&... __elements) 00637 : _Inherited(std::forward<_UElements>(__elements)...) { } 00638 00639 template<typename... _UElements, typename 00640 enable_if< 00641 _TC<sizeof...(_UElements) == 1, _Elements...>::template 00642 _NotSameTuple<_UElements...>() 00643 && _TMC<_UElements...>::template 00644 _MoveConstructibleTuple<_UElements...>() 00645 && !_TMC<_UElements...>::template 00646 _ImplicitlyMoveConvertibleTuple<_UElements...>() 00647 && (sizeof...(_Elements) >= 1), 00648 bool>::type=false> 00649 explicit constexpr tuple(_UElements&&... __elements) 00650 : _Inherited(std::forward<_UElements>(__elements)...) { } 00651 00652 constexpr tuple(const tuple&) = default; 00653 00654 constexpr tuple(tuple&&) = default; 00655 00656 // Shortcut for the cases where constructors taking tuples 00657 // must avoid creating temporaries. 00658 template<typename _Dummy> using _TNTC = 00659 _TC<is_same<_Dummy, void>::value && sizeof...(_Elements) == 1, 00660 _Elements...>; 00661 00662 template<typename... _UElements, typename _Dummy = void, typename 00663 enable_if<_TMC<_UElements...>::template 00664 _ConstructibleTuple<_UElements...>() 00665 && _TMC<_UElements...>::template 00666 _ImplicitlyConvertibleTuple<_UElements...>() 00667 && _TNTC<_Dummy>::template 00668 _NonNestedTuple<const tuple<_UElements...>&>(), 00669 bool>::type=true> 00670 constexpr tuple(const tuple<_UElements...>& __in) 00671 : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) 00672 { } 00673 00674 template<typename... _UElements, typename _Dummy = void, typename 00675 enable_if<_TMC<_UElements...>::template 00676 _ConstructibleTuple<_UElements...>() 00677 && !_TMC<_UElements...>::template 00678 _ImplicitlyConvertibleTuple<_UElements...>() 00679 && _TNTC<_Dummy>::template 00680 _NonNestedTuple<const tuple<_UElements...>&>(), 00681 bool>::type=false> 00682 explicit constexpr tuple(const tuple<_UElements...>& __in) 00683 : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) 00684 { } 00685 00686 template<typename... _UElements, typename _Dummy = void, typename 00687 enable_if<_TMC<_UElements...>::template 00688 _MoveConstructibleTuple<_UElements...>() 00689 && _TMC<_UElements...>::template 00690 _ImplicitlyMoveConvertibleTuple<_UElements...>() 00691 && _TNTC<_Dummy>::template 00692 _NonNestedTuple<tuple<_UElements...>&&>(), 00693 bool>::type=true> 00694 constexpr tuple(tuple<_UElements...>&& __in) 00695 : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } 00696 00697 template<typename... _UElements, typename _Dummy = void, typename 00698 enable_if<_TMC<_UElements...>::template 00699 _MoveConstructibleTuple<_UElements...>() 00700 && !_TMC<_UElements...>::template 00701 _ImplicitlyMoveConvertibleTuple<_UElements...>() 00702 && _TNTC<_Dummy>::template 00703 _NonNestedTuple<tuple<_UElements...>&&>(), 00704 bool>::type=false> 00705 explicit constexpr tuple(tuple<_UElements...>&& __in) 00706 : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } 00707 00708 // Allocator-extended constructors. 00709 00710 template<typename _Alloc> 00711 tuple(allocator_arg_t __tag, const _Alloc& __a) 00712 : _Inherited(__tag, __a) { } 00713 00714 template<typename _Alloc, typename _Dummy = void, 00715 typename enable_if< 00716 _TCC<_Dummy>::template 00717 _ConstructibleTuple<_Elements...>() 00718 && _TCC<_Dummy>::template 00719 _ImplicitlyConvertibleTuple<_Elements...>(), 00720 bool>::type=true> 00721 tuple(allocator_arg_t __tag, const _Alloc& __a, 00722 const _Elements&... __elements) 00723 : _Inherited(__tag, __a, __elements...) { } 00724 00725 template<typename _Alloc, typename _Dummy = void, 00726 typename enable_if< 00727 _TCC<_Dummy>::template 00728 _ConstructibleTuple<_Elements...>() 00729 && !_TCC<_Dummy>::template 00730 _ImplicitlyConvertibleTuple<_Elements...>(), 00731 bool>::type=false> 00732 explicit tuple(allocator_arg_t __tag, const _Alloc& __a, 00733 const _Elements&... __elements) 00734 : _Inherited(__tag, __a, __elements...) { } 00735 00736 template<typename _Alloc, typename... _UElements, typename 00737 enable_if<_TMC<_UElements...>::template 00738 _MoveConstructibleTuple<_UElements...>() 00739 && _TMC<_UElements...>::template 00740 _ImplicitlyMoveConvertibleTuple<_UElements...>(), 00741 bool>::type=true> 00742 tuple(allocator_arg_t __tag, const _Alloc& __a, 00743 _UElements&&... __elements) 00744 : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...) 00745 { } 00746 00747 template<typename _Alloc, typename... _UElements, typename 00748 enable_if<_TMC<_UElements...>::template 00749 _MoveConstructibleTuple<_UElements...>() 00750 && !_TMC<_UElements...>::template 00751 _ImplicitlyMoveConvertibleTuple<_UElements...>(), 00752 bool>::type=false> 00753 explicit tuple(allocator_arg_t __tag, const _Alloc& __a, 00754 _UElements&&... __elements) 00755 : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...) 00756 { } 00757 00758 template<typename _Alloc> 00759 tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) 00760 : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { } 00761 00762 template<typename _Alloc> 00763 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) 00764 : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { } 00765 00766 template<typename _Alloc, typename... _UElements, typename 00767 enable_if<_TMC<_UElements...>::template 00768 _ConstructibleTuple<_UElements...>() 00769 && _TMC<_UElements...>::template 00770 _ImplicitlyConvertibleTuple<_UElements...>(), 00771 bool>::type=true> 00772 tuple(allocator_arg_t __tag, const _Alloc& __a, 00773 const tuple<_UElements...>& __in) 00774 : _Inherited(__tag, __a, 00775 static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) 00776 { } 00777 00778 template<typename _Alloc, typename... _UElements, typename 00779 enable_if<_TMC<_UElements...>::template 00780 _ConstructibleTuple<_UElements...>() 00781 && !_TMC<_UElements...>::template 00782 _ImplicitlyConvertibleTuple<_UElements...>(), 00783 bool>::type=false> 00784 explicit tuple(allocator_arg_t __tag, const _Alloc& __a, 00785 const tuple<_UElements...>& __in) 00786 : _Inherited(__tag, __a, 00787 static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) 00788 { } 00789 00790 template<typename _Alloc, typename... _UElements, typename 00791 enable_if<_TMC<_UElements...>::template 00792 _MoveConstructibleTuple<_UElements...>() 00793 && _TMC<_UElements...>::template 00794 _ImplicitlyMoveConvertibleTuple<_UElements...>(), 00795 bool>::type=true> 00796 tuple(allocator_arg_t __tag, const _Alloc& __a, 00797 tuple<_UElements...>&& __in) 00798 : _Inherited(__tag, __a, 00799 static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) 00800 { } 00801 00802 template<typename _Alloc, typename... _UElements, typename 00803 enable_if<_TMC<_UElements...>::template 00804 _MoveConstructibleTuple<_UElements...>() 00805 && !_TMC<_UElements...>::template 00806 _ImplicitlyMoveConvertibleTuple<_UElements...>(), 00807 bool>::type=false> 00808 explicit tuple(allocator_arg_t __tag, const _Alloc& __a, 00809 tuple<_UElements...>&& __in) 00810 : _Inherited(__tag, __a, 00811 static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) 00812 { } 00813 00814 tuple& 00815 operator=(const tuple& __in) 00816 { 00817 static_cast<_Inherited&>(*this) = __in; 00818 return *this; 00819 } 00820 00821 tuple& 00822 operator=(tuple&& __in) 00823 noexcept(is_nothrow_move_assignable<_Inherited>::value) 00824 { 00825 static_cast<_Inherited&>(*this) = std::move(__in); 00826 return *this; 00827 } 00828 00829 template<typename... _UElements, typename = typename 00830 enable_if<sizeof...(_UElements) 00831 == sizeof...(_Elements)>::type> 00832 tuple& 00833 operator=(const tuple<_UElements...>& __in) 00834 { 00835 static_cast<_Inherited&>(*this) = __in; 00836 return *this; 00837 } 00838 00839 template<typename... _UElements, typename = typename 00840 enable_if<sizeof...(_UElements) 00841 == sizeof...(_Elements)>::type> 00842 tuple& 00843 operator=(tuple<_UElements...>&& __in) 00844 { 00845 static_cast<_Inherited&>(*this) = std::move(__in); 00846 return *this; 00847 } 00848 00849 void 00850 swap(tuple& __in) 00851 noexcept(noexcept(__in._M_swap(__in))) 00852 { _Inherited::_M_swap(__in); } 00853 }; 00854 00855 // Explicit specialization, zero-element tuple. 00856 template<> 00857 class tuple<> 00858 { 00859 public: 00860 void swap(tuple&) noexcept { /* no-op */ } 00861 }; 00862 00863 /// Partial specialization, 2-element tuple. 00864 /// Includes construction and assignment from a pair. 00865 template<typename _T1, typename _T2> 00866 class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2> 00867 { 00868 typedef _Tuple_impl<0, _T1, _T2> _Inherited; 00869 00870 public: 00871 template <typename _U1 = _T1, 00872 typename _U2 = _T2, 00873 typename enable_if<__and_< 00874 __is_implicitly_default_constructible<_U1>, 00875 __is_implicitly_default_constructible<_U2>> 00876 ::value, bool>::type = true> 00877 00878 constexpr tuple() 00879 : _Inherited() { } 00880 00881 template <typename _U1 = _T1, 00882 typename _U2 = _T2, 00883 typename enable_if< 00884 __and_< 00885 is_default_constructible<_U1>, 00886 is_default_constructible<_U2>, 00887 __not_< 00888 __and_<__is_implicitly_default_constructible<_U1>, 00889 __is_implicitly_default_constructible<_U2>>>> 00890 ::value, bool>::type = false> 00891 00892 explicit constexpr tuple() 00893 : _Inherited() { } 00894 00895 // Shortcut for the cases where constructors taking _T1, _T2 00896 // need to be constrained. 00897 template<typename _Dummy> using _TCC = 00898 _TC<is_same<_Dummy, void>::value, _T1, _T2>; 00899 00900 template<typename _Dummy = void, typename 00901 enable_if<_TCC<_Dummy>::template 00902 _ConstructibleTuple<_T1, _T2>() 00903 && _TCC<_Dummy>::template 00904 _ImplicitlyConvertibleTuple<_T1, _T2>(), 00905 bool>::type = true> 00906 constexpr tuple(const _T1& __a1, const _T2& __a2) 00907 : _Inherited(__a1, __a2) { } 00908 00909 template<typename _Dummy = void, typename 00910 enable_if<_TCC<_Dummy>::template 00911 _ConstructibleTuple<_T1, _T2>() 00912 && !_TCC<_Dummy>::template 00913 _ImplicitlyConvertibleTuple<_T1, _T2>(), 00914 bool>::type = false> 00915 explicit constexpr tuple(const _T1& __a1, const _T2& __a2) 00916 : _Inherited(__a1, __a2) { } 00917 00918 // Shortcut for the cases where constructors taking _U1, _U2 00919 // need to be constrained. 00920 using _TMC = _TC<true, _T1, _T2>; 00921 00922 template<typename _U1, typename _U2, typename 00923 enable_if<_TMC::template 00924 _MoveConstructibleTuple<_U1, _U2>() 00925 && _TMC::template 00926 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), 00927 bool>::type = true> 00928 constexpr tuple(_U1&& __a1, _U2&& __a2) 00929 : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } 00930 00931 template<typename _U1, typename _U2, typename 00932 enable_if<_TMC::template 00933 _MoveConstructibleTuple<_U1, _U2>() 00934 && !_TMC::template 00935 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), 00936 bool>::type = false> 00937 explicit constexpr tuple(_U1&& __a1, _U2&& __a2) 00938 : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } 00939 00940 constexpr tuple(const tuple&) = default; 00941 00942 constexpr tuple(tuple&&) = default; 00943 00944 template<typename _U1, typename _U2, typename 00945 enable_if<_TMC::template 00946 _ConstructibleTuple<_U1, _U2>() 00947 && _TMC::template 00948 _ImplicitlyConvertibleTuple<_U1, _U2>(), 00949 bool>::type = true> 00950 constexpr tuple(const tuple<_U1, _U2>& __in) 00951 : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { } 00952 00953 template<typename _U1, typename _U2, typename 00954 enable_if<_TMC::template 00955 _ConstructibleTuple<_U1, _U2>() 00956 && !_TMC::template 00957 _ImplicitlyConvertibleTuple<_U1, _U2>(), 00958 bool>::type = false> 00959 explicit constexpr tuple(const tuple<_U1, _U2>& __in) 00960 : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { } 00961 00962 template<typename _U1, typename _U2, typename 00963 enable_if<_TMC::template 00964 _MoveConstructibleTuple<_U1, _U2>() 00965 && _TMC::template 00966 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), 00967 bool>::type = true> 00968 constexpr tuple(tuple<_U1, _U2>&& __in) 00969 : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } 00970 00971 template<typename _U1, typename _U2, typename 00972 enable_if<_TMC::template 00973 _MoveConstructibleTuple<_U1, _U2>() 00974 && !_TMC::template 00975 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), 00976 bool>::type = false> 00977 explicit constexpr tuple(tuple<_U1, _U2>&& __in) 00978 : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } 00979 00980 template<typename _U1, typename _U2, typename 00981 enable_if<_TMC::template 00982 _ConstructibleTuple<_U1, _U2>() 00983 && _TMC::template 00984 _ImplicitlyConvertibleTuple<_U1, _U2>(), 00985 bool>::type = true> 00986 constexpr tuple(const pair<_U1, _U2>& __in) 00987 : _Inherited(__in.first, __in.second) { } 00988 00989 template<typename _U1, typename _U2, typename 00990 enable_if<_TMC::template 00991 _ConstructibleTuple<_U1, _U2>() 00992 && !_TMC::template 00993 _ImplicitlyConvertibleTuple<_U1, _U2>(), 00994 bool>::type = false> 00995 explicit constexpr tuple(const pair<_U1, _U2>& __in) 00996 : _Inherited(__in.first, __in.second) { } 00997 00998 template<typename _U1, typename _U2, typename 00999 enable_if<_TMC::template 01000 _MoveConstructibleTuple<_U1, _U2>() 01001 && _TMC::template 01002 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), 01003 bool>::type = true> 01004 constexpr tuple(pair<_U1, _U2>&& __in) 01005 : _Inherited(std::forward<_U1>(__in.first), 01006 std::forward<_U2>(__in.second)) { } 01007 01008 template<typename _U1, typename _U2, typename 01009 enable_if<_TMC::template 01010 _MoveConstructibleTuple<_U1, _U2>() 01011 && !_TMC::template 01012 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), 01013 bool>::type = false> 01014 explicit constexpr tuple(pair<_U1, _U2>&& __in) 01015 : _Inherited(std::forward<_U1>(__in.first), 01016 std::forward<_U2>(__in.second)) { } 01017 01018 // Allocator-extended constructors. 01019 01020 template<typename _Alloc> 01021 tuple(allocator_arg_t __tag, const _Alloc& __a) 01022 : _Inherited(__tag, __a) { } 01023 01024 template<typename _Alloc, typename _Dummy = void, 01025 typename enable_if< 01026 _TCC<_Dummy>::template 01027 _ConstructibleTuple<_T1, _T2>() 01028 && _TCC<_Dummy>::template 01029 _ImplicitlyConvertibleTuple<_T1, _T2>(), 01030 bool>::type=true> 01031 01032 tuple(allocator_arg_t __tag, const _Alloc& __a, 01033 const _T1& __a1, const _T2& __a2) 01034 : _Inherited(__tag, __a, __a1, __a2) { } 01035 01036 template<typename _Alloc, typename _Dummy = void, 01037 typename enable_if< 01038 _TCC<_Dummy>::template 01039 _ConstructibleTuple<_T1, _T2>() 01040 && !_TCC<_Dummy>::template 01041 _ImplicitlyConvertibleTuple<_T1, _T2>(), 01042 bool>::type=false> 01043 01044 explicit tuple(allocator_arg_t __tag, const _Alloc& __a, 01045 const _T1& __a1, const _T2& __a2) 01046 : _Inherited(__tag, __a, __a1, __a2) { } 01047 01048 template<typename _Alloc, typename _U1, typename _U2, typename 01049 enable_if<_TMC::template 01050 _MoveConstructibleTuple<_U1, _U2>() 01051 && _TMC::template 01052 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), 01053 bool>::type = true> 01054 tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2) 01055 : _Inherited(__tag, __a, std::forward<_U1>(__a1), 01056 std::forward<_U2>(__a2)) { } 01057 01058 template<typename _Alloc, typename _U1, typename _U2, typename 01059 enable_if<_TMC::template 01060 _MoveConstructibleTuple<_U1, _U2>() 01061 && !_TMC::template 01062 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), 01063 bool>::type = false> 01064 explicit tuple(allocator_arg_t __tag, const _Alloc& __a, 01065 _U1&& __a1, _U2&& __a2) 01066 : _Inherited(__tag, __a, std::forward<_U1>(__a1), 01067 std::forward<_U2>(__a2)) { } 01068 01069 template<typename _Alloc> 01070 tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) 01071 : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { } 01072 01073 template<typename _Alloc> 01074 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) 01075 : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { } 01076 01077 template<typename _Alloc, typename _U1, typename _U2, typename 01078 enable_if<_TMC::template 01079 _ConstructibleTuple<_U1, _U2>() 01080 && _TMC::template 01081 _ImplicitlyConvertibleTuple<_U1, _U2>(), 01082 bool>::type = true> 01083 tuple(allocator_arg_t __tag, const _Alloc& __a, 01084 const tuple<_U1, _U2>& __in) 01085 : _Inherited(__tag, __a, 01086 static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) 01087 { } 01088 01089 template<typename _Alloc, typename _U1, typename _U2, typename 01090 enable_if<_TMC::template 01091 _ConstructibleTuple<_U1, _U2>() 01092 && !_TMC::template 01093 _ImplicitlyConvertibleTuple<_U1, _U2>(), 01094 bool>::type = false> 01095 explicit tuple(allocator_arg_t __tag, const _Alloc& __a, 01096 const tuple<_U1, _U2>& __in) 01097 : _Inherited(__tag, __a, 01098 static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) 01099 { } 01100 01101 template<typename _Alloc, typename _U1, typename _U2, typename 01102 enable_if<_TMC::template 01103 _MoveConstructibleTuple<_U1, _U2>() 01104 && _TMC::template 01105 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), 01106 bool>::type = true> 01107 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in) 01108 : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) 01109 { } 01110 01111 template<typename _Alloc, typename _U1, typename _U2, typename 01112 enable_if<_TMC::template 01113 _MoveConstructibleTuple<_U1, _U2>() 01114 && !_TMC::template 01115 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), 01116 bool>::type = false> 01117 explicit tuple(allocator_arg_t __tag, const _Alloc& __a, 01118 tuple<_U1, _U2>&& __in) 01119 : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) 01120 { } 01121 01122 template<typename _Alloc, typename _U1, typename _U2, typename 01123 enable_if<_TMC::template 01124 _ConstructibleTuple<_U1, _U2>() 01125 && _TMC::template 01126 _ImplicitlyConvertibleTuple<_U1, _U2>(), 01127 bool>::type = true> 01128 tuple(allocator_arg_t __tag, const _Alloc& __a, 01129 const pair<_U1, _U2>& __in) 01130 : _Inherited(__tag, __a, __in.first, __in.second) { } 01131 01132 template<typename _Alloc, typename _U1, typename _U2, typename 01133 enable_if<_TMC::template 01134 _ConstructibleTuple<_U1, _U2>() 01135 && !_TMC::template 01136 _ImplicitlyConvertibleTuple<_U1, _U2>(), 01137 bool>::type = false> 01138 explicit tuple(allocator_arg_t __tag, const _Alloc& __a, 01139 const pair<_U1, _U2>& __in) 01140 : _Inherited(__tag, __a, __in.first, __in.second) { } 01141 01142 template<typename _Alloc, typename _U1, typename _U2, typename 01143 enable_if<_TMC::template 01144 _MoveConstructibleTuple<_U1, _U2>() 01145 && _TMC::template 01146 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), 01147 bool>::type = true> 01148 tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in) 01149 : _Inherited(__tag, __a, std::forward<_U1>(__in.first), 01150 std::forward<_U2>(__in.second)) { } 01151 01152 template<typename _Alloc, typename _U1, typename _U2, typename 01153 enable_if<_TMC::template 01154 _MoveConstructibleTuple<_U1, _U2>() 01155 && !_TMC::template 01156 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), 01157 bool>::type = false> 01158 explicit tuple(allocator_arg_t __tag, const _Alloc& __a, 01159 pair<_U1, _U2>&& __in) 01160 : _Inherited(__tag, __a, std::forward<_U1>(__in.first), 01161 std::forward<_U2>(__in.second)) { } 01162 01163 tuple& 01164 operator=(const tuple& __in) 01165 { 01166 static_cast<_Inherited&>(*this) = __in; 01167 return *this; 01168 } 01169 01170 tuple& 01171 operator=(tuple&& __in) 01172 noexcept(is_nothrow_move_assignable<_Inherited>::value) 01173 { 01174 static_cast<_Inherited&>(*this) = std::move(__in); 01175 return *this; 01176 } 01177 01178 template<typename _U1, typename _U2> 01179 tuple& 01180 operator=(const tuple<_U1, _U2>& __in) 01181 { 01182 static_cast<_Inherited&>(*this) = __in; 01183 return *this; 01184 } 01185 01186 template<typename _U1, typename _U2> 01187 tuple& 01188 operator=(tuple<_U1, _U2>&& __in) 01189 { 01190 static_cast<_Inherited&>(*this) = std::move(__in); 01191 return *this; 01192 } 01193 01194 template<typename _U1, typename _U2> 01195 tuple& 01196 operator=(const pair<_U1, _U2>& __in) 01197 { 01198 this->_M_head(*this) = __in.first; 01199 this->_M_tail(*this)._M_head(*this) = __in.second; 01200 return *this; 01201 } 01202 01203 template<typename _U1, typename _U2> 01204 tuple& 01205 operator=(pair<_U1, _U2>&& __in) 01206 { 01207 this->_M_head(*this) = std::forward<_U1>(__in.first); 01208 this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second); 01209 return *this; 01210 } 01211 01212 void 01213 swap(tuple& __in) 01214 noexcept(noexcept(__in._M_swap(__in))) 01215 { _Inherited::_M_swap(__in); } 01216 }; 01217 01218 01219 /** 01220 * Recursive case for tuple_element: strip off the first element in 01221 * the tuple and retrieve the (i-1)th element of the remaining tuple. 01222 */ 01223 template<std::size_t __i, typename _Head, typename... _Tail> 01224 struct tuple_element<__i, tuple<_Head, _Tail...> > 01225 : tuple_element<__i - 1, tuple<_Tail...> > { }; 01226 01227 /** 01228 * Basis case for tuple_element: The first element is the one we're seeking. 01229 */ 01230 template<typename _Head, typename... _Tail> 01231 struct tuple_element<0, tuple<_Head, _Tail...> > 01232 { 01233 typedef _Head type; 01234 }; 01235 01236 /// class tuple_size 01237 template<typename... _Elements> 01238 struct tuple_size<tuple<_Elements...>> 01239 : public integral_constant<std::size_t, sizeof...(_Elements)> { }; 01240 01241 template<std::size_t __i, typename _Head, typename... _Tail> 01242 constexpr _Head& 01243 __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 01244 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 01245 01246 template<std::size_t __i, typename _Head, typename... _Tail> 01247 constexpr const _Head& 01248 __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 01249 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 01250 01251 /// Return a reference to the ith element of a tuple. 01252 template<std::size_t __i, typename... _Elements> 01253 constexpr __tuple_element_t<__i, tuple<_Elements...>>& 01254 get(tuple<_Elements...>& __t) noexcept 01255 { return std::__get_helper<__i>(__t); } 01256 01257 /// Return a const reference to the ith element of a const tuple. 01258 template<std::size_t __i, typename... _Elements> 01259 constexpr const __tuple_element_t<__i, tuple<_Elements...>>& 01260 get(const tuple<_Elements...>& __t) noexcept 01261 { return std::__get_helper<__i>(__t); } 01262 01263 /// Return an rvalue reference to the ith element of a tuple rvalue. 01264 template<std::size_t __i, typename... _Elements> 01265 constexpr __tuple_element_t<__i, tuple<_Elements...>>&& 01266 get(tuple<_Elements...>&& __t) noexcept 01267 { 01268 typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type; 01269 return std::forward<__element_type&&>(std::get<__i>(__t)); 01270 } 01271 01272 #if __cplusplus > 201103L 01273 01274 #define __cpp_lib_tuples_by_type 201304 01275 01276 template<typename _Head, size_t __i, typename... _Tail> 01277 constexpr _Head& 01278 __get_helper2(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 01279 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 01280 01281 template<typename _Head, size_t __i, typename... _Tail> 01282 constexpr const _Head& 01283 __get_helper2(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 01284 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 01285 01286 /// Return a reference to the unique element of type _Tp of a tuple. 01287 template <typename _Tp, typename... _Types> 01288 constexpr _Tp& 01289 get(tuple<_Types...>& __t) noexcept 01290 { return std::__get_helper2<_Tp>(__t); } 01291 01292 /// Return a reference to the unique element of type _Tp of a tuple rvalue. 01293 template <typename _Tp, typename... _Types> 01294 constexpr _Tp&& 01295 get(tuple<_Types...>&& __t) noexcept 01296 { return std::forward<_Tp&&>(std::__get_helper2<_Tp>(__t)); } 01297 01298 /// Return a const reference to the unique element of type _Tp of a tuple. 01299 template <typename _Tp, typename... _Types> 01300 constexpr const _Tp& 01301 get(const tuple<_Types...>& __t) noexcept 01302 { return std::__get_helper2<_Tp>(__t); } 01303 #endif 01304 01305 // This class performs the comparison operations on tuples 01306 template<typename _Tp, typename _Up, size_t __i, size_t __size> 01307 struct __tuple_compare 01308 { 01309 static constexpr bool 01310 __eq(const _Tp& __t, const _Up& __u) 01311 { 01312 return bool(std::get<__i>(__t) == std::get<__i>(__u)) 01313 && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u); 01314 } 01315 01316 static constexpr bool 01317 __less(const _Tp& __t, const _Up& __u) 01318 { 01319 return bool(std::get<__i>(__t) < std::get<__i>(__u)) 01320 || (!bool(std::get<__i>(__u) < std::get<__i>(__t)) 01321 && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u)); 01322 } 01323 }; 01324 01325 template<typename _Tp, typename _Up, size_t __size> 01326 struct __tuple_compare<_Tp, _Up, __size, __size> 01327 { 01328 static constexpr bool 01329 __eq(const _Tp&, const _Up&) { return true; } 01330 01331 static constexpr bool 01332 __less(const _Tp&, const _Up&) { return false; } 01333 }; 01334 01335 template<typename... _TElements, typename... _UElements> 01336 constexpr bool 01337 operator==(const tuple<_TElements...>& __t, 01338 const tuple<_UElements...>& __u) 01339 { 01340 static_assert(sizeof...(_TElements) == sizeof...(_UElements), 01341 "tuple objects can only be compared if they have equal sizes."); 01342 using __compare = __tuple_compare<tuple<_TElements...>, 01343 tuple<_UElements...>, 01344 0, sizeof...(_TElements)>; 01345 return __compare::__eq(__t, __u); 01346 } 01347 01348 template<typename... _TElements, typename... _UElements> 01349 constexpr bool 01350 operator<(const tuple<_TElements...>& __t, 01351 const tuple<_UElements...>& __u) 01352 { 01353 static_assert(sizeof...(_TElements) == sizeof...(_UElements), 01354 "tuple objects can only be compared if they have equal sizes."); 01355 using __compare = __tuple_compare<tuple<_TElements...>, 01356 tuple<_UElements...>, 01357 0, sizeof...(_TElements)>; 01358 return __compare::__less(__t, __u); 01359 } 01360 01361 template<typename... _TElements, typename... _UElements> 01362 constexpr bool 01363 operator!=(const tuple<_TElements...>& __t, 01364 const tuple<_UElements...>& __u) 01365 { return !(__t == __u); } 01366 01367 template<typename... _TElements, typename... _UElements> 01368 constexpr bool 01369 operator>(const tuple<_TElements...>& __t, 01370 const tuple<_UElements...>& __u) 01371 { return __u < __t; } 01372 01373 template<typename... _TElements, typename... _UElements> 01374 constexpr bool 01375 operator<=(const tuple<_TElements...>& __t, 01376 const tuple<_UElements...>& __u) 01377 { return !(__u < __t); } 01378 01379 template<typename... _TElements, typename... _UElements> 01380 constexpr bool 01381 operator>=(const tuple<_TElements...>& __t, 01382 const tuple<_UElements...>& __u) 01383 { return !(__t < __u); } 01384 01385 // NB: DR 705. 01386 template<typename... _Elements> 01387 constexpr tuple<typename __decay_and_strip<_Elements>::__type...> 01388 make_tuple(_Elements&&... __args) 01389 { 01390 typedef tuple<typename __decay_and_strip<_Elements>::__type...> 01391 __result_type; 01392 return __result_type(std::forward<_Elements>(__args)...); 01393 } 01394 01395 // _GLIBCXX_RESOLVE_LIB_DEFECTS 01396 // 2275. Why is forward_as_tuple not constexpr? 01397 template<typename... _Elements> 01398 constexpr tuple<_Elements&&...> 01399 forward_as_tuple(_Elements&&... __args) noexcept 01400 { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); } 01401 01402 template<typename... _Tps> 01403 struct __is_tuple_like_impl<tuple<_Tps...>> : true_type 01404 { }; 01405 01406 // Internal type trait that allows us to sfinae-protect tuple_cat. 01407 template<typename _Tp> 01408 struct __is_tuple_like 01409 : public __is_tuple_like_impl<typename std::remove_cv 01410 <typename std::remove_reference<_Tp>::type>::type>::type 01411 { }; 01412 01413 template<size_t, typename, typename, size_t> 01414 struct __make_tuple_impl; 01415 01416 template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm> 01417 struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm> 01418 : __make_tuple_impl<_Idx + 1, 01419 tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>, 01420 _Tuple, _Nm> 01421 { }; 01422 01423 template<std::size_t _Nm, typename _Tuple, typename... _Tp> 01424 struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm> 01425 { 01426 typedef tuple<_Tp...> __type; 01427 }; 01428 01429 template<typename _Tuple> 01430 struct __do_make_tuple 01431 : __make_tuple_impl<0, tuple<>, _Tuple, std::tuple_size<_Tuple>::value> 01432 { }; 01433 01434 // Returns the std::tuple equivalent of a tuple-like type. 01435 template<typename _Tuple> 01436 struct __make_tuple 01437 : public __do_make_tuple<typename std::remove_cv 01438 <typename std::remove_reference<_Tuple>::type>::type> 01439 { }; 01440 01441 // Combines several std::tuple's into a single one. 01442 template<typename...> 01443 struct __combine_tuples; 01444 01445 template<> 01446 struct __combine_tuples<> 01447 { 01448 typedef tuple<> __type; 01449 }; 01450 01451 template<typename... _Ts> 01452 struct __combine_tuples<tuple<_Ts...>> 01453 { 01454 typedef tuple<_Ts...> __type; 01455 }; 01456 01457 template<typename... _T1s, typename... _T2s, typename... _Rem> 01458 struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...> 01459 { 01460 typedef typename __combine_tuples<tuple<_T1s..., _T2s...>, 01461 _Rem...>::__type __type; 01462 }; 01463 01464 // Computes the result type of tuple_cat given a set of tuple-like types. 01465 template<typename... _Tpls> 01466 struct __tuple_cat_result 01467 { 01468 typedef typename __combine_tuples 01469 <typename __make_tuple<_Tpls>::__type...>::__type __type; 01470 }; 01471 01472 // Helper to determine the index set for the first tuple-like 01473 // type of a given set. 01474 template<typename...> 01475 struct __make_1st_indices; 01476 01477 template<> 01478 struct __make_1st_indices<> 01479 { 01480 typedef std::_Index_tuple<> __type; 01481 }; 01482 01483 template<typename _Tp, typename... _Tpls> 01484 struct __make_1st_indices<_Tp, _Tpls...> 01485 { 01486 typedef typename std::_Build_index_tuple<std::tuple_size< 01487 typename std::remove_reference<_Tp>::type>::value>::__type __type; 01488 }; 01489 01490 // Performs the actual concatenation by step-wise expanding tuple-like 01491 // objects into the elements, which are finally forwarded into the 01492 // result tuple. 01493 template<typename _Ret, typename _Indices, typename... _Tpls> 01494 struct __tuple_concater; 01495 01496 template<typename _Ret, std::size_t... _Is, typename _Tp, typename... _Tpls> 01497 struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...> 01498 { 01499 template<typename... _Us> 01500 static constexpr _Ret 01501 _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us) 01502 { 01503 typedef typename __make_1st_indices<_Tpls...>::__type __idx; 01504 typedef __tuple_concater<_Ret, __idx, _Tpls...> __next; 01505 return __next::_S_do(std::forward<_Tpls>(__tps)..., 01506 std::forward<_Us>(__us)..., 01507 std::get<_Is>(std::forward<_Tp>(__tp))...); 01508 } 01509 }; 01510 01511 template<typename _Ret> 01512 struct __tuple_concater<_Ret, std::_Index_tuple<>> 01513 { 01514 template<typename... _Us> 01515 static constexpr _Ret 01516 _S_do(_Us&&... __us) 01517 { 01518 return _Ret(std::forward<_Us>(__us)...); 01519 } 01520 }; 01521 01522 /// tuple_cat 01523 template<typename... _Tpls, typename = typename 01524 enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type> 01525 constexpr auto 01526 tuple_cat(_Tpls&&... __tpls) 01527 -> typename __tuple_cat_result<_Tpls...>::__type 01528 { 01529 typedef typename __tuple_cat_result<_Tpls...>::__type __ret; 01530 typedef typename __make_1st_indices<_Tpls...>::__type __idx; 01531 typedef __tuple_concater<__ret, __idx, _Tpls...> __concater; 01532 return __concater::_S_do(std::forward<_Tpls>(__tpls)...); 01533 } 01534 01535 // _GLIBCXX_RESOLVE_LIB_DEFECTS 01536 // 2301. Why is tie not constexpr? 01537 /// tie 01538 template<typename... _Elements> 01539 constexpr tuple<_Elements&...> 01540 tie(_Elements&... __args) noexcept 01541 { return tuple<_Elements&...>(__args...); } 01542 01543 /// swap 01544 template<typename... _Elements> 01545 inline void 01546 swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y) 01547 noexcept(noexcept(__x.swap(__y))) 01548 { __x.swap(__y); } 01549 01550 // A class (and instance) which can be used in 'tie' when an element 01551 // of a tuple is not required 01552 struct _Swallow_assign 01553 { 01554 template<class _Tp> 01555 const _Swallow_assign& 01556 operator=(const _Tp&) const 01557 { return *this; } 01558 }; 01559 01560 const _Swallow_assign ignore{}; 01561 01562 /// Partial specialization for tuples 01563 template<typename... _Types, typename _Alloc> 01564 struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { }; 01565 01566 // See stl_pair.h... 01567 template<class _T1, class _T2> 01568 template<typename... _Args1, typename... _Args2> 01569 inline 01570 pair<_T1, _T2>:: 01571 pair(piecewise_construct_t, 01572 tuple<_Args1...> __first, tuple<_Args2...> __second) 01573 : pair(__first, __second, 01574 typename _Build_index_tuple<sizeof...(_Args1)>::__type(), 01575 typename _Build_index_tuple<sizeof...(_Args2)>::__type()) 01576 { } 01577 01578 template<class _T1, class _T2> 01579 template<typename... _Args1, std::size_t... _Indexes1, 01580 typename... _Args2, std::size_t... _Indexes2> 01581 inline 01582 pair<_T1, _T2>:: 01583 pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2, 01584 _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>) 01585 : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...), 01586 second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...) 01587 { } 01588 01589 /// @} 01590 01591 _GLIBCXX_END_NAMESPACE_VERSION 01592 } // namespace std 01593 01594 #endif // C++11 01595 01596 #endif // _GLIBCXX_TUPLE