tuple_basic.hpp 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987
  1. // tuple_basic.hpp -----------------------------------------------------
  2. // Copyright (C) 1999, 2000 Jaakko Jarvi (jaakko.jarvi@cs.utu.fi)
  3. //
  4. // Distributed under the Boost Software License, Version 1.0. (See
  5. // accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. // For more information, see http://www.boost.org
  8. // Outside help:
  9. // This and that, Gary Powell.
  10. // Fixed return types for get_head/get_tail
  11. // ( and other bugs ) per suggestion of Jens Maurer
  12. // simplified element type accessors + bug fix (Jeremy Siek)
  13. // Several changes/additions according to suggestions by Douglas Gregor,
  14. // William Kempf, Vesa Karvonen, John Max Skaller, Ed Brey, Beman Dawes,
  15. // David Abrahams.
  16. // Revision history:
  17. // 2002 05 01 Hugo Duncan: Fix for Borland after Jaakko's previous changes
  18. // 2002 04 18 Jaakko: tuple element types can be void or plain function
  19. // types, as long as no object is created.
  20. // Tuple objects can no hold even noncopyable types
  21. // such as arrays.
  22. // 2001 10 22 John Maddock
  23. // Fixes for Borland C++
  24. // 2001 08 30 David Abrahams
  25. // Added default constructor for cons<>.
  26. // -----------------------------------------------------------------
  27. #ifndef BOOST_TUPLE_BASIC_HPP
  28. #define BOOST_TUPLE_BASIC_HPP
  29. #include <utility> // needed for the assignment from pair to tuple
  30. #include <boost/type_traits/cv_traits.hpp>
  31. #include <boost/type_traits/function_traits.hpp>
  32. #include <boost/utility/swap.hpp>
  33. #include <boost/detail/workaround.hpp> // needed for BOOST_WORKAROUND
  34. #if defined(BOOST_GCC) && (BOOST_GCC >= 40700)
  35. #pragma GCC diagnostic push
  36. #pragma GCC diagnostic ignored "-Wunused-local-typedefs"
  37. #endif
  38. namespace boost {
  39. namespace tuples {
  40. // -- null_type --------------------------------------------------------
  41. struct null_type {};
  42. // a helper function to provide a const null_type type temporary
  43. namespace detail {
  44. inline const null_type cnull() { return null_type(); }
  45. // -- if construct ------------------------------------------------
  46. // Proposed by Krzysztof Czarnecki and Ulrich Eisenecker
  47. template <bool If, class Then, class Else> struct IF { typedef Then RET; };
  48. template <class Then, class Else> struct IF<false, Then, Else> {
  49. typedef Else RET;
  50. };
  51. } // end detail
  52. // - cons forward declaration -----------------------------------------------
  53. template <class HT, class TT> struct cons;
  54. // - tuple forward declaration -----------------------------------------------
  55. template <
  56. class T0 = null_type, class T1 = null_type, class T2 = null_type,
  57. class T3 = null_type, class T4 = null_type, class T5 = null_type,
  58. class T6 = null_type, class T7 = null_type, class T8 = null_type,
  59. class T9 = null_type>
  60. class tuple;
  61. // tuple_length forward declaration
  62. template<class T> struct length;
  63. namespace detail {
  64. // -- generate error template, referencing to non-existing members of this
  65. // template is used to produce compilation errors intentionally
  66. template<class T>
  67. class generate_error;
  68. template<int N>
  69. struct drop_front {
  70. template<class Tuple>
  71. struct apply {
  72. typedef BOOST_DEDUCED_TYPENAME drop_front<N-1>::BOOST_NESTED_TEMPLATE
  73. apply<Tuple> next;
  74. typedef BOOST_DEDUCED_TYPENAME next::type::tail_type type;
  75. static const type& call(const Tuple& tup) {
  76. return next::call(tup).tail;
  77. }
  78. };
  79. };
  80. template<>
  81. struct drop_front<0> {
  82. template<class Tuple>
  83. struct apply {
  84. typedef Tuple type;
  85. static const type& call(const Tuple& tup) {
  86. return tup;
  87. }
  88. };
  89. };
  90. } // end of namespace detail
  91. // -cons type accessors ----------------------------------------
  92. // typename tuples::element<N,T>::type gets the type of the
  93. // Nth element ot T, first element is at index 0
  94. // -------------------------------------------------------
  95. #ifndef BOOST_NO_CV_SPECIALIZATIONS
  96. template<int N, class T>
  97. struct element
  98. {
  99. typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
  100. apply<T>::type::head_type type;
  101. };
  102. template<int N, class T>
  103. struct element<N, const T>
  104. {
  105. private:
  106. typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
  107. apply<T>::type::head_type unqualified_type;
  108. public:
  109. #if BOOST_WORKAROUND(__BORLANDC__,<0x600)
  110. typedef const unqualified_type type;
  111. #else
  112. typedef BOOST_DEDUCED_TYPENAME boost::add_const<unqualified_type>::type type;
  113. #endif
  114. };
  115. #else // def BOOST_NO_CV_SPECIALIZATIONS
  116. namespace detail {
  117. template<int N, class T, bool IsConst>
  118. struct element_impl
  119. {
  120. typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
  121. apply<T>::type::head_type type;
  122. };
  123. template<int N, class T>
  124. struct element_impl<N, T, true /* IsConst */>
  125. {
  126. typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
  127. apply<T>::type::head_type unqualified_type;
  128. typedef const unqualified_type type;
  129. };
  130. } // end of namespace detail
  131. template<int N, class T>
  132. struct element:
  133. public detail::element_impl<N, T, ::boost::is_const<T>::value>
  134. {
  135. };
  136. #endif
  137. // -get function templates -----------------------------------------------
  138. // Usage: get<N>(aTuple)
  139. // -- some traits classes for get functions
  140. // access traits lifted from detail namespace to be part of the interface,
  141. // (Joel de Guzman's suggestion). Rationale: get functions are part of the
  142. // interface, so should the way to express their return types be.
  143. template <class T> struct access_traits {
  144. typedef const T& const_type;
  145. typedef T& non_const_type;
  146. typedef const typename boost::remove_cv<T>::type& parameter_type;
  147. // used as the tuple constructors parameter types
  148. // Rationale: non-reference tuple element types can be cv-qualified.
  149. // It should be possible to initialize such types with temporaries,
  150. // and when binding temporaries to references, the reference must
  151. // be non-volatile and const. 8.5.3. (5)
  152. };
  153. template <class T> struct access_traits<T&> {
  154. typedef T& const_type;
  155. typedef T& non_const_type;
  156. typedef T& parameter_type;
  157. };
  158. // get function for non-const cons-lists, returns a reference to the element
  159. template<int N, class HT, class TT>
  160. inline typename access_traits<
  161. typename element<N, cons<HT, TT> >::type
  162. >::non_const_type
  163. get(cons<HT, TT>& c) {
  164. typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
  165. apply<cons<HT, TT> > impl;
  166. typedef BOOST_DEDUCED_TYPENAME impl::type cons_element;
  167. return const_cast<cons_element&>(impl::call(c)).head;
  168. }
  169. // get function for const cons-lists, returns a const reference to
  170. // the element. If the element is a reference, returns the reference
  171. // as such (that is, can return a non-const reference)
  172. template<int N, class HT, class TT>
  173. inline typename access_traits<
  174. typename element<N, cons<HT, TT> >::type
  175. >::const_type
  176. get(const cons<HT, TT>& c) {
  177. typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
  178. apply<cons<HT, TT> > impl;
  179. return impl::call(c).head;
  180. }
  181. // -- the cons template --------------------------------------------------
  182. namespace detail {
  183. // These helper templates wrap void types and plain function types.
  184. // The reationale is to allow one to write tuple types with those types
  185. // as elements, even though it is not possible to instantiate such object.
  186. // E.g: typedef tuple<void> some_type; // ok
  187. // but: some_type x; // fails
  188. template <class T> class non_storeable_type {
  189. non_storeable_type();
  190. };
  191. template <class T> struct wrap_non_storeable_type {
  192. typedef typename IF<
  193. ::boost::is_function<T>::value, non_storeable_type<T>, T
  194. >::RET type;
  195. };
  196. template <> struct wrap_non_storeable_type<void> {
  197. typedef non_storeable_type<void> type;
  198. };
  199. } // detail
  200. template <class HT, class TT>
  201. struct cons {
  202. typedef HT head_type;
  203. typedef TT tail_type;
  204. typedef typename
  205. detail::wrap_non_storeable_type<head_type>::type stored_head_type;
  206. stored_head_type head;
  207. tail_type tail;
  208. typename access_traits<stored_head_type>::non_const_type
  209. get_head() { return head; }
  210. typename access_traits<tail_type>::non_const_type
  211. get_tail() { return tail; }
  212. typename access_traits<stored_head_type>::const_type
  213. get_head() const { return head; }
  214. typename access_traits<tail_type>::const_type
  215. get_tail() const { return tail; }
  216. cons() : head(), tail() {}
  217. // cons() : head(detail::default_arg<HT>::f()), tail() {}
  218. // the argument for head is not strictly needed, but it prevents
  219. // array type elements. This is good, since array type elements
  220. // cannot be supported properly in any case (no assignment,
  221. // copy works only if the tails are exactly the same type, ...)
  222. cons(typename access_traits<stored_head_type>::parameter_type h,
  223. const tail_type& t)
  224. : head (h), tail(t) {}
  225. template <class T1, class T2, class T3, class T4, class T5,
  226. class T6, class T7, class T8, class T9, class T10>
  227. cons( T1& t1, T2& t2, T3& t3, T4& t4, T5& t5,
  228. T6& t6, T7& t7, T8& t8, T9& t9, T10& t10 )
  229. : head (t1),
  230. tail (t2, t3, t4, t5, t6, t7, t8, t9, t10, detail::cnull())
  231. {}
  232. template <class T2, class T3, class T4, class T5,
  233. class T6, class T7, class T8, class T9, class T10>
  234. cons( const null_type& /*t1*/, T2& t2, T3& t3, T4& t4, T5& t5,
  235. T6& t6, T7& t7, T8& t8, T9& t9, T10& t10 )
  236. : head (),
  237. tail (t2, t3, t4, t5, t6, t7, t8, t9, t10, detail::cnull())
  238. {}
  239. template <class HT2, class TT2>
  240. cons( const cons<HT2, TT2>& u ) : head(u.head), tail(u.tail) {}
  241. template <class HT2, class TT2>
  242. cons& operator=( const cons<HT2, TT2>& u ) {
  243. head=u.head; tail=u.tail; return *this;
  244. }
  245. // must define assignment operator explicitly, implicit version is
  246. // illformed if HT is a reference (12.8. (12))
  247. cons& operator=(const cons& u) {
  248. head = u.head; tail = u.tail; return *this;
  249. }
  250. template <class T1, class T2>
  251. cons& operator=( const std::pair<T1, T2>& u ) {
  252. BOOST_STATIC_ASSERT(length<cons>::value == 2); // check length = 2
  253. head = u.first; tail.head = u.second; return *this;
  254. }
  255. // get member functions (non-const and const)
  256. template <int N>
  257. typename access_traits<
  258. typename element<N, cons<HT, TT> >::type
  259. >::non_const_type
  260. get() {
  261. return boost::tuples::get<N>(*this); // delegate to non-member get
  262. }
  263. template <int N>
  264. typename access_traits<
  265. typename element<N, cons<HT, TT> >::type
  266. >::const_type
  267. get() const {
  268. return boost::tuples::get<N>(*this); // delegate to non-member get
  269. }
  270. };
  271. template <class HT>
  272. struct cons<HT, null_type> {
  273. typedef HT head_type;
  274. typedef null_type tail_type;
  275. typedef cons<HT, null_type> self_type;
  276. typedef typename
  277. detail::wrap_non_storeable_type<head_type>::type stored_head_type;
  278. stored_head_type head;
  279. typename access_traits<stored_head_type>::non_const_type
  280. get_head() { return head; }
  281. null_type get_tail() { return null_type(); }
  282. typename access_traits<stored_head_type>::const_type
  283. get_head() const { return head; }
  284. const null_type get_tail() const { return null_type(); }
  285. // cons() : head(detail::default_arg<HT>::f()) {}
  286. cons() : head() {}
  287. cons(typename access_traits<stored_head_type>::parameter_type h,
  288. const null_type& = null_type())
  289. : head (h) {}
  290. template<class T1>
  291. cons(T1& t1, const null_type&, const null_type&, const null_type&,
  292. const null_type&, const null_type&, const null_type&,
  293. const null_type&, const null_type&, const null_type&)
  294. : head (t1) {}
  295. cons(const null_type&,
  296. const null_type&, const null_type&, const null_type&,
  297. const null_type&, const null_type&, const null_type&,
  298. const null_type&, const null_type&, const null_type&)
  299. : head () {}
  300. template <class HT2>
  301. cons( const cons<HT2, null_type>& u ) : head(u.head) {}
  302. template <class HT2>
  303. cons& operator=(const cons<HT2, null_type>& u )
  304. { head = u.head; return *this; }
  305. // must define assignment operator explicitely, implicit version
  306. // is illformed if HT is a reference
  307. cons& operator=(const cons& u) { head = u.head; return *this; }
  308. template <int N>
  309. typename access_traits<
  310. typename element<N, self_type>::type
  311. >::non_const_type
  312. get() {
  313. return boost::tuples::get<N>(*this);
  314. }
  315. template <int N>
  316. typename access_traits<
  317. typename element<N, self_type>::type
  318. >::const_type
  319. get() const {
  320. return boost::tuples::get<N>(*this);
  321. }
  322. };
  323. // templates for finding out the length of the tuple -------------------
  324. template<class T>
  325. struct length {
  326. BOOST_STATIC_CONSTANT(int, value = 1 + length<typename T::tail_type>::value);
  327. };
  328. template<>
  329. struct length<tuple<> > {
  330. BOOST_STATIC_CONSTANT(int, value = 0);
  331. };
  332. template<>
  333. struct length<tuple<> const> {
  334. BOOST_STATIC_CONSTANT(int, value = 0);
  335. };
  336. template<>
  337. struct length<null_type> {
  338. BOOST_STATIC_CONSTANT(int, value = 0);
  339. };
  340. template<>
  341. struct length<null_type const> {
  342. BOOST_STATIC_CONSTANT(int, value = 0);
  343. };
  344. namespace detail {
  345. // Tuple to cons mapper --------------------------------------------------
  346. template <class T0, class T1, class T2, class T3, class T4,
  347. class T5, class T6, class T7, class T8, class T9>
  348. struct map_tuple_to_cons
  349. {
  350. typedef cons<T0,
  351. typename map_tuple_to_cons<T1, T2, T3, T4, T5,
  352. T6, T7, T8, T9, null_type>::type
  353. > type;
  354. };
  355. // The empty tuple is a null_type
  356. template <>
  357. struct map_tuple_to_cons<null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type>
  358. {
  359. typedef null_type type;
  360. };
  361. } // end detail
  362. // -------------------------------------------------------------------
  363. // -- tuple ------------------------------------------------------
  364. template <class T0, class T1, class T2, class T3, class T4,
  365. class T5, class T6, class T7, class T8, class T9>
  366. class tuple :
  367. public detail::map_tuple_to_cons<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type
  368. {
  369. public:
  370. typedef typename
  371. detail::map_tuple_to_cons<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type inherited;
  372. typedef typename inherited::head_type head_type;
  373. typedef typename inherited::tail_type tail_type;
  374. // access_traits<T>::parameter_type takes non-reference types as const T&
  375. tuple() {}
  376. explicit tuple(typename access_traits<T0>::parameter_type t0)
  377. : inherited(t0, detail::cnull(), detail::cnull(), detail::cnull(),
  378. detail::cnull(), detail::cnull(), detail::cnull(),
  379. detail::cnull(), detail::cnull(), detail::cnull()) {}
  380. tuple(typename access_traits<T0>::parameter_type t0,
  381. typename access_traits<T1>::parameter_type t1)
  382. : inherited(t0, t1, detail::cnull(), detail::cnull(),
  383. detail::cnull(), detail::cnull(), detail::cnull(),
  384. detail::cnull(), detail::cnull(), detail::cnull()) {}
  385. tuple(typename access_traits<T0>::parameter_type t0,
  386. typename access_traits<T1>::parameter_type t1,
  387. typename access_traits<T2>::parameter_type t2)
  388. : inherited(t0, t1, t2, detail::cnull(), detail::cnull(),
  389. detail::cnull(), detail::cnull(), detail::cnull(),
  390. detail::cnull(), detail::cnull()) {}
  391. tuple(typename access_traits<T0>::parameter_type t0,
  392. typename access_traits<T1>::parameter_type t1,
  393. typename access_traits<T2>::parameter_type t2,
  394. typename access_traits<T3>::parameter_type t3)
  395. : inherited(t0, t1, t2, t3, detail::cnull(), detail::cnull(),
  396. detail::cnull(), detail::cnull(), detail::cnull(),
  397. detail::cnull()) {}
  398. tuple(typename access_traits<T0>::parameter_type t0,
  399. typename access_traits<T1>::parameter_type t1,
  400. typename access_traits<T2>::parameter_type t2,
  401. typename access_traits<T3>::parameter_type t3,
  402. typename access_traits<T4>::parameter_type t4)
  403. : inherited(t0, t1, t2, t3, t4, detail::cnull(), detail::cnull(),
  404. detail::cnull(), detail::cnull(), detail::cnull()) {}
  405. tuple(typename access_traits<T0>::parameter_type t0,
  406. typename access_traits<T1>::parameter_type t1,
  407. typename access_traits<T2>::parameter_type t2,
  408. typename access_traits<T3>::parameter_type t3,
  409. typename access_traits<T4>::parameter_type t4,
  410. typename access_traits<T5>::parameter_type t5)
  411. : inherited(t0, t1, t2, t3, t4, t5, detail::cnull(), detail::cnull(),
  412. detail::cnull(), detail::cnull()) {}
  413. tuple(typename access_traits<T0>::parameter_type t0,
  414. typename access_traits<T1>::parameter_type t1,
  415. typename access_traits<T2>::parameter_type t2,
  416. typename access_traits<T3>::parameter_type t3,
  417. typename access_traits<T4>::parameter_type t4,
  418. typename access_traits<T5>::parameter_type t5,
  419. typename access_traits<T6>::parameter_type t6)
  420. : inherited(t0, t1, t2, t3, t4, t5, t6, detail::cnull(),
  421. detail::cnull(), detail::cnull()) {}
  422. tuple(typename access_traits<T0>::parameter_type t0,
  423. typename access_traits<T1>::parameter_type t1,
  424. typename access_traits<T2>::parameter_type t2,
  425. typename access_traits<T3>::parameter_type t3,
  426. typename access_traits<T4>::parameter_type t4,
  427. typename access_traits<T5>::parameter_type t5,
  428. typename access_traits<T6>::parameter_type t6,
  429. typename access_traits<T7>::parameter_type t7)
  430. : inherited(t0, t1, t2, t3, t4, t5, t6, t7, detail::cnull(),
  431. detail::cnull()) {}
  432. tuple(typename access_traits<T0>::parameter_type t0,
  433. typename access_traits<T1>::parameter_type t1,
  434. typename access_traits<T2>::parameter_type t2,
  435. typename access_traits<T3>::parameter_type t3,
  436. typename access_traits<T4>::parameter_type t4,
  437. typename access_traits<T5>::parameter_type t5,
  438. typename access_traits<T6>::parameter_type t6,
  439. typename access_traits<T7>::parameter_type t7,
  440. typename access_traits<T8>::parameter_type t8)
  441. : inherited(t0, t1, t2, t3, t4, t5, t6, t7, t8, detail::cnull()) {}
  442. tuple(typename access_traits<T0>::parameter_type t0,
  443. typename access_traits<T1>::parameter_type t1,
  444. typename access_traits<T2>::parameter_type t2,
  445. typename access_traits<T3>::parameter_type t3,
  446. typename access_traits<T4>::parameter_type t4,
  447. typename access_traits<T5>::parameter_type t5,
  448. typename access_traits<T6>::parameter_type t6,
  449. typename access_traits<T7>::parameter_type t7,
  450. typename access_traits<T8>::parameter_type t8,
  451. typename access_traits<T9>::parameter_type t9)
  452. : inherited(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9) {}
  453. template<class U1, class U2>
  454. tuple(const cons<U1, U2>& p) : inherited(p) {}
  455. template <class U1, class U2>
  456. tuple& operator=(const cons<U1, U2>& k) {
  457. inherited::operator=(k);
  458. return *this;
  459. }
  460. template <class U1, class U2>
  461. tuple& operator=(const std::pair<U1, U2>& k) {
  462. BOOST_STATIC_ASSERT(length<tuple>::value == 2);// check_length = 2
  463. this->head = k.first;
  464. this->tail.head = k.second;
  465. return *this;
  466. }
  467. };
  468. // The empty tuple
  469. template <>
  470. class tuple<null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type> :
  471. public null_type
  472. {
  473. public:
  474. typedef null_type inherited;
  475. };
  476. // Swallows any assignment (by Doug Gregor)
  477. namespace detail {
  478. struct swallow_assign;
  479. typedef void (detail::swallow_assign::*ignore_t)();
  480. struct swallow_assign {
  481. swallow_assign(ignore_t(*)(ignore_t)) {}
  482. template<typename T>
  483. swallow_assign const& operator=(const T&) const {
  484. return *this;
  485. }
  486. };
  487. } // namespace detail
  488. // "ignore" allows tuple positions to be ignored when using "tie".
  489. inline detail::ignore_t ignore(detail::ignore_t) { return 0; }
  490. // ---------------------------------------------------------------------------
  491. // The call_traits for make_tuple
  492. // Honours the reference_wrapper class.
  493. // Must be instantiated with plain or const plain types (not with references)
  494. // from template<class T> foo(const T& t) : make_tuple_traits<const T>::type
  495. // from template<class T> foo(T& t) : make_tuple_traits<T>::type
  496. // Conversions:
  497. // T -> T,
  498. // references -> compile_time_error
  499. // reference_wrapper<T> -> T&
  500. // const reference_wrapper<T> -> T&
  501. // array -> const ref array
  502. template<class T>
  503. struct make_tuple_traits {
  504. typedef T type;
  505. // commented away, see below (JJ)
  506. // typedef typename IF<
  507. // boost::is_function<T>::value,
  508. // T&,
  509. // T>::RET type;
  510. };
  511. // The is_function test was there originally for plain function types,
  512. // which can't be stored as such (we must either store them as references or
  513. // pointers). Such a type could be formed if make_tuple was called with a
  514. // reference to a function.
  515. // But this would mean that a const qualified function type was formed in
  516. // the make_tuple function and hence make_tuple can't take a function
  517. // reference as a parameter, and thus T can't be a function type.
  518. // So is_function test was removed.
  519. // (14.8.3. says that type deduction fails if a cv-qualified function type
  520. // is created. (It only applies for the case of explicitly specifying template
  521. // args, though?)) (JJ)
  522. template<class T>
  523. struct make_tuple_traits<T&> {
  524. typedef typename
  525. detail::generate_error<T&>::
  526. do_not_use_with_reference_type error;
  527. };
  528. // Arrays can't be stored as plain types; convert them to references.
  529. // All arrays are converted to const. This is because make_tuple takes its
  530. // parameters as const T& and thus the knowledge of the potential
  531. // non-constness of actual argument is lost.
  532. template<class T, int n> struct make_tuple_traits <T[n]> {
  533. typedef const T (&type)[n];
  534. };
  535. template<class T, int n>
  536. struct make_tuple_traits<const T[n]> {
  537. typedef const T (&type)[n];
  538. };
  539. template<class T, int n> struct make_tuple_traits<volatile T[n]> {
  540. typedef const volatile T (&type)[n];
  541. };
  542. template<class T, int n>
  543. struct make_tuple_traits<const volatile T[n]> {
  544. typedef const volatile T (&type)[n];
  545. };
  546. template<class T>
  547. struct make_tuple_traits<reference_wrapper<T> >{
  548. typedef T& type;
  549. };
  550. template<class T>
  551. struct make_tuple_traits<const reference_wrapper<T> >{
  552. typedef T& type;
  553. };
  554. template<>
  555. struct make_tuple_traits<detail::ignore_t(detail::ignore_t)> {
  556. typedef detail::swallow_assign type;
  557. };
  558. namespace detail {
  559. // a helper traits to make the make_tuple functions shorter (Vesa Karvonen's
  560. // suggestion)
  561. template <
  562. class T0 = null_type, class T1 = null_type, class T2 = null_type,
  563. class T3 = null_type, class T4 = null_type, class T5 = null_type,
  564. class T6 = null_type, class T7 = null_type, class T8 = null_type,
  565. class T9 = null_type
  566. >
  567. struct make_tuple_mapper {
  568. typedef
  569. tuple<typename make_tuple_traits<T0>::type,
  570. typename make_tuple_traits<T1>::type,
  571. typename make_tuple_traits<T2>::type,
  572. typename make_tuple_traits<T3>::type,
  573. typename make_tuple_traits<T4>::type,
  574. typename make_tuple_traits<T5>::type,
  575. typename make_tuple_traits<T6>::type,
  576. typename make_tuple_traits<T7>::type,
  577. typename make_tuple_traits<T8>::type,
  578. typename make_tuple_traits<T9>::type> type;
  579. };
  580. } // end detail
  581. // -make_tuple function templates -----------------------------------
  582. inline tuple<> make_tuple() {
  583. return tuple<>();
  584. }
  585. template<class T0>
  586. inline typename detail::make_tuple_mapper<T0>::type
  587. make_tuple(const T0& t0) {
  588. typedef typename detail::make_tuple_mapper<T0>::type t;
  589. return t(t0);
  590. }
  591. template<class T0, class T1>
  592. inline typename detail::make_tuple_mapper<T0, T1>::type
  593. make_tuple(const T0& t0, const T1& t1) {
  594. typedef typename detail::make_tuple_mapper<T0, T1>::type t;
  595. return t(t0, t1);
  596. }
  597. template<class T0, class T1, class T2>
  598. inline typename detail::make_tuple_mapper<T0, T1, T2>::type
  599. make_tuple(const T0& t0, const T1& t1, const T2& t2) {
  600. typedef typename detail::make_tuple_mapper<T0, T1, T2>::type t;
  601. return t(t0, t1, t2);
  602. }
  603. template<class T0, class T1, class T2, class T3>
  604. inline typename detail::make_tuple_mapper<T0, T1, T2, T3>::type
  605. make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3) {
  606. typedef typename detail::make_tuple_mapper<T0, T1, T2, T3>::type t;
  607. return t(t0, t1, t2, t3);
  608. }
  609. template<class T0, class T1, class T2, class T3, class T4>
  610. inline typename detail::make_tuple_mapper<T0, T1, T2, T3, T4>::type
  611. make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
  612. const T4& t4) {
  613. typedef typename detail::make_tuple_mapper<T0, T1, T2, T3, T4>::type t;
  614. return t(t0, t1, t2, t3, t4);
  615. }
  616. template<class T0, class T1, class T2, class T3, class T4, class T5>
  617. inline typename detail::make_tuple_mapper<T0, T1, T2, T3, T4, T5>::type
  618. make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
  619. const T4& t4, const T5& t5) {
  620. typedef typename detail::make_tuple_mapper<T0, T1, T2, T3, T4, T5>::type t;
  621. return t(t0, t1, t2, t3, t4, t5);
  622. }
  623. template<class T0, class T1, class T2, class T3, class T4, class T5, class T6>
  624. inline typename detail::make_tuple_mapper<T0, T1, T2, T3, T4, T5, T6>::type
  625. make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
  626. const T4& t4, const T5& t5, const T6& t6) {
  627. typedef typename detail::make_tuple_mapper
  628. <T0, T1, T2, T3, T4, T5, T6>::type t;
  629. return t(t0, t1, t2, t3, t4, t5, t6);
  630. }
  631. template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
  632. class T7>
  633. inline typename detail::make_tuple_mapper<T0, T1, T2, T3, T4, T5, T6, T7>::type
  634. make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
  635. const T4& t4, const T5& t5, const T6& t6, const T7& t7) {
  636. typedef typename detail::make_tuple_mapper
  637. <T0, T1, T2, T3, T4, T5, T6, T7>::type t;
  638. return t(t0, t1, t2, t3, t4, t5, t6, t7);
  639. }
  640. template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
  641. class T7, class T8>
  642. inline typename detail::make_tuple_mapper
  643. <T0, T1, T2, T3, T4, T5, T6, T7, T8>::type
  644. make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
  645. const T4& t4, const T5& t5, const T6& t6, const T7& t7,
  646. const T8& t8) {
  647. typedef typename detail::make_tuple_mapper
  648. <T0, T1, T2, T3, T4, T5, T6, T7, T8>::type t;
  649. return t(t0, t1, t2, t3, t4, t5, t6, t7, t8);
  650. }
  651. template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
  652. class T7, class T8, class T9>
  653. inline typename detail::make_tuple_mapper
  654. <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type
  655. make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
  656. const T4& t4, const T5& t5, const T6& t6, const T7& t7,
  657. const T8& t8, const T9& t9) {
  658. typedef typename detail::make_tuple_mapper
  659. <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type t;
  660. return t(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9);
  661. }
  662. namespace detail {
  663. template<class T>
  664. struct tie_traits {
  665. typedef T& type;
  666. };
  667. template<>
  668. struct tie_traits<ignore_t(ignore_t)> {
  669. typedef swallow_assign type;
  670. };
  671. template<>
  672. struct tie_traits<void> {
  673. typedef null_type type;
  674. };
  675. template <
  676. class T0 = void, class T1 = void, class T2 = void,
  677. class T3 = void, class T4 = void, class T5 = void,
  678. class T6 = void, class T7 = void, class T8 = void,
  679. class T9 = void
  680. >
  681. struct tie_mapper {
  682. typedef
  683. tuple<typename tie_traits<T0>::type,
  684. typename tie_traits<T1>::type,
  685. typename tie_traits<T2>::type,
  686. typename tie_traits<T3>::type,
  687. typename tie_traits<T4>::type,
  688. typename tie_traits<T5>::type,
  689. typename tie_traits<T6>::type,
  690. typename tie_traits<T7>::type,
  691. typename tie_traits<T8>::type,
  692. typename tie_traits<T9>::type> type;
  693. };
  694. }
  695. // Tie function templates -------------------------------------------------
  696. template<class T0>
  697. inline typename detail::tie_mapper<T0>::type
  698. tie(T0& t0) {
  699. typedef typename detail::tie_mapper<T0>::type t;
  700. return t(t0);
  701. }
  702. template<class T0, class T1>
  703. inline typename detail::tie_mapper<T0, T1>::type
  704. tie(T0& t0, T1& t1) {
  705. typedef typename detail::tie_mapper<T0, T1>::type t;
  706. return t(t0, t1);
  707. }
  708. template<class T0, class T1, class T2>
  709. inline typename detail::tie_mapper<T0, T1, T2>::type
  710. tie(T0& t0, T1& t1, T2& t2) {
  711. typedef typename detail::tie_mapper<T0, T1, T2>::type t;
  712. return t(t0, t1, t2);
  713. }
  714. template<class T0, class T1, class T2, class T3>
  715. inline typename detail::tie_mapper<T0, T1, T2, T3>::type
  716. tie(T0& t0, T1& t1, T2& t2, T3& t3) {
  717. typedef typename detail::tie_mapper<T0, T1, T2, T3>::type t;
  718. return t(t0, t1, t2, t3);
  719. }
  720. template<class T0, class T1, class T2, class T3, class T4>
  721. inline typename detail::tie_mapper<T0, T1, T2, T3, T4>::type
  722. tie(T0& t0, T1& t1, T2& t2, T3& t3,
  723. T4& t4) {
  724. typedef typename detail::tie_mapper<T0, T1, T2, T3, T4>::type t;
  725. return t(t0, t1, t2, t3, t4);
  726. }
  727. template<class T0, class T1, class T2, class T3, class T4, class T5>
  728. inline typename detail::tie_mapper<T0, T1, T2, T3, T4, T5>::type
  729. tie(T0& t0, T1& t1, T2& t2, T3& t3,
  730. T4& t4, T5& t5) {
  731. typedef typename detail::tie_mapper<T0, T1, T2, T3, T4, T5>::type t;
  732. return t(t0, t1, t2, t3, t4, t5);
  733. }
  734. template<class T0, class T1, class T2, class T3, class T4, class T5, class T6>
  735. inline typename detail::tie_mapper<T0, T1, T2, T3, T4, T5, T6>::type
  736. tie(T0& t0, T1& t1, T2& t2, T3& t3,
  737. T4& t4, T5& t5, T6& t6) {
  738. typedef typename detail::tie_mapper
  739. <T0, T1, T2, T3, T4, T5, T6>::type t;
  740. return t(t0, t1, t2, t3, t4, t5, t6);
  741. }
  742. template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
  743. class T7>
  744. inline typename detail::tie_mapper<T0, T1, T2, T3, T4, T5, T6, T7>::type
  745. tie(T0& t0, T1& t1, T2& t2, T3& t3,
  746. T4& t4, T5& t5, T6& t6, T7& t7) {
  747. typedef typename detail::tie_mapper
  748. <T0, T1, T2, T3, T4, T5, T6, T7>::type t;
  749. return t(t0, t1, t2, t3, t4, t5, t6, t7);
  750. }
  751. template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
  752. class T7, class T8>
  753. inline typename detail::tie_mapper
  754. <T0, T1, T2, T3, T4, T5, T6, T7, T8>::type
  755. tie(T0& t0, T1& t1, T2& t2, T3& t3,
  756. T4& t4, T5& t5, T6& t6, T7& t7,
  757. T8& t8) {
  758. typedef typename detail::tie_mapper
  759. <T0, T1, T2, T3, T4, T5, T6, T7, T8>::type t;
  760. return t(t0, t1, t2, t3, t4, t5, t6, t7, t8);
  761. }
  762. template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
  763. class T7, class T8, class T9>
  764. inline typename detail::tie_mapper
  765. <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type
  766. tie(T0& t0, T1& t1, T2& t2, T3& t3,
  767. T4& t4, T5& t5, T6& t6, T7& t7,
  768. T8& t8, T9& t9) {
  769. typedef typename detail::tie_mapper
  770. <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type t;
  771. return t(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9);
  772. }
  773. template <class T0, class T1, class T2, class T3, class T4,
  774. class T5, class T6, class T7, class T8, class T9>
  775. void swap(tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& lhs,
  776. tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& rhs);
  777. inline void swap(null_type&, null_type&) {}
  778. template<class HH>
  779. inline void swap(cons<HH, null_type>& lhs, cons<HH, null_type>& rhs) {
  780. ::boost::swap(lhs.head, rhs.head);
  781. }
  782. template<class HH, class TT>
  783. inline void swap(cons<HH, TT>& lhs, cons<HH, TT>& rhs) {
  784. ::boost::swap(lhs.head, rhs.head);
  785. ::boost::tuples::swap(lhs.tail, rhs.tail);
  786. }
  787. template <class T0, class T1, class T2, class T3, class T4,
  788. class T5, class T6, class T7, class T8, class T9>
  789. inline void swap(tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& lhs,
  790. tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& rhs) {
  791. typedef tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> tuple_type;
  792. typedef typename tuple_type::inherited base;
  793. ::boost::tuples::swap(static_cast<base&>(lhs), static_cast<base&>(rhs));
  794. }
  795. } // end of namespace tuples
  796. } // end of namespace boost
  797. #if defined(BOOST_GCC) && (BOOST_GCC >= 40700)
  798. #pragma GCC diagnostic pop
  799. #endif
  800. #endif // BOOST_TUPLE_BASIC_HPP