libstdc++
|
00001 // <tuple> -*- C++ -*- 00002 00003 // Copyright (C) 2007-2015 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(noexcept(swap(std::declval<_Head&>(), 00328 std::declval<_Head&>())) 00329 && noexcept(_M_tail(__in)._M_swap(_M_tail(__in)))) 00330 { 00331 using std::swap; 00332 swap(_M_head(*this), _M_head(__in)); 00333 _Inherited::_M_swap(_M_tail(__in)); 00334 } 00335 }; 00336 00337 // Basis case of inheritance recursion. 00338 template<std::size_t _Idx, typename _Head> 00339 struct _Tuple_impl<_Idx, _Head> 00340 : private _Head_base<_Idx, _Head, __empty_not_final<_Head>::value> 00341 { 00342 template<std::size_t, typename...> friend class _Tuple_impl; 00343 00344 typedef _Head_base<_Idx, _Head, __empty_not_final<_Head>::value> _Base; 00345 00346 static constexpr _Head& 00347 _M_head(_Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } 00348 00349 static constexpr const _Head& 00350 _M_head(const _Tuple_impl& __t) noexcept { return _Base::_M_head(__t); } 00351 00352 constexpr _Tuple_impl() 00353 : _Base() { } 00354 00355 explicit 00356 constexpr _Tuple_impl(const _Head& __head) 00357 : _Base(__head) { } 00358 00359 template<typename _UHead> 00360 explicit 00361 constexpr _Tuple_impl(_UHead&& __head) 00362 : _Base(std::forward<_UHead>(__head)) { } 00363 00364 constexpr _Tuple_impl(const _Tuple_impl&) = default; 00365 00366 constexpr 00367 _Tuple_impl(_Tuple_impl&& __in) 00368 noexcept(is_nothrow_move_constructible<_Head>::value) 00369 : _Base(std::forward<_Head>(_M_head(__in))) { } 00370 00371 template<typename _UHead> 00372 constexpr _Tuple_impl(const _Tuple_impl<_Idx, _UHead>& __in) 00373 : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in)) { } 00374 00375 template<typename _UHead> 00376 constexpr _Tuple_impl(_Tuple_impl<_Idx, _UHead>&& __in) 00377 : _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in))) 00378 { } 00379 00380 template<typename _Alloc> 00381 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a) 00382 : _Base(__tag, __use_alloc<_Head>(__a)) { } 00383 00384 template<typename _Alloc> 00385 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 00386 const _Head& __head) 00387 : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), __head) { } 00388 00389 template<typename _Alloc, typename _UHead> 00390 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 00391 _UHead&& __head) 00392 : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), 00393 std::forward<_UHead>(__head)) { } 00394 00395 template<typename _Alloc> 00396 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 00397 const _Tuple_impl& __in) 00398 : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), _M_head(__in)) { } 00399 00400 template<typename _Alloc> 00401 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 00402 _Tuple_impl&& __in) 00403 : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), 00404 std::forward<_Head>(_M_head(__in))) { } 00405 00406 template<typename _Alloc, typename _UHead> 00407 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 00408 const _Tuple_impl<_Idx, _UHead>& __in) 00409 : _Base(__use_alloc<_Head, _Alloc, _Head>(__a), 00410 _Tuple_impl<_Idx, _UHead>::_M_head(__in)) { } 00411 00412 template<typename _Alloc, typename _UHead> 00413 _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a, 00414 _Tuple_impl<_Idx, _UHead>&& __in) 00415 : _Base(__use_alloc<_Head, _Alloc, _UHead>(__a), 00416 std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in))) 00417 { } 00418 00419 _Tuple_impl& 00420 operator=(const _Tuple_impl& __in) 00421 { 00422 _M_head(*this) = _M_head(__in); 00423 return *this; 00424 } 00425 00426 _Tuple_impl& 00427 operator=(_Tuple_impl&& __in) 00428 noexcept(is_nothrow_move_assignable<_Head>::value) 00429 { 00430 _M_head(*this) = std::forward<_Head>(_M_head(__in)); 00431 return *this; 00432 } 00433 00434 template<typename _UHead> 00435 _Tuple_impl& 00436 operator=(const _Tuple_impl<_Idx, _UHead>& __in) 00437 { 00438 _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in); 00439 return *this; 00440 } 00441 00442 template<typename _UHead> 00443 _Tuple_impl& 00444 operator=(_Tuple_impl<_Idx, _UHead>&& __in) 00445 { 00446 _M_head(*this) 00447 = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)); 00448 return *this; 00449 } 00450 00451 protected: 00452 void 00453 _M_swap(_Tuple_impl& __in) 00454 noexcept(noexcept(swap(std::declval<_Head&>(), std::declval<_Head&>()))) 00455 { 00456 using std::swap; 00457 swap(_M_head(*this), _M_head(__in)); 00458 } 00459 }; 00460 00461 /// Primary class template, tuple 00462 template<typename... _Elements> 00463 class tuple : public _Tuple_impl<0, _Elements...> 00464 { 00465 typedef _Tuple_impl<0, _Elements...> _Inherited; 00466 00467 public: 00468 constexpr tuple() 00469 : _Inherited() { } 00470 00471 explicit 00472 constexpr tuple(const _Elements&... __elements) 00473 : _Inherited(__elements...) { } 00474 00475 template<typename... _UElements, typename = typename 00476 enable_if<__and_<is_convertible<_UElements, 00477 _Elements>...>::value>::type> 00478 explicit 00479 constexpr tuple(_UElements&&... __elements) 00480 : _Inherited(std::forward<_UElements>(__elements)...) { } 00481 00482 constexpr tuple(const tuple&) = default; 00483 00484 constexpr tuple(tuple&&) = default; 00485 00486 template<typename... _UElements, typename = typename 00487 enable_if<__and_<is_convertible<const _UElements&, 00488 _Elements>...>::value>::type> 00489 constexpr tuple(const tuple<_UElements...>& __in) 00490 : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) 00491 { } 00492 00493 template<typename... _UElements, typename = typename 00494 enable_if<__and_<is_convertible<_UElements, 00495 _Elements>...>::value>::type> 00496 constexpr tuple(tuple<_UElements...>&& __in) 00497 : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } 00498 00499 // Allocator-extended constructors. 00500 00501 template<typename _Alloc> 00502 tuple(allocator_arg_t __tag, const _Alloc& __a) 00503 : _Inherited(__tag, __a) { } 00504 00505 template<typename _Alloc> 00506 tuple(allocator_arg_t __tag, const _Alloc& __a, 00507 const _Elements&... __elements) 00508 : _Inherited(__tag, __a, __elements...) { } 00509 00510 template<typename _Alloc, typename... _UElements, typename = typename 00511 enable_if<sizeof...(_UElements) 00512 == sizeof...(_Elements)>::type> 00513 tuple(allocator_arg_t __tag, const _Alloc& __a, 00514 _UElements&&... __elements) 00515 : _Inherited(__tag, __a, std::forward<_UElements>(__elements)...) 00516 { } 00517 00518 template<typename _Alloc> 00519 tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) 00520 : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { } 00521 00522 template<typename _Alloc> 00523 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) 00524 : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { } 00525 00526 template<typename _Alloc, typename... _UElements, typename = typename 00527 enable_if<sizeof...(_UElements) 00528 == sizeof...(_Elements)>::type> 00529 tuple(allocator_arg_t __tag, const _Alloc& __a, 00530 const tuple<_UElements...>& __in) 00531 : _Inherited(__tag, __a, 00532 static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) 00533 { } 00534 00535 template<typename _Alloc, typename... _UElements, typename = typename 00536 enable_if<sizeof...(_UElements) 00537 == sizeof...(_Elements)>::type> 00538 tuple(allocator_arg_t __tag, const _Alloc& __a, 00539 tuple<_UElements...>&& __in) 00540 : _Inherited(__tag, __a, 00541 static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) 00542 { } 00543 00544 tuple& 00545 operator=(const tuple& __in) 00546 { 00547 static_cast<_Inherited&>(*this) = __in; 00548 return *this; 00549 } 00550 00551 tuple& 00552 operator=(tuple&& __in) 00553 noexcept(is_nothrow_move_assignable<_Inherited>::value) 00554 { 00555 static_cast<_Inherited&>(*this) = std::move(__in); 00556 return *this; 00557 } 00558 00559 template<typename... _UElements, typename = typename 00560 enable_if<sizeof...(_UElements) 00561 == sizeof...(_Elements)>::type> 00562 tuple& 00563 operator=(const tuple<_UElements...>& __in) 00564 { 00565 static_cast<_Inherited&>(*this) = __in; 00566 return *this; 00567 } 00568 00569 template<typename... _UElements, typename = typename 00570 enable_if<sizeof...(_UElements) 00571 == sizeof...(_Elements)>::type> 00572 tuple& 00573 operator=(tuple<_UElements...>&& __in) 00574 { 00575 static_cast<_Inherited&>(*this) = std::move(__in); 00576 return *this; 00577 } 00578 00579 void 00580 swap(tuple& __in) 00581 noexcept(noexcept(__in._M_swap(__in))) 00582 { _Inherited::_M_swap(__in); } 00583 }; 00584 00585 // Explicit specialization, zero-element tuple. 00586 template<> 00587 class tuple<> 00588 { 00589 public: 00590 void swap(tuple&) noexcept { /* no-op */ } 00591 }; 00592 00593 /// Partial specialization, 2-element tuple. 00594 /// Includes construction and assignment from a pair. 00595 template<typename _T1, typename _T2> 00596 class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2> 00597 { 00598 typedef _Tuple_impl<0, _T1, _T2> _Inherited; 00599 00600 public: 00601 constexpr tuple() 00602 : _Inherited() { } 00603 00604 explicit 00605 constexpr tuple(const _T1& __a1, const _T2& __a2) 00606 : _Inherited(__a1, __a2) { } 00607 00608 template<typename _U1, typename _U2, typename = typename 00609 enable_if<__and_<is_convertible<_U1, _T1>, 00610 is_convertible<_U2, _T2>>::value>::type> 00611 explicit 00612 constexpr tuple(_U1&& __a1, _U2&& __a2) 00613 : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } 00614 00615 constexpr tuple(const tuple&) = default; 00616 00617 constexpr tuple(tuple&&) = default; 00618 00619 template<typename _U1, typename _U2, typename = typename 00620 enable_if<__and_<is_convertible<const _U1&, _T1>, 00621 is_convertible<const _U2&, _T2>>::value>::type> 00622 constexpr tuple(const tuple<_U1, _U2>& __in) 00623 : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { } 00624 00625 template<typename _U1, typename _U2, typename = typename 00626 enable_if<__and_<is_convertible<_U1, _T1>, 00627 is_convertible<_U2, _T2>>::value>::type> 00628 constexpr tuple(tuple<_U1, _U2>&& __in) 00629 : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } 00630 00631 template<typename _U1, typename _U2, typename = typename 00632 enable_if<__and_<is_convertible<const _U1&, _T1>, 00633 is_convertible<const _U2&, _T2>>::value>::type> 00634 constexpr tuple(const pair<_U1, _U2>& __in) 00635 : _Inherited(__in.first, __in.second) { } 00636 00637 template<typename _U1, typename _U2, typename = typename 00638 enable_if<__and_<is_convertible<_U1, _T1>, 00639 is_convertible<_U2, _T2>>::value>::type> 00640 constexpr tuple(pair<_U1, _U2>&& __in) 00641 : _Inherited(std::forward<_U1>(__in.first), 00642 std::forward<_U2>(__in.second)) { } 00643 00644 // Allocator-extended constructors. 00645 00646 template<typename _Alloc> 00647 tuple(allocator_arg_t __tag, const _Alloc& __a) 00648 : _Inherited(__tag, __a) { } 00649 00650 template<typename _Alloc> 00651 tuple(allocator_arg_t __tag, const _Alloc& __a, 00652 const _T1& __a1, const _T2& __a2) 00653 : _Inherited(__tag, __a, __a1, __a2) { } 00654 00655 template<typename _Alloc, typename _U1, typename _U2> 00656 tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2) 00657 : _Inherited(__tag, __a, std::forward<_U1>(__a1), 00658 std::forward<_U2>(__a2)) { } 00659 00660 template<typename _Alloc> 00661 tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) 00662 : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { } 00663 00664 template<typename _Alloc> 00665 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) 00666 : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { } 00667 00668 template<typename _Alloc, typename _U1, typename _U2> 00669 tuple(allocator_arg_t __tag, const _Alloc& __a, 00670 const tuple<_U1, _U2>& __in) 00671 : _Inherited(__tag, __a, 00672 static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) 00673 { } 00674 00675 template<typename _Alloc, typename _U1, typename _U2> 00676 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in) 00677 : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) 00678 { } 00679 00680 template<typename _Alloc, typename _U1, typename _U2> 00681 tuple(allocator_arg_t __tag, const _Alloc& __a, 00682 const pair<_U1, _U2>& __in) 00683 : _Inherited(__tag, __a, __in.first, __in.second) { } 00684 00685 template<typename _Alloc, typename _U1, typename _U2> 00686 tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in) 00687 : _Inherited(__tag, __a, std::forward<_U1>(__in.first), 00688 std::forward<_U2>(__in.second)) { } 00689 00690 tuple& 00691 operator=(const tuple& __in) 00692 { 00693 static_cast<_Inherited&>(*this) = __in; 00694 return *this; 00695 } 00696 00697 tuple& 00698 operator=(tuple&& __in) 00699 noexcept(is_nothrow_move_assignable<_Inherited>::value) 00700 { 00701 static_cast<_Inherited&>(*this) = std::move(__in); 00702 return *this; 00703 } 00704 00705 template<typename _U1, typename _U2> 00706 tuple& 00707 operator=(const tuple<_U1, _U2>& __in) 00708 { 00709 static_cast<_Inherited&>(*this) = __in; 00710 return *this; 00711 } 00712 00713 template<typename _U1, typename _U2> 00714 tuple& 00715 operator=(tuple<_U1, _U2>&& __in) 00716 { 00717 static_cast<_Inherited&>(*this) = std::move(__in); 00718 return *this; 00719 } 00720 00721 template<typename _U1, typename _U2> 00722 tuple& 00723 operator=(const pair<_U1, _U2>& __in) 00724 { 00725 this->_M_head(*this) = __in.first; 00726 this->_M_tail(*this)._M_head(*this) = __in.second; 00727 return *this; 00728 } 00729 00730 template<typename _U1, typename _U2> 00731 tuple& 00732 operator=(pair<_U1, _U2>&& __in) 00733 { 00734 this->_M_head(*this) = std::forward<_U1>(__in.first); 00735 this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second); 00736 return *this; 00737 } 00738 00739 void 00740 swap(tuple& __in) 00741 noexcept(noexcept(__in._M_swap(__in))) 00742 { _Inherited::_M_swap(__in); } 00743 }; 00744 00745 00746 /// Gives the type of the ith element of a given tuple type. 00747 template<std::size_t __i, typename _Tp> 00748 struct tuple_element; 00749 00750 /** 00751 * Recursive case for tuple_element: strip off the first element in 00752 * the tuple and retrieve the (i-1)th element of the remaining tuple. 00753 */ 00754 template<std::size_t __i, typename _Head, typename... _Tail> 00755 struct tuple_element<__i, tuple<_Head, _Tail...> > 00756 : tuple_element<__i - 1, tuple<_Tail...> > { }; 00757 00758 /** 00759 * Basis case for tuple_element: The first element is the one we're seeking. 00760 */ 00761 template<typename _Head, typename... _Tail> 00762 struct tuple_element<0, tuple<_Head, _Tail...> > 00763 { 00764 typedef _Head type; 00765 }; 00766 00767 // Duplicate of C++14's tuple_element_t for internal use in C++11 mode 00768 template<std::size_t __i, typename _Tp> 00769 using __tuple_element_t = typename tuple_element<__i, _Tp>::type; 00770 00771 template<std::size_t __i, typename _Tp> 00772 struct tuple_element<__i, const _Tp> 00773 { 00774 typedef typename add_const<__tuple_element_t<__i, _Tp>>::type type; 00775 }; 00776 00777 template<std::size_t __i, typename _Tp> 00778 struct tuple_element<__i, volatile _Tp> 00779 { 00780 typedef typename add_volatile<__tuple_element_t<__i, _Tp>>::type type; 00781 }; 00782 00783 template<std::size_t __i, typename _Tp> 00784 struct tuple_element<__i, const volatile _Tp> 00785 { 00786 typedef typename add_cv<__tuple_element_t<__i, _Tp>>::type type; 00787 }; 00788 00789 #if __cplusplus > 201103L 00790 #define __cpp_lib_tuple_element_t 201402 00791 00792 template<std::size_t __i, typename _Tp> 00793 using tuple_element_t = typename tuple_element<__i, _Tp>::type; 00794 #endif 00795 00796 /// Finds the size of a given tuple type. 00797 template<typename _Tp> 00798 struct tuple_size; 00799 00800 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00801 // 2313. tuple_size should always derive from integral_constant<size_t, N> 00802 template<typename _Tp> 00803 struct tuple_size<const _Tp> 00804 : integral_constant<size_t, tuple_size<_Tp>::value> { }; 00805 00806 template<typename _Tp> 00807 struct tuple_size<volatile _Tp> 00808 : integral_constant<size_t, tuple_size<_Tp>::value> { }; 00809 00810 template<typename _Tp> 00811 struct tuple_size<const volatile _Tp> 00812 : integral_constant<size_t, tuple_size<_Tp>::value> { }; 00813 00814 /// class tuple_size 00815 template<typename... _Elements> 00816 struct tuple_size<tuple<_Elements...>> 00817 : public integral_constant<std::size_t, sizeof...(_Elements)> { }; 00818 00819 template<std::size_t __i, typename _Head, typename... _Tail> 00820 constexpr _Head& 00821 __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 00822 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 00823 00824 template<std::size_t __i, typename _Head, typename... _Tail> 00825 constexpr const _Head& 00826 __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 00827 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 00828 00829 /// Return a reference to the ith element of a tuple. 00830 template<std::size_t __i, typename... _Elements> 00831 constexpr __tuple_element_t<__i, tuple<_Elements...>>& 00832 get(tuple<_Elements...>& __t) noexcept 00833 { return std::__get_helper<__i>(__t); } 00834 00835 /// Return a const reference to the ith element of a const tuple. 00836 template<std::size_t __i, typename... _Elements> 00837 constexpr const __tuple_element_t<__i, tuple<_Elements...>>& 00838 get(const tuple<_Elements...>& __t) noexcept 00839 { return std::__get_helper<__i>(__t); } 00840 00841 /// Return an rvalue reference to the ith element of a tuple rvalue. 00842 template<std::size_t __i, typename... _Elements> 00843 constexpr __tuple_element_t<__i, tuple<_Elements...>>&& 00844 get(tuple<_Elements...>&& __t) noexcept 00845 { 00846 typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type; 00847 return std::forward<__element_type&&>(std::get<__i>(__t)); 00848 } 00849 00850 #if __cplusplus > 201103L 00851 00852 #define __cpp_lib_tuples_by_type 201304 00853 00854 template<typename _Head, size_t __i, typename... _Tail> 00855 constexpr _Head& 00856 __get_helper2(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 00857 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 00858 00859 template<typename _Head, size_t __i, typename... _Tail> 00860 constexpr const _Head& 00861 __get_helper2(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 00862 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 00863 00864 /// Return a reference to the unique element of type _Tp of a tuple. 00865 template <typename _Tp, typename... _Types> 00866 constexpr _Tp& 00867 get(tuple<_Types...>& __t) noexcept 00868 { return std::__get_helper2<_Tp>(__t); } 00869 00870 /// Return a reference to the unique element of type _Tp of a tuple rvalue. 00871 template <typename _Tp, typename... _Types> 00872 constexpr _Tp&& 00873 get(tuple<_Types...>&& __t) noexcept 00874 { return std::forward<_Tp&&>(std::__get_helper2<_Tp>(__t)); } 00875 00876 /// Return a const reference to the unique element of type _Tp of a tuple. 00877 template <typename _Tp, typename... _Types> 00878 constexpr const _Tp& 00879 get(const tuple<_Types...>& __t) noexcept 00880 { return std::__get_helper2<_Tp>(__t); } 00881 #endif 00882 00883 // This class performs the comparison operations on tuples 00884 template<typename _Tp, typename _Up, size_t __i, size_t __size> 00885 struct __tuple_compare 00886 { 00887 static constexpr bool 00888 __eq(const _Tp& __t, const _Up& __u) 00889 { 00890 return bool(std::get<__i>(__t) == std::get<__i>(__u)) 00891 && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u); 00892 } 00893 00894 static constexpr bool 00895 __less(const _Tp& __t, const _Up& __u) 00896 { 00897 return bool(std::get<__i>(__t) < std::get<__i>(__u)) 00898 || (!bool(std::get<__i>(__u) < std::get<__i>(__t)) 00899 && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u)); 00900 } 00901 }; 00902 00903 template<typename _Tp, typename _Up, size_t __size> 00904 struct __tuple_compare<_Tp, _Up, __size, __size> 00905 { 00906 static constexpr bool 00907 __eq(const _Tp&, const _Up&) { return true; } 00908 00909 static constexpr bool 00910 __less(const _Tp&, const _Up&) { return false; } 00911 }; 00912 00913 template<typename... _TElements, typename... _UElements> 00914 constexpr bool 00915 operator==(const tuple<_TElements...>& __t, 00916 const tuple<_UElements...>& __u) 00917 { 00918 static_assert(sizeof...(_TElements) == sizeof...(_UElements), 00919 "tuple objects can only be compared if they have equal sizes."); 00920 using __compare = __tuple_compare<tuple<_TElements...>, 00921 tuple<_UElements...>, 00922 0, sizeof...(_TElements)>; 00923 return __compare::__eq(__t, __u); 00924 } 00925 00926 template<typename... _TElements, typename... _UElements> 00927 constexpr bool 00928 operator<(const tuple<_TElements...>& __t, 00929 const tuple<_UElements...>& __u) 00930 { 00931 static_assert(sizeof...(_TElements) == sizeof...(_UElements), 00932 "tuple objects can only be compared if they have equal sizes."); 00933 using __compare = __tuple_compare<tuple<_TElements...>, 00934 tuple<_UElements...>, 00935 0, sizeof...(_TElements)>; 00936 return __compare::__less(__t, __u); 00937 } 00938 00939 template<typename... _TElements, typename... _UElements> 00940 constexpr bool 00941 operator!=(const tuple<_TElements...>& __t, 00942 const tuple<_UElements...>& __u) 00943 { return !(__t == __u); } 00944 00945 template<typename... _TElements, typename... _UElements> 00946 constexpr bool 00947 operator>(const tuple<_TElements...>& __t, 00948 const tuple<_UElements...>& __u) 00949 { return __u < __t; } 00950 00951 template<typename... _TElements, typename... _UElements> 00952 constexpr bool 00953 operator<=(const tuple<_TElements...>& __t, 00954 const tuple<_UElements...>& __u) 00955 { return !(__u < __t); } 00956 00957 template<typename... _TElements, typename... _UElements> 00958 constexpr bool 00959 operator>=(const tuple<_TElements...>& __t, 00960 const tuple<_UElements...>& __u) 00961 { return !(__t < __u); } 00962 00963 // NB: DR 705. 00964 template<typename... _Elements> 00965 constexpr tuple<typename __decay_and_strip<_Elements>::__type...> 00966 make_tuple(_Elements&&... __args) 00967 { 00968 typedef tuple<typename __decay_and_strip<_Elements>::__type...> 00969 __result_type; 00970 return __result_type(std::forward<_Elements>(__args)...); 00971 } 00972 00973 template<typename... _Elements> 00974 tuple<_Elements&&...> 00975 forward_as_tuple(_Elements&&... __args) noexcept 00976 { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); } 00977 00978 template<typename> 00979 struct __is_tuple_like_impl : false_type 00980 { }; 00981 00982 template<typename... _Tps> 00983 struct __is_tuple_like_impl<tuple<_Tps...>> : true_type 00984 { }; 00985 00986 template<typename _T1, typename _T2> 00987 struct __is_tuple_like_impl<pair<_T1, _T2>> : true_type 00988 { }; 00989 00990 template<typename _Tp, std::size_t _Nm> 00991 struct __is_tuple_like_impl<array<_Tp, _Nm>> : true_type 00992 { }; 00993 00994 // Internal type trait that allows us to sfinae-protect tuple_cat. 00995 template<typename _Tp> 00996 struct __is_tuple_like 00997 : public __is_tuple_like_impl<typename std::remove_cv 00998 <typename std::remove_reference<_Tp>::type>::type>::type 00999 { }; 01000 01001 template<size_t, typename, typename, size_t> 01002 struct __make_tuple_impl; 01003 01004 template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm> 01005 struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm> 01006 : __make_tuple_impl<_Idx + 1, 01007 tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>, 01008 _Tuple, _Nm> 01009 { }; 01010 01011 template<std::size_t _Nm, typename _Tuple, typename... _Tp> 01012 struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm> 01013 { 01014 typedef tuple<_Tp...> __type; 01015 }; 01016 01017 template<typename _Tuple> 01018 struct __do_make_tuple 01019 : __make_tuple_impl<0, tuple<>, _Tuple, std::tuple_size<_Tuple>::value> 01020 { }; 01021 01022 // Returns the std::tuple equivalent of a tuple-like type. 01023 template<typename _Tuple> 01024 struct __make_tuple 01025 : public __do_make_tuple<typename std::remove_cv 01026 <typename std::remove_reference<_Tuple>::type>::type> 01027 { }; 01028 01029 // Combines several std::tuple's into a single one. 01030 template<typename...> 01031 struct __combine_tuples; 01032 01033 template<> 01034 struct __combine_tuples<> 01035 { 01036 typedef tuple<> __type; 01037 }; 01038 01039 template<typename... _Ts> 01040 struct __combine_tuples<tuple<_Ts...>> 01041 { 01042 typedef tuple<_Ts...> __type; 01043 }; 01044 01045 template<typename... _T1s, typename... _T2s, typename... _Rem> 01046 struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...> 01047 { 01048 typedef typename __combine_tuples<tuple<_T1s..., _T2s...>, 01049 _Rem...>::__type __type; 01050 }; 01051 01052 // Computes the result type of tuple_cat given a set of tuple-like types. 01053 template<typename... _Tpls> 01054 struct __tuple_cat_result 01055 { 01056 typedef typename __combine_tuples 01057 <typename __make_tuple<_Tpls>::__type...>::__type __type; 01058 }; 01059 01060 // Helper to determine the index set for the first tuple-like 01061 // type of a given set. 01062 template<typename...> 01063 struct __make_1st_indices; 01064 01065 template<> 01066 struct __make_1st_indices<> 01067 { 01068 typedef std::_Index_tuple<> __type; 01069 }; 01070 01071 template<typename _Tp, typename... _Tpls> 01072 struct __make_1st_indices<_Tp, _Tpls...> 01073 { 01074 typedef typename std::_Build_index_tuple<std::tuple_size< 01075 typename std::remove_reference<_Tp>::type>::value>::__type __type; 01076 }; 01077 01078 // Performs the actual concatenation by step-wise expanding tuple-like 01079 // objects into the elements, which are finally forwarded into the 01080 // result tuple. 01081 template<typename _Ret, typename _Indices, typename... _Tpls> 01082 struct __tuple_concater; 01083 01084 template<typename _Ret, std::size_t... _Is, typename _Tp, typename... _Tpls> 01085 struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...> 01086 { 01087 template<typename... _Us> 01088 static constexpr _Ret 01089 _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us) 01090 { 01091 typedef typename __make_1st_indices<_Tpls...>::__type __idx; 01092 typedef __tuple_concater<_Ret, __idx, _Tpls...> __next; 01093 return __next::_S_do(std::forward<_Tpls>(__tps)..., 01094 std::forward<_Us>(__us)..., 01095 std::get<_Is>(std::forward<_Tp>(__tp))...); 01096 } 01097 }; 01098 01099 template<typename _Ret> 01100 struct __tuple_concater<_Ret, std::_Index_tuple<>> 01101 { 01102 template<typename... _Us> 01103 static constexpr _Ret 01104 _S_do(_Us&&... __us) 01105 { 01106 return _Ret(std::forward<_Us>(__us)...); 01107 } 01108 }; 01109 01110 /// tuple_cat 01111 template<typename... _Tpls, typename = typename 01112 enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type> 01113 constexpr auto 01114 tuple_cat(_Tpls&&... __tpls) 01115 -> typename __tuple_cat_result<_Tpls...>::__type 01116 { 01117 typedef typename __tuple_cat_result<_Tpls...>::__type __ret; 01118 typedef typename __make_1st_indices<_Tpls...>::__type __idx; 01119 typedef __tuple_concater<__ret, __idx, _Tpls...> __concater; 01120 return __concater::_S_do(std::forward<_Tpls>(__tpls)...); 01121 } 01122 01123 /// tie 01124 template<typename... _Elements> 01125 inline tuple<_Elements&...> 01126 tie(_Elements&... __args) noexcept 01127 { return tuple<_Elements&...>(__args...); } 01128 01129 /// swap 01130 template<typename... _Elements> 01131 inline void 01132 swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y) 01133 noexcept(noexcept(__x.swap(__y))) 01134 { __x.swap(__y); } 01135 01136 // A class (and instance) which can be used in 'tie' when an element 01137 // of a tuple is not required 01138 struct _Swallow_assign 01139 { 01140 template<class _Tp> 01141 const _Swallow_assign& 01142 operator=(const _Tp&) const 01143 { return *this; } 01144 }; 01145 01146 const _Swallow_assign ignore{}; 01147 01148 /// Partial specialization for tuples 01149 template<typename... _Types, typename _Alloc> 01150 struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { }; 01151 01152 // See stl_pair.h... 01153 template<class _T1, class _T2> 01154 template<typename... _Args1, typename... _Args2> 01155 inline 01156 pair<_T1, _T2>:: 01157 pair(piecewise_construct_t, 01158 tuple<_Args1...> __first, tuple<_Args2...> __second) 01159 : pair(__first, __second, 01160 typename _Build_index_tuple<sizeof...(_Args1)>::__type(), 01161 typename _Build_index_tuple<sizeof...(_Args2)>::__type()) 01162 { } 01163 01164 template<class _T1, class _T2> 01165 template<typename... _Args1, std::size_t... _Indexes1, 01166 typename... _Args2, std::size_t... _Indexes2> 01167 inline 01168 pair<_T1, _T2>:: 01169 pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2, 01170 _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>) 01171 : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...), 01172 second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...) 01173 { } 01174 01175 /// @} 01176 01177 _GLIBCXX_END_NAMESPACE_VERSION 01178 } // namespace std 01179 01180 #endif // C++11 01181 01182 #endif // _GLIBCXX_TUPLE