cons.hpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // cons.hpp
  3. //
  4. // Copyright 2008 Eric Niebler. Distributed under the Boost
  5. // Software License, Version 1.0. (See accompanying file
  6. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. #ifndef BOOST_XPRESSIVE_DETAIL_UTILITY_CONS_HPP_EAN_11_19_2005
  8. #define BOOST_XPRESSIVE_DETAIL_UTILITY_CONS_HPP_EAN_11_19_2005
  9. #include <boost/version.hpp>
  10. #if BOOST_VERSION >= 103300
  11. // In Boost 1.33+, we have a cons list in Fusion, so just include it.
  12. # if BOOST_VERSION >= 103500
  13. # include <boost/fusion/include/cons.hpp> // Boost 1.35+ has Fusion2
  14. # else
  15. # include <boost/spirit/fusion/sequence/cons.hpp> // Fusion1
  16. # endif
  17. #else
  18. // For earlier versions of Boost, put the definition of cons here
  19. # include <boost/call_traits.hpp>
  20. # include <boost/mpl/if.hpp>
  21. # include <boost/mpl/eval_if.hpp>
  22. # include <boost/mpl/identity.hpp>
  23. # include <boost/type_traits/is_const.hpp>
  24. # include <boost/type_traits/add_const.hpp>
  25. # include <boost/type_traits/add_reference.hpp>
  26. # include <boost/spirit/fusion/detail/config.hpp>
  27. # include <boost/spirit/fusion/detail/access.hpp>
  28. # include <boost/spirit/fusion/iterator/next.hpp>
  29. # include <boost/spirit/fusion/iterator/equal_to.hpp>
  30. # include <boost/spirit/fusion/iterator/as_fusion_iterator.hpp>
  31. # include <boost/spirit/fusion/iterator/detail/iterator_base.hpp>
  32. # include <boost/spirit/fusion/sequence/begin.hpp>
  33. # include <boost/spirit/fusion/sequence/end.hpp>
  34. # include <boost/spirit/fusion/sequence/as_fusion_sequence.hpp>
  35. # include <boost/spirit/fusion/sequence/detail/sequence_base.hpp>
  36. namespace boost { namespace fusion
  37. {
  38. struct nil;
  39. struct cons_tag;
  40. template <typename Car, typename Cdr>
  41. struct cons;
  42. struct cons_iterator_tag;
  43. template <typename Cons>
  44. struct cons_iterator;
  45. namespace cons_detail
  46. {
  47. template <typename Iterator>
  48. struct deref_traits_impl
  49. {
  50. typedef typename Iterator::cons_type cons_type;
  51. typedef typename cons_type::car_type value_type;
  52. typedef typename mpl::eval_if<
  53. is_const<cons_type>
  54. , add_reference<typename add_const<value_type>::type>
  55. , add_reference<value_type> >::type
  56. type;
  57. static type
  58. call(Iterator const& i)
  59. {
  60. return detail::ref(i.cons.car);
  61. }
  62. };
  63. template <typename Iterator>
  64. struct next_traits_impl
  65. {
  66. typedef typename Iterator::cons_type cons_type;
  67. typedef typename cons_type::cdr_type cdr_type;
  68. typedef cons_iterator<
  69. typename mpl::eval_if<
  70. is_const<cons_type>
  71. , add_const<cdr_type>
  72. , mpl::identity<cdr_type>
  73. >::type>
  74. type;
  75. static type
  76. call(Iterator const& i)
  77. {
  78. return type(detail::ref(i.cons.cdr));
  79. }
  80. };
  81. template <typename Iterator>
  82. struct value_traits_impl
  83. {
  84. typedef typename Iterator::cons_type cons_type;
  85. typedef typename cons_type::car_type type;
  86. };
  87. template <typename Cons>
  88. struct begin_traits_impl
  89. {
  90. typedef cons_iterator<Cons> type;
  91. static type
  92. call(Cons& t)
  93. {
  94. return type(t);
  95. }
  96. };
  97. template <typename Cons>
  98. struct end_traits_impl
  99. {
  100. typedef cons_iterator<
  101. typename mpl::if_<is_const<Cons>, nil const, nil>::type>
  102. type;
  103. static type
  104. call(Cons& t)
  105. {
  106. FUSION_RETURN_DEFAULT_CONSTRUCTED;
  107. }
  108. };
  109. } // namespace cons_detail
  110. namespace meta
  111. {
  112. template <typename Tag>
  113. struct deref_impl;
  114. template <>
  115. struct deref_impl<cons_iterator_tag>
  116. {
  117. template <typename Iterator>
  118. struct apply : cons_detail::deref_traits_impl<Iterator> {};
  119. };
  120. template <typename Tag>
  121. struct next_impl;
  122. template <>
  123. struct next_impl<cons_iterator_tag>
  124. {
  125. template <typename Iterator>
  126. struct apply : cons_detail::next_traits_impl<Iterator> {};
  127. };
  128. template <typename Tag>
  129. struct value_impl;
  130. template <>
  131. struct value_impl<cons_iterator_tag>
  132. {
  133. template <typename Iterator>
  134. struct apply : cons_detail::value_traits_impl<Iterator> {};
  135. };
  136. template <typename Tag>
  137. struct begin_impl;
  138. template <>
  139. struct begin_impl<cons_tag>
  140. {
  141. template <typename Sequence>
  142. struct apply : cons_detail::begin_traits_impl<Sequence>
  143. {};
  144. };
  145. template <typename Tag>
  146. struct end_impl;
  147. template <>
  148. struct end_impl<cons_tag>
  149. {
  150. template <typename Sequence>
  151. struct apply : cons_detail::end_traits_impl<Sequence>
  152. {};
  153. };
  154. } // namespace meta
  155. template <typename Cons = nil>
  156. struct cons_iterator : iterator_base<cons_iterator<Cons> >
  157. {
  158. typedef cons_iterator_tag tag;
  159. typedef Cons cons_type;
  160. explicit cons_iterator(cons_type& cons_)
  161. : cons(cons_) {}
  162. cons_type& cons;
  163. };
  164. template <>
  165. struct cons_iterator<nil> : iterator_base<cons_iterator<nil> >
  166. {
  167. typedef cons_iterator_tag tag;
  168. typedef nil cons_type;
  169. cons_iterator() {}
  170. explicit cons_iterator(nil const&) {}
  171. };
  172. template <>
  173. struct cons_iterator<nil const> : iterator_base<cons_iterator<nil const> >
  174. {
  175. typedef cons_iterator_tag tag;
  176. typedef nil const cons_type;
  177. cons_iterator() {}
  178. explicit cons_iterator(nil const&) {}
  179. };
  180. struct nil : sequence_base<nil>
  181. {
  182. typedef cons_tag tag;
  183. typedef void_t car_type;
  184. typedef void_t cdr_type;
  185. };
  186. template <typename Car, typename Cdr = nil>
  187. struct cons : sequence_base<cons<Car,Cdr> >
  188. {
  189. typedef cons_tag tag;
  190. typedef typename call_traits<Car>::value_type car_type;
  191. typedef Cdr cdr_type;
  192. cons()
  193. : car(), cdr() {}
  194. explicit cons(
  195. typename call_traits<Car>::param_type car_
  196. , typename call_traits<Cdr>::param_type cdr_ = Cdr())
  197. : car(car_), cdr(cdr_) {}
  198. car_type car;
  199. cdr_type cdr;
  200. };
  201. template <typename Car>
  202. inline cons<Car>
  203. make_cons(Car const& car)
  204. {
  205. return cons<Car>(car);
  206. }
  207. template <typename Car, typename Cdr>
  208. inline cons<Car, Cdr>
  209. make_cons(Car const& car, Cdr const& cdr)
  210. {
  211. return cons<Car, Cdr>(car, cdr);
  212. }
  213. }} // namespace boost::fusion
  214. namespace boost { namespace mpl
  215. {
  216. template <typename Tag>
  217. struct begin_impl;
  218. template <typename Tag>
  219. struct end_impl;
  220. template <>
  221. struct begin_impl<fusion::cons_tag>
  222. : fusion::meta::begin_impl<fusion::cons_tag>
  223. {
  224. };
  225. template <>
  226. struct end_impl<fusion::cons_tag>
  227. : fusion::meta::end_impl<fusion::cons_tag>
  228. {
  229. };
  230. }} // namespace boost::mpl
  231. #endif
  232. // Before Boost v1.33.1, Fusion cons lists were not valid MPL sequences.
  233. #if BOOST_VERSION < 103301
  234. namespace boost { namespace mpl
  235. {
  236. template<typename Iterator>
  237. struct next;
  238. template<typename Cons>
  239. struct next<fusion::cons_iterator<Cons> >
  240. : fusion::cons_detail::next_traits_impl<fusion::cons_iterator<Cons> >
  241. {
  242. };
  243. template<typename Iterator>
  244. struct deref;
  245. template<typename Cons>
  246. struct deref<fusion::cons_iterator<Cons> >
  247. : fusion::cons_detail::value_traits_impl<fusion::cons_iterator<Cons> >
  248. {
  249. };
  250. }} // namespace boost::mpl
  251. #endif
  252. #endif