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 && !is_same<typename decay<_U1>::type, 00928 allocator_arg_t>::value, 00929 bool>::type = true> 00930 constexpr tuple(_U1&& __a1, _U2&& __a2) 00931 : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } 00932 00933 template<typename _U1, typename _U2, typename 00934 enable_if<_TMC::template 00935 _MoveConstructibleTuple<_U1, _U2>() 00936 && !_TMC::template 00937 _ImplicitlyMoveConvertibleTuple<_U1, _U2>() 00938 && !is_same<typename decay<_U1>::type, 00939 allocator_arg_t>::value, 00940 bool>::type = false> 00941 explicit constexpr tuple(_U1&& __a1, _U2&& __a2) 00942 : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } 00943 00944 constexpr tuple(const tuple&) = default; 00945 00946 constexpr tuple(tuple&&) = default; 00947 00948 template<typename _U1, typename _U2, typename 00949 enable_if<_TMC::template 00950 _ConstructibleTuple<_U1, _U2>() 00951 && _TMC::template 00952 _ImplicitlyConvertibleTuple<_U1, _U2>(), 00953 bool>::type = true> 00954 constexpr tuple(const tuple<_U1, _U2>& __in) 00955 : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { } 00956 00957 template<typename _U1, typename _U2, typename 00958 enable_if<_TMC::template 00959 _ConstructibleTuple<_U1, _U2>() 00960 && !_TMC::template 00961 _ImplicitlyConvertibleTuple<_U1, _U2>(), 00962 bool>::type = false> 00963 explicit constexpr tuple(const tuple<_U1, _U2>& __in) 00964 : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { } 00965 00966 template<typename _U1, typename _U2, typename 00967 enable_if<_TMC::template 00968 _MoveConstructibleTuple<_U1, _U2>() 00969 && _TMC::template 00970 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), 00971 bool>::type = true> 00972 constexpr tuple(tuple<_U1, _U2>&& __in) 00973 : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } 00974 00975 template<typename _U1, typename _U2, typename 00976 enable_if<_TMC::template 00977 _MoveConstructibleTuple<_U1, _U2>() 00978 && !_TMC::template 00979 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), 00980 bool>::type = false> 00981 explicit constexpr tuple(tuple<_U1, _U2>&& __in) 00982 : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } 00983 00984 template<typename _U1, typename _U2, typename 00985 enable_if<_TMC::template 00986 _ConstructibleTuple<_U1, _U2>() 00987 && _TMC::template 00988 _ImplicitlyConvertibleTuple<_U1, _U2>(), 00989 bool>::type = true> 00990 constexpr tuple(const pair<_U1, _U2>& __in) 00991 : _Inherited(__in.first, __in.second) { } 00992 00993 template<typename _U1, typename _U2, typename 00994 enable_if<_TMC::template 00995 _ConstructibleTuple<_U1, _U2>() 00996 && !_TMC::template 00997 _ImplicitlyConvertibleTuple<_U1, _U2>(), 00998 bool>::type = false> 00999 explicit constexpr tuple(const pair<_U1, _U2>& __in) 01000 : _Inherited(__in.first, __in.second) { } 01001 01002 template<typename _U1, typename _U2, typename 01003 enable_if<_TMC::template 01004 _MoveConstructibleTuple<_U1, _U2>() 01005 && _TMC::template 01006 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), 01007 bool>::type = true> 01008 constexpr tuple(pair<_U1, _U2>&& __in) 01009 : _Inherited(std::forward<_U1>(__in.first), 01010 std::forward<_U2>(__in.second)) { } 01011 01012 template<typename _U1, typename _U2, typename 01013 enable_if<_TMC::template 01014 _MoveConstructibleTuple<_U1, _U2>() 01015 && !_TMC::template 01016 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), 01017 bool>::type = false> 01018 explicit constexpr tuple(pair<_U1, _U2>&& __in) 01019 : _Inherited(std::forward<_U1>(__in.first), 01020 std::forward<_U2>(__in.second)) { } 01021 01022 // Allocator-extended constructors. 01023 01024 template<typename _Alloc> 01025 tuple(allocator_arg_t __tag, const _Alloc& __a) 01026 : _Inherited(__tag, __a) { } 01027 01028 template<typename _Alloc, typename _Dummy = void, 01029 typename enable_if< 01030 _TCC<_Dummy>::template 01031 _ConstructibleTuple<_T1, _T2>() 01032 && _TCC<_Dummy>::template 01033 _ImplicitlyConvertibleTuple<_T1, _T2>(), 01034 bool>::type=true> 01035 01036 tuple(allocator_arg_t __tag, const _Alloc& __a, 01037 const _T1& __a1, const _T2& __a2) 01038 : _Inherited(__tag, __a, __a1, __a2) { } 01039 01040 template<typename _Alloc, typename _Dummy = void, 01041 typename enable_if< 01042 _TCC<_Dummy>::template 01043 _ConstructibleTuple<_T1, _T2>() 01044 && !_TCC<_Dummy>::template 01045 _ImplicitlyConvertibleTuple<_T1, _T2>(), 01046 bool>::type=false> 01047 01048 explicit tuple(allocator_arg_t __tag, const _Alloc& __a, 01049 const _T1& __a1, const _T2& __a2) 01050 : _Inherited(__tag, __a, __a1, __a2) { } 01051 01052 template<typename _Alloc, typename _U1, typename _U2, typename 01053 enable_if<_TMC::template 01054 _MoveConstructibleTuple<_U1, _U2>() 01055 && _TMC::template 01056 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), 01057 bool>::type = true> 01058 tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2) 01059 : _Inherited(__tag, __a, std::forward<_U1>(__a1), 01060 std::forward<_U2>(__a2)) { } 01061 01062 template<typename _Alloc, typename _U1, typename _U2, typename 01063 enable_if<_TMC::template 01064 _MoveConstructibleTuple<_U1, _U2>() 01065 && !_TMC::template 01066 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), 01067 bool>::type = false> 01068 explicit tuple(allocator_arg_t __tag, const _Alloc& __a, 01069 _U1&& __a1, _U2&& __a2) 01070 : _Inherited(__tag, __a, std::forward<_U1>(__a1), 01071 std::forward<_U2>(__a2)) { } 01072 01073 template<typename _Alloc> 01074 tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) 01075 : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { } 01076 01077 template<typename _Alloc> 01078 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) 01079 : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { } 01080 01081 template<typename _Alloc, typename _U1, typename _U2, typename 01082 enable_if<_TMC::template 01083 _ConstructibleTuple<_U1, _U2>() 01084 && _TMC::template 01085 _ImplicitlyConvertibleTuple<_U1, _U2>(), 01086 bool>::type = true> 01087 tuple(allocator_arg_t __tag, const _Alloc& __a, 01088 const tuple<_U1, _U2>& __in) 01089 : _Inherited(__tag, __a, 01090 static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) 01091 { } 01092 01093 template<typename _Alloc, typename _U1, typename _U2, typename 01094 enable_if<_TMC::template 01095 _ConstructibleTuple<_U1, _U2>() 01096 && !_TMC::template 01097 _ImplicitlyConvertibleTuple<_U1, _U2>(), 01098 bool>::type = false> 01099 explicit tuple(allocator_arg_t __tag, const _Alloc& __a, 01100 const tuple<_U1, _U2>& __in) 01101 : _Inherited(__tag, __a, 01102 static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) 01103 { } 01104 01105 template<typename _Alloc, typename _U1, typename _U2, typename 01106 enable_if<_TMC::template 01107 _MoveConstructibleTuple<_U1, _U2>() 01108 && _TMC::template 01109 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), 01110 bool>::type = true> 01111 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in) 01112 : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) 01113 { } 01114 01115 template<typename _Alloc, typename _U1, typename _U2, typename 01116 enable_if<_TMC::template 01117 _MoveConstructibleTuple<_U1, _U2>() 01118 && !_TMC::template 01119 _ImplicitlyMoveConvertibleTuple<_U1, _U2>(), 01120 bool>::type = false> 01121 explicit tuple(allocator_arg_t __tag, const _Alloc& __a, 01122 tuple<_U1, _U2>&& __in) 01123 : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) 01124 { } 01125 01126 template<typename _Alloc, typename _U1, typename _U2, typename 01127 enable_if<_TMC::template 01128 _ConstructibleTuple<_U1, _U2>() 01129 && _TMC::template 01130 _ImplicitlyConvertibleTuple<_U1, _U2>(), 01131 bool>::type = true> 01132 tuple(allocator_arg_t __tag, const _Alloc& __a, 01133 const pair<_U1, _U2>& __in) 01134 : _Inherited(__tag, __a, __in.first, __in.second) { } 01135 01136 template<typename _Alloc, typename _U1, typename _U2, typename 01137 enable_if<_TMC::template 01138 _ConstructibleTuple<_U1, _U2>() 01139 && !_TMC::template 01140 _ImplicitlyConvertibleTuple<_U1, _U2>(), 01141 bool>::type = false> 01142 explicit tuple(allocator_arg_t __tag, const _Alloc& __a, 01143 const pair<_U1, _U2>& __in) 01144 : _Inherited(__tag, __a, __in.first, __in.second) { } 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, pair<_U1, _U2>&& __in) 01153 : _Inherited(__tag, __a, std::forward<_U1>(__in.first), 01154 std::forward<_U2>(__in.second)) { } 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 pair<_U1, _U2>&& __in) 01164 : _Inherited(__tag, __a, std::forward<_U1>(__in.first), 01165 std::forward<_U2>(__in.second)) { } 01166 01167 tuple& 01168 operator=(const tuple& __in) 01169 { 01170 static_cast<_Inherited&>(*this) = __in; 01171 return *this; 01172 } 01173 01174 tuple& 01175 operator=(tuple&& __in) 01176 noexcept(is_nothrow_move_assignable<_Inherited>::value) 01177 { 01178 static_cast<_Inherited&>(*this) = std::move(__in); 01179 return *this; 01180 } 01181 01182 template<typename _U1, typename _U2> 01183 tuple& 01184 operator=(const tuple<_U1, _U2>& __in) 01185 { 01186 static_cast<_Inherited&>(*this) = __in; 01187 return *this; 01188 } 01189 01190 template<typename _U1, typename _U2> 01191 tuple& 01192 operator=(tuple<_U1, _U2>&& __in) 01193 { 01194 static_cast<_Inherited&>(*this) = std::move(__in); 01195 return *this; 01196 } 01197 01198 template<typename _U1, typename _U2> 01199 tuple& 01200 operator=(const pair<_U1, _U2>& __in) 01201 { 01202 this->_M_head(*this) = __in.first; 01203 this->_M_tail(*this)._M_head(*this) = __in.second; 01204 return *this; 01205 } 01206 01207 template<typename _U1, typename _U2> 01208 tuple& 01209 operator=(pair<_U1, _U2>&& __in) 01210 { 01211 this->_M_head(*this) = std::forward<_U1>(__in.first); 01212 this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second); 01213 return *this; 01214 } 01215 01216 void 01217 swap(tuple& __in) 01218 noexcept(noexcept(__in._M_swap(__in))) 01219 { _Inherited::_M_swap(__in); } 01220 }; 01221 01222 01223 /** 01224 * Recursive case for tuple_element: strip off the first element in 01225 * the tuple and retrieve the (i-1)th element of the remaining tuple. 01226 */ 01227 template<std::size_t __i, typename _Head, typename... _Tail> 01228 struct tuple_element<__i, tuple<_Head, _Tail...> > 01229 : tuple_element<__i - 1, tuple<_Tail...> > { }; 01230 01231 /** 01232 * Basis case for tuple_element: The first element is the one we're seeking. 01233 */ 01234 template<typename _Head, typename... _Tail> 01235 struct tuple_element<0, tuple<_Head, _Tail...> > 01236 { 01237 typedef _Head type; 01238 }; 01239 01240 /// class tuple_size 01241 template<typename... _Elements> 01242 struct tuple_size<tuple<_Elements...>> 01243 : public integral_constant<std::size_t, sizeof...(_Elements)> { }; 01244 01245 template<std::size_t __i, typename _Head, typename... _Tail> 01246 constexpr _Head& 01247 __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 01248 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 01249 01250 template<std::size_t __i, typename _Head, typename... _Tail> 01251 constexpr const _Head& 01252 __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 01253 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 01254 01255 /// Return a reference to the ith element of a tuple. 01256 template<std::size_t __i, typename... _Elements> 01257 constexpr __tuple_element_t<__i, tuple<_Elements...>>& 01258 get(tuple<_Elements...>& __t) noexcept 01259 { return std::__get_helper<__i>(__t); } 01260 01261 /// Return a const reference to the ith element of a const tuple. 01262 template<std::size_t __i, typename... _Elements> 01263 constexpr const __tuple_element_t<__i, tuple<_Elements...>>& 01264 get(const tuple<_Elements...>& __t) noexcept 01265 { return std::__get_helper<__i>(__t); } 01266 01267 /// Return an rvalue reference to the ith element of a tuple rvalue. 01268 template<std::size_t __i, typename... _Elements> 01269 constexpr __tuple_element_t<__i, tuple<_Elements...>>&& 01270 get(tuple<_Elements...>&& __t) noexcept 01271 { 01272 typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type; 01273 return std::forward<__element_type&&>(std::get<__i>(__t)); 01274 } 01275 01276 #if __cplusplus > 201103L 01277 01278 #define __cpp_lib_tuples_by_type 201304 01279 01280 template<typename _Head, size_t __i, typename... _Tail> 01281 constexpr _Head& 01282 __get_helper2(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 01283 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 01284 01285 template<typename _Head, size_t __i, typename... _Tail> 01286 constexpr const _Head& 01287 __get_helper2(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 01288 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 01289 01290 /// Return a reference to the unique element of type _Tp of a tuple. 01291 template <typename _Tp, typename... _Types> 01292 constexpr _Tp& 01293 get(tuple<_Types...>& __t) noexcept 01294 { return std::__get_helper2<_Tp>(__t); } 01295 01296 /// Return a reference to the unique element of type _Tp of a tuple rvalue. 01297 template <typename _Tp, typename... _Types> 01298 constexpr _Tp&& 01299 get(tuple<_Types...>&& __t) noexcept 01300 { return std::forward<_Tp&&>(std::__get_helper2<_Tp>(__t)); } 01301 01302 /// Return a const reference to the unique element of type _Tp of a tuple. 01303 template <typename _Tp, typename... _Types> 01304 constexpr const _Tp& 01305 get(const tuple<_Types...>& __t) noexcept 01306 { return std::__get_helper2<_Tp>(__t); } 01307 #endif 01308 01309 // This class performs the comparison operations on tuples 01310 template<typename _Tp, typename _Up, size_t __i, size_t __size> 01311 struct __tuple_compare 01312 { 01313 static constexpr bool 01314 __eq(const _Tp& __t, const _Up& __u) 01315 { 01316 return bool(std::get<__i>(__t) == std::get<__i>(__u)) 01317 && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u); 01318 } 01319 01320 static constexpr bool 01321 __less(const _Tp& __t, const _Up& __u) 01322 { 01323 return bool(std::get<__i>(__t) < std::get<__i>(__u)) 01324 || (!bool(std::get<__i>(__u) < std::get<__i>(__t)) 01325 && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u)); 01326 } 01327 }; 01328 01329 template<typename _Tp, typename _Up, size_t __size> 01330 struct __tuple_compare<_Tp, _Up, __size, __size> 01331 { 01332 static constexpr bool 01333 __eq(const _Tp&, const _Up&) { return true; } 01334 01335 static constexpr bool 01336 __less(const _Tp&, const _Up&) { return false; } 01337 }; 01338 01339 template<typename... _TElements, typename... _UElements> 01340 constexpr bool 01341 operator==(const tuple<_TElements...>& __t, 01342 const tuple<_UElements...>& __u) 01343 { 01344 static_assert(sizeof...(_TElements) == sizeof...(_UElements), 01345 "tuple objects can only be compared if they have equal sizes."); 01346 using __compare = __tuple_compare<tuple<_TElements...>, 01347 tuple<_UElements...>, 01348 0, sizeof...(_TElements)>; 01349 return __compare::__eq(__t, __u); 01350 } 01351 01352 template<typename... _TElements, typename... _UElements> 01353 constexpr bool 01354 operator<(const tuple<_TElements...>& __t, 01355 const tuple<_UElements...>& __u) 01356 { 01357 static_assert(sizeof...(_TElements) == sizeof...(_UElements), 01358 "tuple objects can only be compared if they have equal sizes."); 01359 using __compare = __tuple_compare<tuple<_TElements...>, 01360 tuple<_UElements...>, 01361 0, sizeof...(_TElements)>; 01362 return __compare::__less(__t, __u); 01363 } 01364 01365 template<typename... _TElements, typename... _UElements> 01366 constexpr bool 01367 operator!=(const tuple<_TElements...>& __t, 01368 const tuple<_UElements...>& __u) 01369 { return !(__t == __u); } 01370 01371 template<typename... _TElements, typename... _UElements> 01372 constexpr bool 01373 operator>(const tuple<_TElements...>& __t, 01374 const tuple<_UElements...>& __u) 01375 { return __u < __t; } 01376 01377 template<typename... _TElements, typename... _UElements> 01378 constexpr bool 01379 operator<=(const tuple<_TElements...>& __t, 01380 const tuple<_UElements...>& __u) 01381 { return !(__u < __t); } 01382 01383 template<typename... _TElements, typename... _UElements> 01384 constexpr bool 01385 operator>=(const tuple<_TElements...>& __t, 01386 const tuple<_UElements...>& __u) 01387 { return !(__t < __u); } 01388 01389 // NB: DR 705. 01390 template<typename... _Elements> 01391 constexpr tuple<typename __decay_and_strip<_Elements>::__type...> 01392 make_tuple(_Elements&&... __args) 01393 { 01394 typedef tuple<typename __decay_and_strip<_Elements>::__type...> 01395 __result_type; 01396 return __result_type(std::forward<_Elements>(__args)...); 01397 } 01398 01399 // _GLIBCXX_RESOLVE_LIB_DEFECTS 01400 // 2275. Why is forward_as_tuple not constexpr? 01401 template<typename... _Elements> 01402 constexpr tuple<_Elements&&...> 01403 forward_as_tuple(_Elements&&... __args) noexcept 01404 { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); } 01405 01406 template<typename... _Tps> 01407 struct __is_tuple_like_impl<tuple<_Tps...>> : true_type 01408 { }; 01409 01410 // Internal type trait that allows us to sfinae-protect tuple_cat. 01411 template<typename _Tp> 01412 struct __is_tuple_like 01413 : public __is_tuple_like_impl<typename std::remove_cv 01414 <typename std::remove_reference<_Tp>::type>::type>::type 01415 { }; 01416 01417 template<size_t, typename, typename, size_t> 01418 struct __make_tuple_impl; 01419 01420 template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm> 01421 struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm> 01422 : __make_tuple_impl<_Idx + 1, 01423 tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>, 01424 _Tuple, _Nm> 01425 { }; 01426 01427 template<std::size_t _Nm, typename _Tuple, typename... _Tp> 01428 struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm> 01429 { 01430 typedef tuple<_Tp...> __type; 01431 }; 01432 01433 template<typename _Tuple> 01434 struct __do_make_tuple 01435 : __make_tuple_impl<0, tuple<>, _Tuple, std::tuple_size<_Tuple>::value> 01436 { }; 01437 01438 // Returns the std::tuple equivalent of a tuple-like type. 01439 template<typename _Tuple> 01440 struct __make_tuple 01441 : public __do_make_tuple<typename std::remove_cv 01442 <typename std::remove_reference<_Tuple>::type>::type> 01443 { }; 01444 01445 // Combines several std::tuple's into a single one. 01446 template<typename...> 01447 struct __combine_tuples; 01448 01449 template<> 01450 struct __combine_tuples<> 01451 { 01452 typedef tuple<> __type; 01453 }; 01454 01455 template<typename... _Ts> 01456 struct __combine_tuples<tuple<_Ts...>> 01457 { 01458 typedef tuple<_Ts...> __type; 01459 }; 01460 01461 template<typename... _T1s, typename... _T2s, typename... _Rem> 01462 struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...> 01463 { 01464 typedef typename __combine_tuples<tuple<_T1s..., _T2s...>, 01465 _Rem...>::__type __type; 01466 }; 01467 01468 // Computes the result type of tuple_cat given a set of tuple-like types. 01469 template<typename... _Tpls> 01470 struct __tuple_cat_result 01471 { 01472 typedef typename __combine_tuples 01473 <typename __make_tuple<_Tpls>::__type...>::__type __type; 01474 }; 01475 01476 // Helper to determine the index set for the first tuple-like 01477 // type of a given set. 01478 template<typename...> 01479 struct __make_1st_indices; 01480 01481 template<> 01482 struct __make_1st_indices<> 01483 { 01484 typedef std::_Index_tuple<> __type; 01485 }; 01486 01487 template<typename _Tp, typename... _Tpls> 01488 struct __make_1st_indices<_Tp, _Tpls...> 01489 { 01490 typedef typename std::_Build_index_tuple<std::tuple_size< 01491 typename std::remove_reference<_Tp>::type>::value>::__type __type; 01492 }; 01493 01494 // Performs the actual concatenation by step-wise expanding tuple-like 01495 // objects into the elements, which are finally forwarded into the 01496 // result tuple. 01497 template<typename _Ret, typename _Indices, typename... _Tpls> 01498 struct __tuple_concater; 01499 01500 template<typename _Ret, std::size_t... _Is, typename _Tp, typename... _Tpls> 01501 struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...> 01502 { 01503 template<typename... _Us> 01504 static constexpr _Ret 01505 _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us) 01506 { 01507 typedef typename __make_1st_indices<_Tpls...>::__type __idx; 01508 typedef __tuple_concater<_Ret, __idx, _Tpls...> __next; 01509 return __next::_S_do(std::forward<_Tpls>(__tps)..., 01510 std::forward<_Us>(__us)..., 01511 std::get<_Is>(std::forward<_Tp>(__tp))...); 01512 } 01513 }; 01514 01515 template<typename _Ret> 01516 struct __tuple_concater<_Ret, std::_Index_tuple<>> 01517 { 01518 template<typename... _Us> 01519 static constexpr _Ret 01520 _S_do(_Us&&... __us) 01521 { 01522 return _Ret(std::forward<_Us>(__us)...); 01523 } 01524 }; 01525 01526 /// tuple_cat 01527 template<typename... _Tpls, typename = typename 01528 enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type> 01529 constexpr auto 01530 tuple_cat(_Tpls&&... __tpls) 01531 -> typename __tuple_cat_result<_Tpls...>::__type 01532 { 01533 typedef typename __tuple_cat_result<_Tpls...>::__type __ret; 01534 typedef typename __make_1st_indices<_Tpls...>::__type __idx; 01535 typedef __tuple_concater<__ret, __idx, _Tpls...> __concater; 01536 return __concater::_S_do(std::forward<_Tpls>(__tpls)...); 01537 } 01538 01539 // _GLIBCXX_RESOLVE_LIB_DEFECTS 01540 // 2301. Why is tie not constexpr? 01541 /// tie 01542 template<typename... _Elements> 01543 constexpr tuple<_Elements&...> 01544 tie(_Elements&... __args) noexcept 01545 { return tuple<_Elements&...>(__args...); } 01546 01547 /// swap 01548 template<typename... _Elements> 01549 inline void 01550 swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y) 01551 noexcept(noexcept(__x.swap(__y))) 01552 { __x.swap(__y); } 01553 01554 // A class (and instance) which can be used in 'tie' when an element 01555 // of a tuple is not required 01556 struct _Swallow_assign 01557 { 01558 template<class _Tp> 01559 const _Swallow_assign& 01560 operator=(const _Tp&) const 01561 { return *this; } 01562 }; 01563 01564 const _Swallow_assign ignore{}; 01565 01566 /// Partial specialization for tuples 01567 template<typename... _Types, typename _Alloc> 01568 struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { }; 01569 01570 // See stl_pair.h... 01571 template<class _T1, class _T2> 01572 template<typename... _Args1, typename... _Args2> 01573 inline 01574 pair<_T1, _T2>:: 01575 pair(piecewise_construct_t, 01576 tuple<_Args1...> __first, tuple<_Args2...> __second) 01577 : pair(__first, __second, 01578 typename _Build_index_tuple<sizeof...(_Args1)>::__type(), 01579 typename _Build_index_tuple<sizeof...(_Args2)>::__type()) 01580 { } 01581 01582 template<class _T1, class _T2> 01583 template<typename... _Args1, std::size_t... _Indexes1, 01584 typename... _Args2, std::size_t... _Indexes2> 01585 inline 01586 pair<_T1, _T2>:: 01587 pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2, 01588 _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>) 01589 : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...), 01590 second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...) 01591 { } 01592 01593 /// @} 01594 01595 _GLIBCXX_END_NAMESPACE_VERSION 01596 } // namespace std 01597 01598 #endif // C++11 01599 01600 #endif // _GLIBCXX_TUPLE