|
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>, 00611 __not_<is_same<typename decay<_U1>::type, 00612 allocator_arg_t>>> 00613 ::value>::type> 00614 explicit 00615 constexpr tuple(_U1&& __a1, _U2&& __a2) 00616 : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } 00617 00618 constexpr tuple(const tuple&) = default; 00619 00620 constexpr tuple(tuple&&) = default; 00621 00622 template<typename _U1, typename _U2, typename = typename 00623 enable_if<__and_<is_convertible<const _U1&, _T1>, 00624 is_convertible<const _U2&, _T2>>::value>::type> 00625 constexpr tuple(const tuple<_U1, _U2>& __in) 00626 : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { } 00627 00628 template<typename _U1, typename _U2, typename = typename 00629 enable_if<__and_<is_convertible<_U1, _T1>, 00630 is_convertible<_U2, _T2>>::value>::type> 00631 constexpr tuple(tuple<_U1, _U2>&& __in) 00632 : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } 00633 00634 template<typename _U1, typename _U2, typename = typename 00635 enable_if<__and_<is_convertible<const _U1&, _T1>, 00636 is_convertible<const _U2&, _T2>>::value>::type> 00637 constexpr tuple(const pair<_U1, _U2>& __in) 00638 : _Inherited(__in.first, __in.second) { } 00639 00640 template<typename _U1, typename _U2, typename = typename 00641 enable_if<__and_<is_convertible<_U1, _T1>, 00642 is_convertible<_U2, _T2>>::value>::type> 00643 constexpr tuple(pair<_U1, _U2>&& __in) 00644 : _Inherited(std::forward<_U1>(__in.first), 00645 std::forward<_U2>(__in.second)) { } 00646 00647 // Allocator-extended constructors. 00648 00649 template<typename _Alloc> 00650 tuple(allocator_arg_t __tag, const _Alloc& __a) 00651 : _Inherited(__tag, __a) { } 00652 00653 template<typename _Alloc> 00654 tuple(allocator_arg_t __tag, const _Alloc& __a, 00655 const _T1& __a1, const _T2& __a2) 00656 : _Inherited(__tag, __a, __a1, __a2) { } 00657 00658 template<typename _Alloc, typename _U1, typename _U2> 00659 tuple(allocator_arg_t __tag, const _Alloc& __a, _U1&& __a1, _U2&& __a2) 00660 : _Inherited(__tag, __a, std::forward<_U1>(__a1), 00661 std::forward<_U2>(__a2)) { } 00662 00663 template<typename _Alloc> 00664 tuple(allocator_arg_t __tag, const _Alloc& __a, const tuple& __in) 00665 : _Inherited(__tag, __a, static_cast<const _Inherited&>(__in)) { } 00666 00667 template<typename _Alloc> 00668 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple&& __in) 00669 : _Inherited(__tag, __a, static_cast<_Inherited&&>(__in)) { } 00670 00671 template<typename _Alloc, typename _U1, typename _U2> 00672 tuple(allocator_arg_t __tag, const _Alloc& __a, 00673 const tuple<_U1, _U2>& __in) 00674 : _Inherited(__tag, __a, 00675 static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) 00676 { } 00677 00678 template<typename _Alloc, typename _U1, typename _U2> 00679 tuple(allocator_arg_t __tag, const _Alloc& __a, tuple<_U1, _U2>&& __in) 00680 : _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) 00681 { } 00682 00683 template<typename _Alloc, typename _U1, typename _U2> 00684 tuple(allocator_arg_t __tag, const _Alloc& __a, 00685 const pair<_U1, _U2>& __in) 00686 : _Inherited(__tag, __a, __in.first, __in.second) { } 00687 00688 template<typename _Alloc, typename _U1, typename _U2> 00689 tuple(allocator_arg_t __tag, const _Alloc& __a, pair<_U1, _U2>&& __in) 00690 : _Inherited(__tag, __a, std::forward<_U1>(__in.first), 00691 std::forward<_U2>(__in.second)) { } 00692 00693 tuple& 00694 operator=(const tuple& __in) 00695 { 00696 static_cast<_Inherited&>(*this) = __in; 00697 return *this; 00698 } 00699 00700 tuple& 00701 operator=(tuple&& __in) 00702 noexcept(is_nothrow_move_assignable<_Inherited>::value) 00703 { 00704 static_cast<_Inherited&>(*this) = std::move(__in); 00705 return *this; 00706 } 00707 00708 template<typename _U1, typename _U2> 00709 tuple& 00710 operator=(const tuple<_U1, _U2>& __in) 00711 { 00712 static_cast<_Inherited&>(*this) = __in; 00713 return *this; 00714 } 00715 00716 template<typename _U1, typename _U2> 00717 tuple& 00718 operator=(tuple<_U1, _U2>&& __in) 00719 { 00720 static_cast<_Inherited&>(*this) = std::move(__in); 00721 return *this; 00722 } 00723 00724 template<typename _U1, typename _U2> 00725 tuple& 00726 operator=(const pair<_U1, _U2>& __in) 00727 { 00728 this->_M_head(*this) = __in.first; 00729 this->_M_tail(*this)._M_head(*this) = __in.second; 00730 return *this; 00731 } 00732 00733 template<typename _U1, typename _U2> 00734 tuple& 00735 operator=(pair<_U1, _U2>&& __in) 00736 { 00737 this->_M_head(*this) = std::forward<_U1>(__in.first); 00738 this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second); 00739 return *this; 00740 } 00741 00742 void 00743 swap(tuple& __in) 00744 noexcept(noexcept(__in._M_swap(__in))) 00745 { _Inherited::_M_swap(__in); } 00746 }; 00747 00748 00749 /// Gives the type of the ith element of a given tuple type. 00750 template<std::size_t __i, typename _Tp> 00751 struct tuple_element; 00752 00753 /** 00754 * Recursive case for tuple_element: strip off the first element in 00755 * the tuple and retrieve the (i-1)th element of the remaining tuple. 00756 */ 00757 template<std::size_t __i, typename _Head, typename... _Tail> 00758 struct tuple_element<__i, tuple<_Head, _Tail...> > 00759 : tuple_element<__i - 1, tuple<_Tail...> > { }; 00760 00761 /** 00762 * Basis case for tuple_element: The first element is the one we're seeking. 00763 */ 00764 template<typename _Head, typename... _Tail> 00765 struct tuple_element<0, tuple<_Head, _Tail...> > 00766 { 00767 typedef _Head type; 00768 }; 00769 00770 // Duplicate of C++14's tuple_element_t for internal use in C++11 mode 00771 template<std::size_t __i, typename _Tp> 00772 using __tuple_element_t = typename tuple_element<__i, _Tp>::type; 00773 00774 template<std::size_t __i, typename _Tp> 00775 struct tuple_element<__i, const _Tp> 00776 { 00777 typedef typename add_const<__tuple_element_t<__i, _Tp>>::type type; 00778 }; 00779 00780 template<std::size_t __i, typename _Tp> 00781 struct tuple_element<__i, volatile _Tp> 00782 { 00783 typedef typename add_volatile<__tuple_element_t<__i, _Tp>>::type type; 00784 }; 00785 00786 template<std::size_t __i, typename _Tp> 00787 struct tuple_element<__i, const volatile _Tp> 00788 { 00789 typedef typename add_cv<__tuple_element_t<__i, _Tp>>::type type; 00790 }; 00791 00792 #if __cplusplus > 201103L 00793 #define __cpp_lib_tuple_element_t 201402 00794 00795 template<std::size_t __i, typename _Tp> 00796 using tuple_element_t = typename tuple_element<__i, _Tp>::type; 00797 #endif 00798 00799 /// Finds the size of a given tuple type. 00800 template<typename _Tp> 00801 struct tuple_size; 00802 00803 // _GLIBCXX_RESOLVE_LIB_DEFECTS 00804 // 2313. tuple_size should always derive from integral_constant<size_t, N> 00805 template<typename _Tp> 00806 struct tuple_size<const _Tp> 00807 : integral_constant<size_t, tuple_size<_Tp>::value> { }; 00808 00809 template<typename _Tp> 00810 struct tuple_size<volatile _Tp> 00811 : integral_constant<size_t, tuple_size<_Tp>::value> { }; 00812 00813 template<typename _Tp> 00814 struct tuple_size<const volatile _Tp> 00815 : integral_constant<size_t, tuple_size<_Tp>::value> { }; 00816 00817 /// class tuple_size 00818 template<typename... _Elements> 00819 struct tuple_size<tuple<_Elements...>> 00820 : public integral_constant<std::size_t, sizeof...(_Elements)> { }; 00821 00822 template<std::size_t __i, typename _Head, typename... _Tail> 00823 constexpr _Head& 00824 __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 00825 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 00826 00827 template<std::size_t __i, typename _Head, typename... _Tail> 00828 constexpr const _Head& 00829 __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 00830 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 00831 00832 /// Return a reference to the ith element of a tuple. 00833 template<std::size_t __i, typename... _Elements> 00834 constexpr __tuple_element_t<__i, tuple<_Elements...>>& 00835 get(tuple<_Elements...>& __t) noexcept 00836 { return std::__get_helper<__i>(__t); } 00837 00838 /// Return a const reference to the ith element of a const tuple. 00839 template<std::size_t __i, typename... _Elements> 00840 constexpr const __tuple_element_t<__i, tuple<_Elements...>>& 00841 get(const tuple<_Elements...>& __t) noexcept 00842 { return std::__get_helper<__i>(__t); } 00843 00844 /// Return an rvalue reference to the ith element of a tuple rvalue. 00845 template<std::size_t __i, typename... _Elements> 00846 constexpr __tuple_element_t<__i, tuple<_Elements...>>&& 00847 get(tuple<_Elements...>&& __t) noexcept 00848 { 00849 typedef __tuple_element_t<__i, tuple<_Elements...>> __element_type; 00850 return std::forward<__element_type&&>(std::get<__i>(__t)); 00851 } 00852 00853 #if __cplusplus > 201103L 00854 00855 #define __cpp_lib_tuples_by_type 201304 00856 00857 template<typename _Head, size_t __i, typename... _Tail> 00858 constexpr _Head& 00859 __get_helper2(_Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 00860 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 00861 00862 template<typename _Head, size_t __i, typename... _Tail> 00863 constexpr const _Head& 00864 __get_helper2(const _Tuple_impl<__i, _Head, _Tail...>& __t) noexcept 00865 { return _Tuple_impl<__i, _Head, _Tail...>::_M_head(__t); } 00866 00867 /// Return a reference to the unique element of type _Tp of a tuple. 00868 template <typename _Tp, typename... _Types> 00869 constexpr _Tp& 00870 get(tuple<_Types...>& __t) noexcept 00871 { return std::__get_helper2<_Tp>(__t); } 00872 00873 /// Return a reference to the unique element of type _Tp of a tuple rvalue. 00874 template <typename _Tp, typename... _Types> 00875 constexpr _Tp&& 00876 get(tuple<_Types...>&& __t) noexcept 00877 { return std::forward<_Tp&&>(std::__get_helper2<_Tp>(__t)); } 00878 00879 /// Return a const reference to the unique element of type _Tp of a tuple. 00880 template <typename _Tp, typename... _Types> 00881 constexpr const _Tp& 00882 get(const tuple<_Types...>& __t) noexcept 00883 { return std::__get_helper2<_Tp>(__t); } 00884 #endif 00885 00886 // This class performs the comparison operations on tuples 00887 template<typename _Tp, typename _Up, size_t __i, size_t __size> 00888 struct __tuple_compare 00889 { 00890 static constexpr bool 00891 __eq(const _Tp& __t, const _Up& __u) 00892 { 00893 return bool(std::get<__i>(__t) == std::get<__i>(__u)) 00894 && __tuple_compare<_Tp, _Up, __i + 1, __size>::__eq(__t, __u); 00895 } 00896 00897 static constexpr bool 00898 __less(const _Tp& __t, const _Up& __u) 00899 { 00900 return bool(std::get<__i>(__t) < std::get<__i>(__u)) 00901 || (!bool(std::get<__i>(__u) < std::get<__i>(__t)) 00902 && __tuple_compare<_Tp, _Up, __i + 1, __size>::__less(__t, __u)); 00903 } 00904 }; 00905 00906 template<typename _Tp, typename _Up, size_t __size> 00907 struct __tuple_compare<_Tp, _Up, __size, __size> 00908 { 00909 static constexpr bool 00910 __eq(const _Tp&, const _Up&) { return true; } 00911 00912 static constexpr bool 00913 __less(const _Tp&, const _Up&) { return false; } 00914 }; 00915 00916 template<typename... _TElements, typename... _UElements> 00917 constexpr bool 00918 operator==(const tuple<_TElements...>& __t, 00919 const tuple<_UElements...>& __u) 00920 { 00921 static_assert(sizeof...(_TElements) == sizeof...(_UElements), 00922 "tuple objects can only be compared if they have equal sizes."); 00923 using __compare = __tuple_compare<tuple<_TElements...>, 00924 tuple<_UElements...>, 00925 0, sizeof...(_TElements)>; 00926 return __compare::__eq(__t, __u); 00927 } 00928 00929 template<typename... _TElements, typename... _UElements> 00930 constexpr bool 00931 operator<(const tuple<_TElements...>& __t, 00932 const tuple<_UElements...>& __u) 00933 { 00934 static_assert(sizeof...(_TElements) == sizeof...(_UElements), 00935 "tuple objects can only be compared if they have equal sizes."); 00936 using __compare = __tuple_compare<tuple<_TElements...>, 00937 tuple<_UElements...>, 00938 0, sizeof...(_TElements)>; 00939 return __compare::__less(__t, __u); 00940 } 00941 00942 template<typename... _TElements, typename... _UElements> 00943 constexpr bool 00944 operator!=(const tuple<_TElements...>& __t, 00945 const tuple<_UElements...>& __u) 00946 { return !(__t == __u); } 00947 00948 template<typename... _TElements, typename... _UElements> 00949 constexpr bool 00950 operator>(const tuple<_TElements...>& __t, 00951 const tuple<_UElements...>& __u) 00952 { return __u < __t; } 00953 00954 template<typename... _TElements, typename... _UElements> 00955 constexpr bool 00956 operator<=(const tuple<_TElements...>& __t, 00957 const tuple<_UElements...>& __u) 00958 { return !(__u < __t); } 00959 00960 template<typename... _TElements, typename... _UElements> 00961 constexpr bool 00962 operator>=(const tuple<_TElements...>& __t, 00963 const tuple<_UElements...>& __u) 00964 { return !(__t < __u); } 00965 00966 // NB: DR 705. 00967 template<typename... _Elements> 00968 constexpr tuple<typename __decay_and_strip<_Elements>::__type...> 00969 make_tuple(_Elements&&... __args) 00970 { 00971 typedef tuple<typename __decay_and_strip<_Elements>::__type...> 00972 __result_type; 00973 return __result_type(std::forward<_Elements>(__args)...); 00974 } 00975 00976 template<typename... _Elements> 00977 tuple<_Elements&&...> 00978 forward_as_tuple(_Elements&&... __args) noexcept 00979 { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); } 00980 00981 template<typename> 00982 struct __is_tuple_like_impl : false_type 00983 { }; 00984 00985 template<typename... _Tps> 00986 struct __is_tuple_like_impl<tuple<_Tps...>> : true_type 00987 { }; 00988 00989 template<typename _T1, typename _T2> 00990 struct __is_tuple_like_impl<pair<_T1, _T2>> : true_type 00991 { }; 00992 00993 template<typename _Tp, std::size_t _Nm> 00994 struct __is_tuple_like_impl<array<_Tp, _Nm>> : true_type 00995 { }; 00996 00997 // Internal type trait that allows us to sfinae-protect tuple_cat. 00998 template<typename _Tp> 00999 struct __is_tuple_like 01000 : public __is_tuple_like_impl<typename std::remove_cv 01001 <typename std::remove_reference<_Tp>::type>::type>::type 01002 { }; 01003 01004 template<size_t, typename, typename, size_t> 01005 struct __make_tuple_impl; 01006 01007 template<size_t _Idx, typename _Tuple, typename... _Tp, size_t _Nm> 01008 struct __make_tuple_impl<_Idx, tuple<_Tp...>, _Tuple, _Nm> 01009 : __make_tuple_impl<_Idx + 1, 01010 tuple<_Tp..., __tuple_element_t<_Idx, _Tuple>>, 01011 _Tuple, _Nm> 01012 { }; 01013 01014 template<std::size_t _Nm, typename _Tuple, typename... _Tp> 01015 struct __make_tuple_impl<_Nm, tuple<_Tp...>, _Tuple, _Nm> 01016 { 01017 typedef tuple<_Tp...> __type; 01018 }; 01019 01020 template<typename _Tuple> 01021 struct __do_make_tuple 01022 : __make_tuple_impl<0, tuple<>, _Tuple, std::tuple_size<_Tuple>::value> 01023 { }; 01024 01025 // Returns the std::tuple equivalent of a tuple-like type. 01026 template<typename _Tuple> 01027 struct __make_tuple 01028 : public __do_make_tuple<typename std::remove_cv 01029 <typename std::remove_reference<_Tuple>::type>::type> 01030 { }; 01031 01032 // Combines several std::tuple's into a single one. 01033 template<typename...> 01034 struct __combine_tuples; 01035 01036 template<> 01037 struct __combine_tuples<> 01038 { 01039 typedef tuple<> __type; 01040 }; 01041 01042 template<typename... _Ts> 01043 struct __combine_tuples<tuple<_Ts...>> 01044 { 01045 typedef tuple<_Ts...> __type; 01046 }; 01047 01048 template<typename... _T1s, typename... _T2s, typename... _Rem> 01049 struct __combine_tuples<tuple<_T1s...>, tuple<_T2s...>, _Rem...> 01050 { 01051 typedef typename __combine_tuples<tuple<_T1s..., _T2s...>, 01052 _Rem...>::__type __type; 01053 }; 01054 01055 // Computes the result type of tuple_cat given a set of tuple-like types. 01056 template<typename... _Tpls> 01057 struct __tuple_cat_result 01058 { 01059 typedef typename __combine_tuples 01060 <typename __make_tuple<_Tpls>::__type...>::__type __type; 01061 }; 01062 01063 // Helper to determine the index set for the first tuple-like 01064 // type of a given set. 01065 template<typename...> 01066 struct __make_1st_indices; 01067 01068 template<> 01069 struct __make_1st_indices<> 01070 { 01071 typedef std::_Index_tuple<> __type; 01072 }; 01073 01074 template<typename _Tp, typename... _Tpls> 01075 struct __make_1st_indices<_Tp, _Tpls...> 01076 { 01077 typedef typename std::_Build_index_tuple<std::tuple_size< 01078 typename std::remove_reference<_Tp>::type>::value>::__type __type; 01079 }; 01080 01081 // Performs the actual concatenation by step-wise expanding tuple-like 01082 // objects into the elements, which are finally forwarded into the 01083 // result tuple. 01084 template<typename _Ret, typename _Indices, typename... _Tpls> 01085 struct __tuple_concater; 01086 01087 template<typename _Ret, std::size_t... _Is, typename _Tp, typename... _Tpls> 01088 struct __tuple_concater<_Ret, std::_Index_tuple<_Is...>, _Tp, _Tpls...> 01089 { 01090 template<typename... _Us> 01091 static constexpr _Ret 01092 _S_do(_Tp&& __tp, _Tpls&&... __tps, _Us&&... __us) 01093 { 01094 typedef typename __make_1st_indices<_Tpls...>::__type __idx; 01095 typedef __tuple_concater<_Ret, __idx, _Tpls...> __next; 01096 return __next::_S_do(std::forward<_Tpls>(__tps)..., 01097 std::forward<_Us>(__us)..., 01098 std::get<_Is>(std::forward<_Tp>(__tp))...); 01099 } 01100 }; 01101 01102 template<typename _Ret> 01103 struct __tuple_concater<_Ret, std::_Index_tuple<>> 01104 { 01105 template<typename... _Us> 01106 static constexpr _Ret 01107 _S_do(_Us&&... __us) 01108 { 01109 return _Ret(std::forward<_Us>(__us)...); 01110 } 01111 }; 01112 01113 /// tuple_cat 01114 template<typename... _Tpls, typename = typename 01115 enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type> 01116 constexpr auto 01117 tuple_cat(_Tpls&&... __tpls) 01118 -> typename __tuple_cat_result<_Tpls...>::__type 01119 { 01120 typedef typename __tuple_cat_result<_Tpls...>::__type __ret; 01121 typedef typename __make_1st_indices<_Tpls...>::__type __idx; 01122 typedef __tuple_concater<__ret, __idx, _Tpls...> __concater; 01123 return __concater::_S_do(std::forward<_Tpls>(__tpls)...); 01124 } 01125 01126 /// tie 01127 template<typename... _Elements> 01128 inline tuple<_Elements&...> 01129 tie(_Elements&... __args) noexcept 01130 { return tuple<_Elements&...>(__args...); } 01131 01132 /// swap 01133 template<typename... _Elements> 01134 inline void 01135 swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y) 01136 noexcept(noexcept(__x.swap(__y))) 01137 { __x.swap(__y); } 01138 01139 // A class (and instance) which can be used in 'tie' when an element 01140 // of a tuple is not required 01141 struct _Swallow_assign 01142 { 01143 template<class _Tp> 01144 const _Swallow_assign& 01145 operator=(const _Tp&) const 01146 { return *this; } 01147 }; 01148 01149 const _Swallow_assign ignore{}; 01150 01151 /// Partial specialization for tuples 01152 template<typename... _Types, typename _Alloc> 01153 struct uses_allocator<tuple<_Types...>, _Alloc> : true_type { }; 01154 01155 // See stl_pair.h... 01156 template<class _T1, class _T2> 01157 template<typename... _Args1, typename... _Args2> 01158 inline 01159 pair<_T1, _T2>:: 01160 pair(piecewise_construct_t, 01161 tuple<_Args1...> __first, tuple<_Args2...> __second) 01162 : pair(__first, __second, 01163 typename _Build_index_tuple<sizeof...(_Args1)>::__type(), 01164 typename _Build_index_tuple<sizeof...(_Args2)>::__type()) 01165 { } 01166 01167 template<class _T1, class _T2> 01168 template<typename... _Args1, std::size_t... _Indexes1, 01169 typename... _Args2, std::size_t... _Indexes2> 01170 inline 01171 pair<_T1, _T2>:: 01172 pair(tuple<_Args1...>& __tuple1, tuple<_Args2...>& __tuple2, 01173 _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>) 01174 : first(std::forward<_Args1>(std::get<_Indexes1>(__tuple1))...), 01175 second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...) 01176 { } 01177 01178 /// @} 01179 01180 _GLIBCXX_END_NAMESPACE_VERSION 01181 } // namespace std 01182 01183 #endif // C++11 01184 01185 #endif // _GLIBCXX_TUPLE