tuple 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698
  1. // <tuple> -*- C++ -*-
  2. // Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
  3. //
  4. // This file is part of the GNU ISO C++ Library. This library is free
  5. // software; you can redistribute it and/or modify it under the
  6. // terms of the GNU General Public License as published by the
  7. // Free Software Foundation; either version 3, or (at your option)
  8. // any later version.
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. // Under Section 7 of GPL version 3, you are granted additional
  14. // permissions described in the GCC Runtime Library Exception, version
  15. // 3.1, as published by the Free Software Foundation.
  16. // You should have received a copy of the GNU General Public License and
  17. // a copy of the GCC Runtime Library Exception along with this program;
  18. // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  19. // <http://www.gnu.org/licenses/>.
  20. /** @file include/tuple
  21. * This is a Standard C++ Library header.
  22. */
  23. #ifndef _GLIBCXX_TUPLE
  24. #define _GLIBCXX_TUPLE 1
  25. #pragma GCC system_header
  26. #ifndef __GXX_EXPERIMENTAL_CXX0X__
  27. # include <c++0x_warning.h>
  28. #else
  29. #include <utility>
  30. namespace std
  31. {
  32. // Adds a const reference to a non-reference type.
  33. template<typename _Tp>
  34. struct __add_c_ref
  35. { typedef const _Tp& type; };
  36. template<typename _Tp>
  37. struct __add_c_ref<_Tp&>
  38. { typedef _Tp& type; };
  39. // Adds a reference to a non-reference type.
  40. template<typename _Tp>
  41. struct __add_ref
  42. { typedef _Tp& type; };
  43. template<typename _Tp>
  44. struct __add_ref<_Tp&>
  45. { typedef _Tp& type; };
  46. template<std::size_t _Idx, typename _Head, bool _IsEmpty>
  47. struct _Head_base;
  48. template<std::size_t _Idx, typename _Head>
  49. struct _Head_base<_Idx, _Head, true>
  50. : public _Head
  51. {
  52. _Head_base()
  53. : _Head() { }
  54. _Head_base(const _Head& __h)
  55. : _Head(__h) { }
  56. template<typename _UHead>
  57. _Head_base(_UHead&& __h)
  58. : _Head(std::forward<_UHead>(__h)) { }
  59. _Head& _M_head() { return *this; }
  60. const _Head& _M_head() const { return *this; }
  61. void _M_swap_impl(_Head&&) { /* no-op */ }
  62. };
  63. template<std::size_t _Idx, typename _Head>
  64. struct _Head_base<_Idx, _Head, false>
  65. {
  66. _Head_base()
  67. : _M_head_impl() { }
  68. _Head_base(const _Head& __h)
  69. : _M_head_impl(__h) { }
  70. template<typename _UHead>
  71. _Head_base(_UHead&& __h)
  72. : _M_head_impl(std::forward<_UHead>(__h)) { }
  73. _Head& _M_head() { return _M_head_impl; }
  74. const _Head& _M_head() const { return _M_head_impl; }
  75. void
  76. _M_swap_impl(_Head&& __h)
  77. {
  78. using std::swap;
  79. swap(__h, _M_head_impl);
  80. }
  81. _Head _M_head_impl;
  82. };
  83. /**
  84. * Contains the actual implementation of the @c tuple template, stored
  85. * as a recursive inheritance hierarchy from the first element (most
  86. * derived class) to the last (least derived class). The @c Idx
  87. * parameter gives the 0-based index of the element stored at this
  88. * point in the hierarchy; we use it to implement a constant-time
  89. * get() operation.
  90. */
  91. template<std::size_t _Idx, typename... _Elements>
  92. struct _Tuple_impl;
  93. /**
  94. * Zero-element tuple implementation. This is the basis case for the
  95. * inheritance recursion.
  96. */
  97. template<std::size_t _Idx>
  98. struct _Tuple_impl<_Idx>
  99. {
  100. protected:
  101. void _M_swap_impl(_Tuple_impl&&) { /* no-op */ }
  102. };
  103. /**
  104. * Recursive tuple implementation. Here we store the @c Head element
  105. * and derive from a @c Tuple_impl containing the remaining elements
  106. * (which contains the @c Tail).
  107. */
  108. template<std::size_t _Idx, typename _Head, typename... _Tail>
  109. struct _Tuple_impl<_Idx, _Head, _Tail...>
  110. : public _Tuple_impl<_Idx + 1, _Tail...>,
  111. private _Head_base<_Idx, _Head, std::is_empty<_Head>::value>
  112. {
  113. typedef _Tuple_impl<_Idx + 1, _Tail...> _Inherited;
  114. typedef _Head_base<_Idx, _Head, std::is_empty<_Head>::value> _Base;
  115. _Head& _M_head() { return _Base::_M_head(); }
  116. const _Head& _M_head() const { return _Base::_M_head(); }
  117. _Inherited& _M_tail() { return *this; }
  118. const _Inherited& _M_tail() const { return *this; }
  119. _Tuple_impl()
  120. : _Inherited(), _Base() { }
  121. explicit
  122. _Tuple_impl(const _Head& __head, const _Tail&... __tail)
  123. : _Inherited(__tail...), _Base(__head) { }
  124. template<typename _UHead, typename... _UTail>
  125. explicit
  126. _Tuple_impl(_UHead&& __head, _UTail&&... __tail)
  127. : _Inherited(std::forward<_UTail>(__tail)...),
  128. _Base(std::forward<_UHead>(__head)) { }
  129. _Tuple_impl(const _Tuple_impl& __in)
  130. : _Inherited(__in._M_tail()), _Base(__in._M_head()) { }
  131. _Tuple_impl(_Tuple_impl&& __in)
  132. : _Inherited(std::move<_Inherited&&>(__in._M_tail())),
  133. _Base(std::forward<_Head>(__in._M_head())) { }
  134. template<typename... _UElements>
  135. _Tuple_impl(const _Tuple_impl<_Idx, _UElements...>& __in)
  136. : _Inherited(__in._M_tail()), _Base(__in._M_head()) { }
  137. template<typename... _UElements>
  138. _Tuple_impl(_Tuple_impl<_Idx, _UElements...>&& __in)
  139. : _Inherited(std::move<typename _Tuple_impl<_Idx, _UElements...>::
  140. _Inherited&&>(__in._M_tail())),
  141. _Base(std::forward<typename _Tuple_impl<_Idx, _UElements...>::
  142. _Base>(__in._M_head())) { }
  143. _Tuple_impl&
  144. operator=(const _Tuple_impl& __in)
  145. {
  146. _M_head() = __in._M_head();
  147. _M_tail() = __in._M_tail();
  148. return *this;
  149. }
  150. _Tuple_impl&
  151. operator=(_Tuple_impl&& __in)
  152. {
  153. _M_head() = std::move(__in._M_head());
  154. _M_tail() = std::move(__in._M_tail());
  155. return *this;
  156. }
  157. template<typename... _UElements>
  158. _Tuple_impl&
  159. operator=(const _Tuple_impl<_Idx, _UElements...>& __in)
  160. {
  161. _M_head() = __in._M_head();
  162. _M_tail() = __in._M_tail();
  163. return *this;
  164. }
  165. template<typename... _UElements>
  166. _Tuple_impl&
  167. operator=(_Tuple_impl<_Idx, _UElements...>&& __in)
  168. {
  169. _M_head() = std::move(__in._M_head());
  170. _M_tail() = std::move(__in._M_tail());
  171. return *this;
  172. }
  173. protected:
  174. void
  175. _M_swap_impl(_Tuple_impl&& __in)
  176. {
  177. _Base::_M_swap_impl(__in._M_head());
  178. _Inherited::_M_swap_impl(__in._M_tail());
  179. }
  180. };
  181. /// tuple
  182. template<typename... _Elements>
  183. class tuple : public _Tuple_impl<0, _Elements...>
  184. {
  185. typedef _Tuple_impl<0, _Elements...> _Inherited;
  186. public:
  187. tuple()
  188. : _Inherited() { }
  189. explicit
  190. tuple(const _Elements&... __elements)
  191. : _Inherited(__elements...) { }
  192. template<typename... _UElements>
  193. explicit
  194. tuple(_UElements&&... __elements)
  195. : _Inherited(std::forward<_UElements>(__elements)...) { }
  196. tuple(const tuple& __in)
  197. : _Inherited(static_cast<const _Inherited&>(__in)) { }
  198. tuple(tuple&& __in)
  199. : _Inherited(std::move<_Inherited>(__in)) { }
  200. template<typename... _UElements>
  201. tuple(const tuple<_UElements...>& __in)
  202. : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
  203. { }
  204. template<typename... _UElements>
  205. tuple(tuple<_UElements...>&& __in)
  206. : _Inherited(std::move<_Tuple_impl<0, _UElements...> >(__in)) { }
  207. // XXX http://gcc.gnu.org/ml/libstdc++/2008-02/msg00047.html
  208. template<typename... _UElements>
  209. tuple(tuple<_UElements...>& __in)
  210. : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&>(__in))
  211. { }
  212. tuple&
  213. operator=(const tuple& __in)
  214. {
  215. static_cast<_Inherited&>(*this) = __in;
  216. return *this;
  217. }
  218. tuple&
  219. operator=(tuple&& __in)
  220. {
  221. static_cast<_Inherited&>(*this) = std::move(__in);
  222. return *this;
  223. }
  224. template<typename... _UElements>
  225. tuple&
  226. operator=(const tuple<_UElements...>& __in)
  227. {
  228. static_cast<_Inherited&>(*this) = __in;
  229. return *this;
  230. }
  231. template<typename... _UElements>
  232. tuple&
  233. operator=(tuple<_UElements...>&& __in)
  234. {
  235. static_cast<_Inherited&>(*this) = std::move(__in);
  236. return *this;
  237. }
  238. void
  239. swap(tuple&& __in)
  240. { _Inherited::_M_swap_impl(__in); }
  241. };
  242. template<>
  243. class tuple<>
  244. {
  245. public:
  246. void swap(tuple&&) { /* no-op */ }
  247. };
  248. /// tuple (2-element), with construction and assignment from a pair.
  249. template<typename _T1, typename _T2>
  250. class tuple<_T1, _T2> : public _Tuple_impl<0, _T1, _T2>
  251. {
  252. typedef _Tuple_impl<0, _T1, _T2> _Inherited;
  253. public:
  254. tuple()
  255. : _Inherited() { }
  256. explicit
  257. tuple(const _T1& __a1, const _T2& __a2)
  258. : _Inherited(__a1, __a2) { }
  259. template<typename _U1, typename _U2>
  260. explicit
  261. tuple(_U1&& __a1, _U2&& __a2)
  262. : _Inherited(std::forward<_U1>(__a1), std::forward<_U2>(__a2)) { }
  263. tuple(const tuple& __in)
  264. : _Inherited(static_cast<const _Inherited&>(__in)) { }
  265. tuple(tuple&& __in)
  266. : _Inherited(std::move<_Inherited>(__in)) { }
  267. template<typename _U1, typename _U2>
  268. tuple(const tuple<_U1, _U2>& __in)
  269. : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&>(__in)) { }
  270. template<typename _U1, typename _U2>
  271. tuple(tuple<_U1, _U2>&& __in)
  272. : _Inherited(std::move<_Tuple_impl<0, _U1, _U2> >(__in)) { }
  273. template<typename _U1, typename _U2>
  274. tuple(const pair<_U1, _U2>& __in)
  275. : _Inherited(__in.first, __in.second) { }
  276. template<typename _U1, typename _U2>
  277. tuple(pair<_U1, _U2>&& __in)
  278. : _Inherited(std::move(__in.first), std::move(__in.second)) { }
  279. tuple&
  280. operator=(const tuple& __in)
  281. {
  282. static_cast<_Inherited&>(*this) = __in;
  283. return *this;
  284. }
  285. tuple&
  286. operator=(tuple&& __in)
  287. {
  288. static_cast<_Inherited&>(*this) = std::move(__in);
  289. return *this;
  290. }
  291. template<typename _U1, typename _U2>
  292. tuple&
  293. operator=(const tuple<_U1, _U2>& __in)
  294. {
  295. static_cast<_Inherited&>(*this) = __in;
  296. return *this;
  297. }
  298. template<typename _U1, typename _U2>
  299. tuple&
  300. operator=(tuple<_U1, _U2>&& __in)
  301. {
  302. static_cast<_Inherited&>(*this) = std::move(__in);
  303. return *this;
  304. }
  305. template<typename _U1, typename _U2>
  306. tuple&
  307. operator=(const pair<_U1, _U2>& __in)
  308. {
  309. this->_M_head() = __in.first;
  310. this->_M_tail()._M_head() = __in.second;
  311. return *this;
  312. }
  313. template<typename _U1, typename _U2>
  314. tuple&
  315. operator=(pair<_U1, _U2>&& __in)
  316. {
  317. this->_M_head() = std::move(__in.first);
  318. this->_M_tail()._M_head() = std::move(__in.second);
  319. return *this;
  320. }
  321. void
  322. swap(tuple&& __in)
  323. {
  324. using std::swap;
  325. swap(this->_M_head(), __in._M_head());
  326. swap(this->_M_tail()._M_head(), __in._M_tail()._M_head());
  327. }
  328. };
  329. /// Gives the type of the ith element of a given tuple type.
  330. template<std::size_t __i, typename _Tp>
  331. struct tuple_element;
  332. /**
  333. * Recursive case for tuple_element: strip off the first element in
  334. * the tuple and retrieve the (i-1)th element of the remaining tuple.
  335. */
  336. template<std::size_t __i, typename _Head, typename... _Tail>
  337. struct tuple_element<__i, tuple<_Head, _Tail...> >
  338. : tuple_element<__i - 1, tuple<_Tail...> > { };
  339. /**
  340. * Basis case for tuple_element: The first element is the one we're seeking.
  341. */
  342. template<typename _Head, typename... _Tail>
  343. struct tuple_element<0, tuple<_Head, _Tail...> >
  344. {
  345. typedef _Head type;
  346. };
  347. /// Finds the size of a given tuple type.
  348. template<typename _Tp>
  349. struct tuple_size;
  350. /// class tuple_size
  351. template<typename... _Elements>
  352. struct tuple_size<tuple<_Elements...> >
  353. {
  354. static const std::size_t value = sizeof...(_Elements);
  355. };
  356. template<typename... _Elements>
  357. const std::size_t tuple_size<tuple<_Elements...> >::value;
  358. template<std::size_t __i, typename _Head, typename... _Tail>
  359. inline typename __add_ref<_Head>::type
  360. __get_helper(_Tuple_impl<__i, _Head, _Tail...>& __t)
  361. { return __t._M_head(); }
  362. template<std::size_t __i, typename _Head, typename... _Tail>
  363. inline typename __add_c_ref<_Head>::type
  364. __get_helper(const _Tuple_impl<__i, _Head, _Tail...>& __t)
  365. { return __t._M_head(); }
  366. // Return a reference (const reference) to the ith element of a tuple.
  367. // Any const or non-const ref elements are returned with their original type.
  368. template<std::size_t __i, typename... _Elements>
  369. inline typename __add_ref<
  370. typename tuple_element<__i, tuple<_Elements...> >::type
  371. >::type
  372. get(tuple<_Elements...>& __t)
  373. { return __get_helper<__i>(__t); }
  374. template<std::size_t __i, typename... _Elements>
  375. inline typename __add_c_ref<
  376. typename tuple_element<__i, tuple<_Elements...> >::type
  377. >::type
  378. get(const tuple<_Elements...>& __t)
  379. { return __get_helper<__i>(__t); }
  380. // This class helps construct the various comparison operations on tuples
  381. template<std::size_t __check_equal_size, std::size_t __i, std::size_t __j,
  382. typename _Tp, typename _Up>
  383. struct __tuple_compare;
  384. template<std::size_t __i, std::size_t __j, typename _Tp, typename _Up>
  385. struct __tuple_compare<0, __i, __j, _Tp, _Up>
  386. {
  387. static bool __eq(const _Tp& __t, const _Up& __u)
  388. {
  389. return (get<__i>(__t) == get<__i>(__u) &&
  390. __tuple_compare<0, __i + 1, __j, _Tp, _Up>::__eq(__t, __u));
  391. }
  392. static bool __less(const _Tp& __t, const _Up& __u)
  393. {
  394. return ((get<__i>(__t) < get<__i>(__u))
  395. || !(get<__i>(__u) < get<__i>(__t)) &&
  396. __tuple_compare<0, __i + 1, __j, _Tp, _Up>::__less(__t, __u));
  397. }
  398. };
  399. template<std::size_t __i, typename _Tp, typename _Up>
  400. struct __tuple_compare<0, __i, __i, _Tp, _Up>
  401. {
  402. static bool __eq(const _Tp&, const _Up&)
  403. { return true; }
  404. static bool __less(const _Tp&, const _Up&)
  405. { return false; }
  406. };
  407. template<typename... _TElements, typename... _UElements>
  408. bool
  409. operator==(const tuple<_TElements...>& __t,
  410. const tuple<_UElements...>& __u)
  411. {
  412. typedef tuple<_TElements...> _Tp;
  413. typedef tuple<_UElements...> _Up;
  414. return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value,
  415. 0, tuple_size<_Tp>::value, _Tp, _Up>::__eq(__t, __u));
  416. }
  417. template<typename... _TElements, typename... _UElements>
  418. bool
  419. operator<(const tuple<_TElements...>& __t,
  420. const tuple<_UElements...>& __u)
  421. {
  422. typedef tuple<_TElements...> _Tp;
  423. typedef tuple<_UElements...> _Up;
  424. return (__tuple_compare<tuple_size<_Tp>::value - tuple_size<_Up>::value,
  425. 0, tuple_size<_Tp>::value, _Tp, _Up>::__less(__t, __u));
  426. }
  427. template<typename... _TElements, typename... _UElements>
  428. inline bool
  429. operator!=(const tuple<_TElements...>& __t,
  430. const tuple<_UElements...>& __u)
  431. { return !(__t == __u); }
  432. template<typename... _TElements, typename... _UElements>
  433. inline bool
  434. operator>(const tuple<_TElements...>& __t,
  435. const tuple<_UElements...>& __u)
  436. { return __u < __t; }
  437. template<typename... _TElements, typename... _UElements>
  438. inline bool
  439. operator<=(const tuple<_TElements...>& __t,
  440. const tuple<_UElements...>& __u)
  441. { return !(__u < __t); }
  442. template<typename... _TElements, typename... _UElements>
  443. inline bool
  444. operator>=(const tuple<_TElements...>& __t,
  445. const tuple<_UElements...>& __u)
  446. { return !(__t < __u); }
  447. // NB: DR 705.
  448. template<typename... _Elements>
  449. inline tuple<typename __decay_and_strip<_Elements>::__type...>
  450. make_tuple(_Elements&&... __args)
  451. {
  452. typedef tuple<typename __decay_and_strip<_Elements>::__type...>
  453. __result_type;
  454. return __result_type(std::forward<_Elements>(__args)...);
  455. }
  456. template<std::size_t...> struct __index_holder { };
  457. template<std::size_t __i, typename _IdxHolder, typename... _Elements>
  458. struct __index_holder_impl;
  459. template<std::size_t __i, std::size_t... _Indexes, typename _IdxHolder,
  460. typename... _Elements>
  461. struct __index_holder_impl<__i, __index_holder<_Indexes...>,
  462. _IdxHolder, _Elements...>
  463. {
  464. typedef typename __index_holder_impl<__i + 1,
  465. __index_holder<_Indexes..., __i>,
  466. _Elements...>::type type;
  467. };
  468. template<std::size_t __i, std::size_t... _Indexes>
  469. struct __index_holder_impl<__i, __index_holder<_Indexes...> >
  470. { typedef __index_holder<_Indexes...> type; };
  471. template<typename... _Elements>
  472. struct __make_index_holder
  473. : __index_holder_impl<0, __index_holder<>, _Elements...> { };
  474. template<typename... _TElements, std::size_t... _TIdx,
  475. typename... _UElements, std::size_t... _UIdx>
  476. inline tuple<_TElements..., _UElements...>
  477. __tuple_cat_helper(const tuple<_TElements...>& __t,
  478. const __index_holder<_TIdx...>&,
  479. const tuple<_UElements...>& __u,
  480. const __index_holder<_UIdx...>&)
  481. { return tuple<_TElements..., _UElements...>(get<_TIdx>(__t)...,
  482. get<_UIdx>(__u)...); }
  483. template<typename... _TElements, std::size_t... _TIdx,
  484. typename... _UElements, std::size_t... _UIdx>
  485. inline tuple<_TElements..., _UElements...>
  486. __tuple_cat_helper(tuple<_TElements...>&& __t,
  487. const __index_holder<_TIdx...>&,
  488. const tuple<_UElements...>& __u,
  489. const __index_holder<_UIdx...>&)
  490. { return tuple<_TElements..., _UElements...>
  491. (std::move(get<_TIdx>(__t))..., get<_UIdx>(__u)...); }
  492. template<typename... _TElements, std::size_t... _TIdx,
  493. typename... _UElements, std::size_t... _UIdx>
  494. inline tuple<_TElements..., _UElements...>
  495. __tuple_cat_helper(const tuple<_TElements...>& __t,
  496. const __index_holder<_TIdx...>&,
  497. tuple<_UElements...>&& __u,
  498. const __index_holder<_UIdx...>&)
  499. { return tuple<_TElements..., _UElements...>
  500. (get<_TIdx>(__t)..., std::move(get<_UIdx>(__u))...); }
  501. template<typename... _TElements, std::size_t... _TIdx,
  502. typename... _UElements, std::size_t... _UIdx>
  503. inline tuple<_TElements..., _UElements...>
  504. __tuple_cat_helper(tuple<_TElements...>&& __t,
  505. const __index_holder<_TIdx...>&,
  506. tuple<_UElements...>&& __u,
  507. const __index_holder<_UIdx...>&)
  508. { return tuple<_TElements..., _UElements...>
  509. (std::move(get<_TIdx>(__t))..., std::move(get<_UIdx>(__u))...); }
  510. template<typename... _TElements, typename... _UElements>
  511. inline tuple<_TElements..., _UElements...>
  512. tuple_cat(const tuple<_TElements...>& __t, const tuple<_UElements...>& __u)
  513. {
  514. return __tuple_cat_helper(__t, typename
  515. __make_index_holder<_TElements...>::type(),
  516. __u, typename
  517. __make_index_holder<_UElements...>::type());
  518. }
  519. template<typename... _TElements, typename... _UElements>
  520. inline tuple<_TElements..., _UElements...>
  521. tuple_cat(tuple<_TElements...>&& __t, const tuple<_UElements...>& __u)
  522. {
  523. return __tuple_cat_helper(std::move(__t), typename
  524. __make_index_holder<_TElements...>::type(),
  525. __u, typename
  526. __make_index_holder<_UElements...>::type());
  527. }
  528. template<typename... _TElements, typename... _UElements>
  529. inline tuple<_TElements..., _UElements...>
  530. tuple_cat(const tuple<_TElements...>& __t, tuple<_UElements...>&& __u)
  531. {
  532. return __tuple_cat_helper(__t, typename
  533. __make_index_holder<_TElements...>::type(),
  534. std::move(__u), typename
  535. __make_index_holder<_UElements...>::type());
  536. }
  537. template<typename... _TElements, typename... _UElements>
  538. inline tuple<_TElements..., _UElements...>
  539. tuple_cat(tuple<_TElements...>&& __t, tuple<_UElements...>&& __u)
  540. {
  541. return __tuple_cat_helper(std::move(__t), typename
  542. __make_index_holder<_TElements...>::type(),
  543. std::move(__u), typename
  544. __make_index_holder<_UElements...>::type());
  545. }
  546. template<typename... _Elements>
  547. inline tuple<_Elements&...>
  548. tie(_Elements&... __args)
  549. { return tuple<_Elements&...>(__args...); }
  550. template<typename... _Elements>
  551. inline void
  552. swap(tuple<_Elements...>& __x, tuple<_Elements...>& __y)
  553. { __x.swap(__y); }
  554. template<typename... _Elements>
  555. inline void
  556. swap(tuple<_Elements...>&& __x, tuple<_Elements...>& __y)
  557. { __x.swap(__y); }
  558. template<typename... _Elements>
  559. inline void
  560. swap(tuple<_Elements...>& __x, tuple<_Elements...>&& __y)
  561. { __x.swap(__y); }
  562. // A class (and instance) which can be used in 'tie' when an element
  563. // of a tuple is not required
  564. struct _Swallow_assign
  565. {
  566. template<class _Tp>
  567. _Swallow_assign&
  568. operator=(const _Tp&)
  569. { return *this; }
  570. };
  571. // TODO: Put this in some kind of shared file.
  572. namespace
  573. {
  574. _Swallow_assign ignore;
  575. }; // anonymous namespace
  576. }
  577. #endif // __GXX_EXPERIMENTAL_CXX0X__
  578. #endif // _GLIBCXX_TUPLE