libstdc++
|
00001 // <tuple> -*- C++ -*- 00002 00003 // Copyright (C) 2007, 2008, 2009, 2010, 2011 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 #ifndef __GXX_EXPERIMENTAL_CXX0X__ 00035 # include <bits/c++0x_warning.h> 00036 #else 00037 00038 #include <utility> 00039 00040 namespace std _GLIBCXX_VISIBILITY(default) 00041 { 00042 _GLIBCXX_BEGIN_NAMESPACE_VERSION 00043 00044 // Adds a const reference to a non-reference type. 00045 template<typename _Tp> 00046 struct __add_c_ref 00047 { typedef const _Tp& type; }; 00048 00049 template<typename _Tp> 00050 struct __add_c_ref<_Tp&> 00051 { typedef _Tp& type; }; 00052 00053 // Adds a reference to a non-reference type. 00054 template<typename _Tp> 00055 struct __add_ref 00056 { typedef _Tp& type; }; 00057 00058 template<typename _Tp> 00059 struct __add_ref<_Tp&> 00060 { typedef _Tp& type; }; 00061 00062 template<std::size_t _Idx, typename _Head, bool _IsEmpty> 00063 struct _Head_base; 00064 00065 template<std::size_t _Idx, typename _Head> 00066 struct _Head_base<_Idx, _Head, true> 00067 : public _Head 00068 { 00069 constexpr _Head_base() 00070 : _Head() { } 00071 00072 constexpr _Head_base(const _Head& __h) 00073 : _Head(__h) { } 00074 00075 template<typename _UHead> 00076 _Head_base(_UHead&& __h) 00077 : _Head(std::forward<_UHead>(__h)) { } 00078 00079 _Head& _M_head() { return *this; } 00080 const _Head& _M_head() const { return *this; } 00081 00082 void 00083 _M_swap_impl(_Head& __h) 00084 { 00085 using std::swap; 00086 swap(__h, _M_head()); 00087 } 00088 }; 00089 00090 template<std::size_t _Idx, typename _Head> 00091 struct _Head_base<_Idx, _Head, false> 00092 { 00093 constexpr _Head_base() 00094 : _M_head_impl() { } 00095 00096 constexpr _Head_base(const _Head& __h) 00097 : _M_head_impl(__h) { } 00098 00099 template<typename _UHead> 00100 _Head_base(_UHead&& __h) 00101 : _M_head_impl(std::forward<_UHead>(__h)) { } 00102 00103 _Head& _M_head() { return _M_head_impl; } 00104 const _Head& _M_head() const { return _M_head_impl; } 00105 00106 void 00107 _M_swap_impl(_Head& __h) 00108 { 00109 using std::swap; 00110 swap(__h, _M_head()); 00111 } 00112 00113 _Head _M_head_impl; 00114 }; 00115 00116 /** 00117 * Contains the actual implementation of the @c tuple template, stored 00118 * as a recursive inheritance hierarchy from the first element (most 00119 * derived class) to the last (least derived class). The @c Idx 00120 * parameter gives the 0-based index of the element stored at this 00121 * point in the hierarchy; we use it to implement a constant-time 00122 * get() operation. 00123 */ 00124 template<std::size_t _Idx, typename... _Elements> 00125 struct _Tuple_impl; 00126 00127 /** 00128 * Zero-element tuple implementation. This is the basis case for the 00129 * inheritance recursion. 00130 */ 00131 template<std::size_t _Idx> 00132 struct _Tuple_impl<_Idx> 00133 { 00134 protected: 00135 void _M_swap_impl(_Tuple_impl&) { /* no-op */ } 00136 }; 00137 00138 /** 00139 * Recursive tuple implementation. Here we store the @c Head element 00140 * and derive from a @c Tuple_impl containing the remaining elements 00141 * (which contains the @c Tail). 00142 */ 00143 template<std::size_t _Idx, typename _Head, typename... _Tail> 00144 struct _Tuple_impl<_Idx, _Head, _Tail...> 00145 : public _Tuple_impl<_Idx + 1, _Tail...>, 00146 private _Head_base<_Idx, _Head, std::is_empty<_Head>::value> 00147 { 00148 typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited; 00149 typedef _Head_base<_Idx, _Head, std::is_empty<_Head>::value> _Base; 00150 00151 _Head& _M_head() { return _Base::_M_head(); } 00152 const _Head& _M_head() const { return _Base::_M_head(); } 00153 00154 _Inherited& _M_tail() { return *this; } 00155 const _Inherited& _M_tail() const { return *this; } 00156 00157 constexpr _Tuple_impl() 00158 : _Inherited(), _Base() { } 00159 00160 explicit 00161 constexpr _Tuple_impl(const _Head& __head, const _Tail&... __tail) 00162 : _Inherited(__tail...), _Base(__head) { } 00163 00164 template<typename _UHead, typename... _UTail> 00165 explicit 00166 _Tuple_impl(_UHead&& __head, _UTail&&... __tail) 00167 : _Inherited(std::forward<_UTail>(__tail)...), 00168 _Base(std::forward<_UHead>(__head)) { } 00169 00170 constexpr _Tuple_impl(const _Tuple_impl&) = default; 00171 00172 _Tuple_impl(_Tuple_impl&& __in) 00173 : _Inherited(std::move(__in._M_tail())), 00174 _Base(std::forward<_Head>(__in._M_head())) { } 00175 00176 template<typename... _UElements> 00177 _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in) 00178 : _Inherited(__in._M_tail()), _Base(__in._M_head()) { } 00179 00180 template<typename _UHead, typename... _UTails> 00181 _Tuple_impl(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) 00182 : _Inherited(std::move(__in._M_tail())), 00183 _Base(std::forward<_UHead>(__in._M_head())) { } 00184 00185 _Tuple_impl& 00186 operator=(const _Tuple_impl& __in) 00187 { 00188 _M_head() = __in._M_head(); 00189 _M_tail() = __in._M_tail(); 00190 return *this; 00191 } 00192 00193 _Tuple_impl& 00194 operator=(_Tuple_impl&& __in) 00195 { 00196 _M_head() = std::forward<_Head>(__in._M_head()); 00197 _M_tail() = std::move(__in._M_tail()); 00198 return *this; 00199 } 00200 00201 template<typename... _UElements> 00202 _Tuple_impl& 00203 operator=(const _Tuple_impl<_Idx, _UElements...>& __in) 00204 { 00205 _M_head() = __in._M_head(); 00206 _M_tail() = __in._M_tail(); 00207 return *this; 00208 } 00209 00210 template<typename _UHead, typename... _UTails> 00211 _Tuple_impl& 00212 operator=(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) 00213 { 00214 _M_head() = std::forward<_UHead>(__in._M_head()); 00215 _M_tail() = std::move(__in._M_tail()); 00216 return *this; 00217 } 00218 00219 protected: 00220 void 00221 _M_swap_impl(_Tuple_impl& __in) 00222 { 00223 _Base::_M_swap_impl(__in._M_head()); 00224 _Inherited::_M_swap_impl(__in._M_tail()); 00225 } 00226 }; 00227 00228 /// tuple 00229 template<typename... _Elements> 00230 class tuple : public _Tuple_impl<0, _Elements...> 00231 { 00232 typedef _Tuple_impl<0, _Elements...> _Inherited; 00233 00234 public: 00235 constexpr tuple() 00236 : _Inherited() { } 00237 00238 explicit 00239 constexpr tuple(const _Elements&... __elements) 00240 : _Inherited(__elements...) { } 00241 00242 template<typename... _UElements, typename = typename 00243 std::enable_if<sizeof...(_UElements) 00244 == sizeof...(_Elements)>::type> 00245 explicit 00246 tuple(_UElements&&... __elements) 00247 : _Inherited(std::forward<_UElements>(__elements)...) { } 00248 00249 constexpr tuple(const tuple&) = default; 00250 00251 tuple(tuple&& __in) 00252 : _Inherited(static_cast<_Inherited&&>(__in)) { } 00253 00254 template<typename... _UElements, typename = typename 00255 std::enable_if<sizeof...(_UElements) 00256 == sizeof...(_Elements)>::type> 00257 tuple(const tuple<_UElements...>& __in) 00258 : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in)) 00259 { } 00260 00261 template<typename... _UElements, typename = typename 00262 std::enable_if<sizeof...(_UElements) 00263 == sizeof...(_Elements)>::type> 00264 tuple(tuple<_UElements...>&& __in) 00265 : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { } 00266 00267 tuple& 00268 operator=(const tuple& __in) 00269 { 00270 static_cast<_Inherited&>(*this) = __in; 00271 return *this; 00272 } 00273 00274 tuple& 00275 operator=(tuple&& __in) 00276 { 00277 static_cast<_Inherited&>(*this) = std::move(__in); 00278 return *this; 00279 } 00280 00281 template<typename... _UElements, typename = typename 00282 std::enable_if<sizeof...(_UElements) 00283 == sizeof...(_Elements)>::type> 00284 tuple& 00285 operator=(const tuple<_UElements...>& __in) 00286 { 00287 static_cast<_Inherited&>(*this) = __in; 00288 return *this; 00289 } 00290 00291 template<typename... _UElements, typename = typename 00292 std::enable_if<sizeof...(_UElements) 00293 == sizeof...(_Elements)>::type> 00294 tuple& 00295 operator=(tuple<_UElements...>&& __in) 00296 { 00297 static_cast<_Inherited&>(*this) = std::move(__in); 00298 return *this; 00299 } 00300 00301 void 00302 swap(tuple& __in) 00303 { _Inherited::_M_swap_impl(__in); } 00304 }; 00305 00306 template<> 00307 class tuple<> 00308 { 00309 public: 00310 void swap(tuple&) { /* no-op */ } 00311 }; 00312 00313 /// tuple (2-element), with construction and assignment from a pair. 00314 template<typename _T1, typename _T2> 00315 class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2> 00316 { 00317 typedef _Tuple_impl<0, _T1, _T2> _Inherited; 00318 00319 public: 00320 constexpr tuple() 00321 : _Inherited() { } 00322 00323 explicit 00324 constexpr tuple(const _T1& __a1, const _T2& __a2) 00325 : _Inherited(__a1, __a2) { } 00326 00327 template<typename _U1, typename _U2> 00328 explicit 00329 tuple(_U1&& __a1, _U2&& __a2) 00330 : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { } 00331 00332 constexpr tuple(const tuple&) = default; 00333 00334 tuple(tuple&& __in) 00335 : _Inherited(static_cast<_Inherited&&>(__in)) { } 00336 00337 template<typename _U1, typename _U2> 00338 tuple(const tuple<_U1, _U2>& __in) 00339 : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { } 00340 00341 template<typename _U1, typename _U2> 00342 tuple(tuple<_U1, _U2>&& __in) 00343 : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { } 00344 00345 template<typename _U1, typename _U2> 00346 tuple(const pair<_U1, _U2>& __in) 00347 : _Inherited(__in.first, __in.second) { } 00348 00349 template<typename _U1, typename _U2> 00350 tuple(pair<_U1, _U2>&& __in) 00351 : _Inherited(std::forward<_U1>(__in.first), 00352 std::forward<_U2>(__in.second)) { } 00353 00354 tuple& 00355 operator=(const tuple& __in) 00356 { 00357 static_cast<_Inherited&>(*this) = __in; 00358 return *this; 00359 } 00360 00361 tuple& 00362 operator=(tuple&& __in) 00363 { 00364 static_cast<_Inherited&>(*this) = std::move(__in); 00365 return *this; 00366 } 00367 00368 template<typename _U1, typename _U2> 00369 tuple& 00370 operator=(const tuple<_U1, _U2>& __in) 00371 { 00372 static_cast<_Inherited&>(*this) = __in; 00373 return *this; 00374 } 00375 00376 template<typename _U1, typename _U2> 00377 tuple& 00378 operator=(tuple<_U1, _U2>&& __in) 00379 { 00380 static_cast<_Inherited&>(*this) = std::move(__in); 00381 return *this; 00382 } 00383 00384 template<typename _U1, typename _U2> 00385 tuple& 00386 operator=(const pair<_U1, _U2>& __in) 00387 { 00388 this->_M_head() = __in.first; 00389 this->_M_tail()._M_head() = __in.second; 00390 return *this; 00391 } 00392 00393 template<typename _U1, typename _U2> 00394 tuple& 00395 operator=(pair<_U1, _U2>&& __in) 00396 { 00397 this->_M_head() = std::forward<_U1>(__in.first); 00398 this->_M_tail()._M_head() = std::forward<_U2>(__in.second); 00399 return *this; 00400 } 00401 00402 void 00403 swap(tuple& __in) 00404 { 00405 using std::swap; 00406 swap(this->_M_head(), __in._M_head()); 00407 swap(this->_M_tail()._M_head(), __in._M_tail()._M_head()); 00408 } 00409 }; 00410 00411 /// tuple (1-element). 00412 template<typename _T1> 00413 class tuple<_T1> : public _Tuple_impl<0, _T1> 00414 { 00415 typedef _Tuple_impl<0, _T1> _Inherited; 00416 00417 public: 00418 constexpr tuple() 00419 : _Inherited() { } 00420 00421 explicit 00422 constexpr tuple(const _T1& __a1) 00423 : _Inherited(__a1) { } 00424 00425 template<typename _U1, typename = typename 00426 std::enable_if<std::is_convertible<_U1, _T1>::value>::type> 00427 explicit 00428 tuple(_U1&& __a1) 00429 : _Inherited(std::forward<_U1>(__a1)) { } 00430 00431 constexpr tuple(const tuple&) = default; 00432 00433 tuple(tuple&& __in) 00434 : _Inherited(static_cast<_Inherited&&>(__in)) { } 00435 00436 template<typename _U1> 00437 tuple(const tuple<_U1>& __in) 00438 : _Inherited(static_cast<const _Tuple_impl<0, _U1>&>(__in)) { } 00439 00440 template<typename _U1> 00441 tuple(tuple<_U1>&& __in) 00442 : _Inherited(static_cast<_Tuple_impl<0, _U1>&&>(__in)) { } 00443 00444 tuple& 00445 operator=(const tuple& __in) 00446 { 00447 static_cast<_Inherited&>(*this) = __in; 00448 return *this; 00449 } 00450 00451 tuple& 00452 operator=(tuple&& __in) 00453 { 00454 static_cast<_Inherited&>(*this) = std::move(__in); 00455 return *this; 00456 } 00457 00458 template<typename _U1> 00459 tuple& 00460 operator=(const tuple<_U1>& __in) 00461 { 00462 static_cast<_Inherited&>(*this) = __in; 00463 return *this; 00464 } 00465 00466 template<typename _U1> 00467 tuple& 00468 operator=(tuple<_U1>&& __in) 00469 { 00470 static_cast<_Inherited&>(*this) = std::move(__in); 00471 return *this; 00472 } 00473 00474 void 00475 swap(tuple& __in) 00476 { _Inherited::_M_swap_impl(__in); } 00477 }; 00478 00479 00480 /// Gives the type of the ith element of a given tuple type. 00481 template<std::size_t __i, typename _Tp> 00482 struct tuple_element; 00483 00484 /** 00485 * Recursive case for tuple_element: strip off the first element in 00486 * the tuple and retrieve the (i-1)th element of the remaining tuple. 00487 */ 00488 template<std::size_t __i, typename _Head, typename... _Tail> 00489 struct tuple_element<__i, tuple<_Head, _Tail...> > 00490 : tuple_element<__i - 1, tuple<_Tail...> > { }; 00491 00492 /** 00493 * Basis case for tuple_element: The first element is the one we're seeking. 00494 */ 00495 template<typename _Head, typename... _Tail> 00496 struct tuple_element<0, tuple<_Head, _Tail...> > 00497 { 00498 typedef _Head type; 00499 }; 00500 00501 /// Finds the size of a given tuple type. 00502 template<typename _Tp> 00503 struct tuple_size; 00504 00505 /// class tuple_size 00506 template<typename... _Elements> 00507 struct tuple_size<tuple<_Elements...> > 00508 { 00509 static const std::size_t value = sizeof...(_Elements); 00510 }; 00511 00512 template<typename... _Elements> 00513 const std::size_t tuple_size<tuple<_Elements...> >::value; 00514 00515 template<std::size_t __i, typename _Head, typename... _Tail> 00516 inline typename __add_ref<_Head>::type 00517 __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t) 00518 { return __t._M_head(); } 00519 00520 template<std::size_t __i, typename _Head, typename... _Tail> 00521 inline typename __add_c_ref<_Head>::type 00522 __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t) 00523 { return __t._M_head(); } 00524 00525 // Return a reference (const reference) to the ith element of a tuple. 00526 // Any const or non-const ref elements are returned with their original type. 00527 template<std::size_t __i, typename... _Elements> 00528 inline typename __add_ref< 00529 typename tuple_element<__i, tuple<_Elements...> >::type 00530 >::type 00531 get(tuple<_Elements...>& __t) 00532 { return __get_helper<__i>(__t); } 00533 00534 template<std::size_t __i, typename... _Elements> 00535 inline typename __add_c_ref< 00536 typename tuple_element<__i, tuple<_Elements...> >::type 00537 >::type 00538 get(const tuple<_Elements...>& __t) 00539 { return __get_helper<__i>(__t); } 00540 00541 // This class helps construct the various comparison operations on tuples 00542 template<std::size_t __check_equal_size, std::size_t __i, std::size_t __j, 00543 typename _Tp, typename _Up> 00544 struct __tuple_compare; 00545 00546 template<std::size_t __i, std::size_t __j, typename _Tp, typename _Up> 00547 struct __tuple_compare<0, __i, __j, _Tp, _Up> 00548 { 00549 static bool __eq(const _Tp& __t, const _Up& __u) 00550 { 00551 return (get<__i>(__t) == get<__i>(__u) && 00552 __tuple_compare<0, __i + 1, __j, _Tp, _Up>::__eq(__t, __u)); 00553 } 00554 00555 static bool __less(const _Tp& __t, const _Up& __u) 00556 { 00557 return ((get<__i>(__t) < get<__i>(__u)) 00558 || !(get<__i>(__u) < get<__i>(__t)) && 00559 __tuple_compare<0, __i + 1, __j, _Tp, _Up>::__less(__t, __u)); 00560 } 00561 }; 00562 00563 template<std::size_t __i, typename _Tp, typename _Up> 00564 struct __tuple_compare<0, __i, __i, _Tp, _Up> 00565 { 00566 static bool __eq(const _Tp&, const _Up&) 00567 { return true; } 00568 00569 static bool __less(const _Tp&, const _Up&) 00570 { return false; } 00571 }; 00572 00573 template<typename... _TElements, typename... _UElements> 00574 bool 00575 operator==(const tuple<_TElements...>& __t, 00576 const tuple<_UElements...>& __u) 00577 { 00578 typedef tuple<_TElements...> _Tp; 00579 typedef tuple<_UElements...> _Up; 00580 return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value, 00581 0, tuple_size<_Tp>::value, _Tp, _Up>::__eq(__t, __u)); 00582 } 00583 00584 template<typename... _TElements, typename... _UElements> 00585 bool 00586 operator<(const tuple<_TElements...>& __t, 00587 const tuple<_UElements...>& __u) 00588 { 00589 typedef tuple<_TElements...> _Tp; 00590 typedef tuple<_UElements...> _Up; 00591 return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value, 00592 0, tuple_size<_Tp>::value, _Tp, _Up>::__less(__t, __u)); 00593 } 00594 00595 template<typename... _TElements, typename... _UElements> 00596 inline bool 00597 operator!=(const tuple<_TElements...>& __t, 00598 const tuple<_UElements...>& __u) 00599 { return !(__t == __u); } 00600 00601 template<typename... _TElements, typename... _UElements> 00602 inline bool 00603 operator>(const tuple<_TElements...>& __t, 00604 const tuple<_UElements...>& __u) 00605 { return __u < __t; } 00606 00607 template<typename... _TElements, typename... _UElements> 00608 inline bool 00609 operator<=(const tuple<_TElements...>& __t, 00610 const tuple<_UElements...>& __u) 00611 { return !(__u < __t); } 00612 00613 template<typename... _TElements, typename... _UElements> 00614 inline bool 00615 operator>=(const tuple<_TElements...>& __t, 00616 const tuple<_UElements...>& __u) 00617 { return !(__t < __u); } 00618 00619 // NB: DR 705. 00620 template<typename... _Elements> 00621 inline tuple<typename __decay_and_strip<_Elements>::__type...> 00622 make_tuple(_Elements&&... __args) 00623 { 00624 typedef tuple<typename __decay_and_strip<_Elements>::__type...> 00625 __result_type; 00626 return __result_type(std::forward<_Elements>(__args)...); 00627 } 00628 00629 template<typename... _Elements> 00630 inline tuple<_Elements&&...> 00631 forward_as_tuple(_Elements&&... __args) 00632 { return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); } 00633 00634 template<std::size_t...> struct __index_holder { }; 00635 00636 template<std::size_t __i, typename _IdxHolder, typename... _Elements> 00637 struct __index_holder_impl; 00638 00639 template<std::size_t __i, std::size_t... _Indexes, typename _IdxHolder, 00640 typename... _Elements> 00641 struct __index_holder_impl<__i, __index_holder<_Indexes...>, 00642 _IdxHolder, _Elements...> 00643 { 00644 typedef typename __index_holder_impl<__i + 1, 00645 __index_holder<_Indexes..., __i>, 00646 _Elements...>::type type; 00647 }; 00648 00649 template<std::size_t __i, std::size_t... _Indexes> 00650 struct __index_holder_impl<__i, __index_holder<_Indexes...> > 00651 { typedef __index_holder<_Indexes...> type; }; 00652 00653 template<typename... _Elements> 00654 struct __make_index_holder 00655 : __index_holder_impl<0, __index_holder<>, _Elements...> { }; 00656 00657 template<typename... _TElements, std::size_t... _TIdx, 00658 typename... _UElements, std::size_t... _UIdx> 00659 inline tuple<_TElements..., _UElements...> 00660 __tuple_cat_helper(const tuple<_TElements...>& __t, 00661 const __index_holder<_TIdx...>&, 00662 const tuple<_UElements...>& __u, 00663 const __index_holder<_UIdx...>&) 00664 { return tuple<_TElements..., _UElements...>(get<_TIdx>(__t)..., 00665 get<_UIdx>(__u)...); } 00666 00667 template<typename... _TElements, std::size_t... _TIdx, 00668 typename... _UElements, std::size_t... _UIdx> 00669 inline tuple<_TElements..., _UElements...> 00670 __tuple_cat_helper(tuple<_TElements...>&& __t, 00671 const __index_holder<_TIdx...>&, 00672 const tuple<_UElements...>& __u, 00673 const __index_holder<_UIdx...>&) 00674 { return tuple<_TElements..., _UElements...> 00675 (std::forward<_TElements>(get<_TIdx>(__t))..., get<_UIdx>(__u)...); } 00676 00677 template<typename... _TElements, std::size_t... _TIdx, 00678 typename... _UElements, std::size_t... _UIdx> 00679 inline tuple<_TElements..., _UElements...> 00680 __tuple_cat_helper(const tuple<_TElements...>& __t, 00681 const __index_holder<_TIdx...>&, 00682 tuple<_UElements...>&& __u, 00683 const __index_holder<_UIdx...>&) 00684 { return tuple<_TElements..., _UElements...> 00685 (get<_TIdx>(__t)..., std::forward<_UElements>(get<_UIdx>(__u))...); } 00686 00687 template<typename... _TElements, std::size_t... _TIdx, 00688 typename... _UElements, std::size_t... _UIdx> 00689 inline tuple<_TElements..., _UElements...> 00690 __tuple_cat_helper(tuple<_TElements...>&& __t, 00691 const __index_holder<_TIdx...>&, 00692 tuple<_UElements...>&& __u, 00693 const __index_holder<_UIdx...>&) 00694 { return tuple<_TElements..., _UElements...> 00695 (std::forward<_TElements>(get<_TIdx>(__t))..., 00696 std::forward<_UElements>(get<_UIdx>(__u))...); } 00697 00698 template<typename... _TElements, typename... _UElements> 00699 inline tuple<_TElements..., _UElements...> 00700 tuple_cat(const tuple<_TElements...>& __t, const tuple<_UElements...>& __u) 00701 { 00702 return __tuple_cat_helper(__t, typename 00703 __make_index_holder<_TElements...>::type(), 00704 __u, typename 00705 __make_index_holder<_UElements...>::type()); 00706 } 00707 00708 template<typename... _TElements, typename... _UElements> 00709 inline tuple<_TElements..., _UElements...> 00710 tuple_cat(tuple<_TElements...>&& __t, const tuple<_UElements...>& __u) 00711 { 00712 return __tuple_cat_helper(std::move(__t), typename 00713 __make_index_holder<_TElements...>::type(), 00714 __u, typename 00715 __make_index_holder<_UElements...>::type()); 00716 } 00717 00718 template<typename... _TElements, typename... _UElements> 00719 inline tuple<_TElements..., _UElements...> 00720 tuple_cat(const tuple<_TElements...>& __t, tuple<_UElements...>&& __u) 00721 { 00722 return __tuple_cat_helper(__t, typename 00723 __make_index_holder<_TElements...>::type(), 00724 std::move(__u), typename 00725 __make_index_holder<_UElements...>::type()); 00726 } 00727 00728 template<typename... _TElements, typename... _UElements> 00729 inline tuple<_TElements..., _UElements...> 00730 tuple_cat(tuple<_TElements...>&& __t, tuple<_UElements...>&& __u) 00731 { 00732 return __tuple_cat_helper(std::move(__t), typename 00733 __make_index_holder<_TElements...>::type(), 00734 std::move(__u), typename 00735 __make_index_holder<_UElements...>::type()); 00736 } 00737 00738 template<typename... _Elements> 00739 inline tuple<_Elements&...> 00740 tie(_Elements&... __args) 00741 { return tuple<_Elements&...>(__args...); } 00742 00743 template<typename... _Elements> 00744 inline void 00745 swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y) 00746 { __x.swap(__y); } 00747 00748 // A class (and instance) which can be used in 'tie' when an element 00749 // of a tuple is not required 00750 struct _Swallow_assign 00751 { 00752 template<class _Tp> 00753 const _Swallow_assign& 00754 operator=(const _Tp&) const 00755 { return *this; } 00756 }; 00757 00758 const _Swallow_assign ignore{}; 00759 00760 /** 00761 * Stores a tuple of indices. Used by bind() to extract the elements 00762 * in a tuple. 00763 */ 00764 template<int... _Indexes> 00765 struct _Index_tuple 00766 { 00767 typedef _Index_tuple<_Indexes..., sizeof...(_Indexes)> __next; 00768 }; 00769 00770 /// Builds an _Index_tuple<0, 1, 2, ..., _Num-1>. 00771 template<std::size_t _Num> 00772 struct _Build_index_tuple 00773 { 00774 typedef typename _Build_index_tuple<_Num-1>::__type::__next __type; 00775 }; 00776 00777 template<> 00778 struct _Build_index_tuple<0> 00779 { 00780 typedef _Index_tuple<> __type; 00781 }; 00782 00783 // See stl_pair.h... 00784 template<class _T1, class _T2> 00785 template<typename _Tp, typename... _Args> 00786 inline _Tp 00787 pair<_T1, _T2>:: 00788 __cons(tuple<_Args...>&& __tuple) 00789 { 00790 typedef typename _Build_index_tuple<sizeof...(_Args)>::__type 00791 _Indexes; 00792 return __do_cons<_Tp>(std::move(__tuple), _Indexes()); 00793 } 00794 00795 template<class _T1, class _T2> 00796 template<typename _Tp, typename... _Args, int... _Indexes> 00797 inline _Tp 00798 pair<_T1, _T2>:: 00799 __do_cons(tuple<_Args...>&& __tuple, 00800 const _Index_tuple<_Indexes...>&) 00801 { return _Tp(std::forward<_Args>(get<_Indexes>(__tuple))...); } 00802 00803 _GLIBCXX_END_NAMESPACE_VERSION 00804 } // namespace 00805 00806 #endif // __GXX_EXPERIMENTAL_CXX0X__ 00807 00808 #endif // _GLIBCXX_TUPLE