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