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