/src/contrib/boost/spirit/home/support/make_component.hpp

http://pythonocc.googlecode.com/ · C++ Header · 364 lines · 296 code · 52 blank · 16 comment · 0 complexity · c8894e15238d50a6e1e8e0a513ffb29c MD5 · raw file

  1. /*=============================================================================
  2. Copyright (c) 2001-2010 Joel de Guzman
  3. http://spirit.sourceforge.net/
  4. Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. =============================================================================*/
  7. #ifndef BOOST_SPIRIT_MAKE_COMPONENT_OCTOBER_16_2008_1250PM
  8. #define BOOST_SPIRIT_MAKE_COMPONENT_OCTOBER_16_2008_1250PM
  9. #if defined(_MSC_VER)
  10. #pragma once
  11. #endif
  12. #include <boost/proto/proto.hpp>
  13. #include <boost/spirit/home/support/detail/make_cons.hpp>
  14. #include <boost/spirit/home/support/modify.hpp>
  15. namespace boost { namespace spirit
  16. {
  17. // There is no real "component" class. Each domain is responsible
  18. // for creating its own components. You need to specialize this for
  19. // each component in your domain. Use this as a guide.
  20. template <typename Domain, typename Tag, typename Enable = void>
  21. struct make_component
  22. {
  23. template <typename Sig>
  24. struct result;
  25. template <typename This, typename Elements, typename Modifiers>
  26. struct result<This(Elements, Modifiers)>;
  27. template <typename Elements, typename Modifiers>
  28. typename result<make_component(Elements, Modifiers)>::type
  29. operator()(Elements const& elements, Modifiers const& modifiers) const;
  30. };
  31. namespace tag
  32. {
  33. // Normally, we use proto tags as-is to distinguish operators.
  34. // The special case is proto::tag::subscript. Spirit uses this
  35. // as either sementic actions or directives. To distinguish between
  36. // the two, we use these special tags below.
  37. struct directive;
  38. struct action;
  39. }
  40. template <typename Domain, typename T, typename Enable = void>
  41. struct flatten_tree;
  42. }}
  43. namespace boost { namespace spirit { namespace detail
  44. {
  45. template <typename Domain>
  46. struct make_terminal : proto::transform<make_terminal<Domain> >
  47. {
  48. template<typename Expr, typename State, typename Data>
  49. struct impl : proto::transform_impl<Expr, State, Data>
  50. {
  51. typedef typename
  52. proto::result_of::value<Expr>::type
  53. value;
  54. typedef typename result_of::make_cons<value>::type elements;
  55. typedef
  56. make_component<Domain, proto::tag::terminal>
  57. make_component_;
  58. typedef typename
  59. make_component_::template
  60. result<make_component_(elements, Data)>::type
  61. result_type;
  62. result_type operator()(
  63. typename impl::expr_param expr
  64. , typename impl::state_param /*state*/
  65. , typename impl::data_param data
  66. ) const
  67. {
  68. return typename impl::make_component_()(
  69. detail::make_cons(proto::value(expr))
  70. , data
  71. );
  72. }
  73. };
  74. };
  75. template <typename Domain, typename Tag, typename Grammar>
  76. struct make_unary : proto::transform<make_unary<Domain, Tag, Grammar> >
  77. {
  78. template<typename Expr, typename State, typename Data>
  79. struct impl : proto::transform_impl<Expr, State, Data>
  80. {
  81. typedef typename
  82. proto::result_of::child_c<Expr, 0>::type
  83. child;
  84. typedef typename Grammar::
  85. template result<Grammar(child, State, Data)>::type
  86. child_component;
  87. typedef typename
  88. result_of::make_cons<child_component>::type
  89. elements;
  90. typedef make_component<Domain, Tag> make_component_;
  91. typedef typename
  92. make_component_::template
  93. result<make_component_(elements, Data)>::type
  94. result_type;
  95. result_type operator()(
  96. typename impl::expr_param expr
  97. , typename impl::state_param state
  98. , typename impl::data_param data
  99. ) const
  100. {
  101. return typename impl::make_component_()(
  102. detail::make_cons(
  103. Grammar()(proto::child(expr), state, data))
  104. , data
  105. );
  106. }
  107. };
  108. };
  109. // un-flattened version
  110. template <typename Domain, typename Tag, typename Grammar,
  111. bool flatten = flatten_tree<Domain, Tag>::value>
  112. struct make_binary
  113. {
  114. template<typename Expr, typename State, typename Data>
  115. struct impl : proto::transform_impl<Expr, State, Data>
  116. {
  117. typedef typename Grammar::
  118. template result<Grammar(
  119. typename proto::result_of::child_c<Expr, 0>::type
  120. , State, Data)>::type
  121. lhs_component;
  122. typedef typename Grammar::
  123. template result<Grammar(
  124. typename proto::result_of::child_c<Expr, 1>::type
  125. , State, Data)>::type
  126. rhs_component;
  127. typedef typename
  128. result_of::make_cons<
  129. lhs_component
  130. , typename result_of::make_cons<rhs_component>::type
  131. >::type
  132. elements_type;
  133. typedef make_component<Domain, Tag> make_component_;
  134. typedef typename
  135. make_component_::template
  136. result<make_component_(elements_type, Data)>::type
  137. result_type;
  138. result_type operator()(
  139. typename impl::expr_param expr
  140. , typename impl::state_param state
  141. , typename impl::data_param data
  142. ) const
  143. {
  144. elements_type elements =
  145. detail::make_cons(
  146. Grammar()(
  147. proto::child_c<0>(expr), state, data) // LHS
  148. , detail::make_cons(
  149. Grammar()(
  150. proto::child_c<1>(expr), state, data) // RHS
  151. )
  152. );
  153. return make_component_()(elements, data);
  154. }
  155. };
  156. };
  157. template <typename Grammar>
  158. struct make_binary_helper : proto::transform<make_binary_helper<Grammar> >
  159. {
  160. template<typename Expr, typename State, typename Data>
  161. struct impl : proto::transform_impl<Expr, State, Data>
  162. {
  163. typedef typename Grammar::
  164. template result<Grammar(Expr, State, Data)>::type
  165. lhs;
  166. typedef typename result_of::make_cons<lhs, State>::type result_type;
  167. result_type operator()(
  168. typename impl::expr_param expr
  169. , typename impl::state_param state
  170. , typename impl::data_param data
  171. ) const
  172. {
  173. return detail::make_cons(Grammar()(expr, state, data), state);
  174. }
  175. };
  176. };
  177. // Flattened version
  178. template <typename Domain, typename Tag, typename Grammar>
  179. struct make_binary<Domain, Tag, Grammar, true>
  180. : proto::transform<make_binary<Domain, Tag, Grammar> >
  181. {
  182. template<typename Expr, typename State, typename Data>
  183. struct impl : proto::transform_impl<Expr, State, Data>
  184. {
  185. typedef typename
  186. proto::reverse_fold_tree<
  187. proto::_
  188. , proto::make<fusion::nil>
  189. , make_binary_helper<Grammar>
  190. >::template impl<Expr, State, Data>
  191. reverse_fold_tree;
  192. typedef typename reverse_fold_tree::result_type elements;
  193. typedef make_component<Domain, Tag> make_component_;
  194. typedef typename
  195. make_component_::template
  196. result<make_component_(elements, Data)>::type
  197. result_type;
  198. result_type operator()(
  199. typename impl::expr_param expr
  200. , typename impl::state_param state
  201. , typename impl::data_param data
  202. ) const
  203. {
  204. return make_component_()(
  205. reverse_fold_tree()(expr, state, data), data);
  206. }
  207. };
  208. };
  209. template <typename Domain, typename Grammar>
  210. struct make_directive : proto::transform<make_directive<Domain, Grammar> >
  211. {
  212. template<typename Expr, typename State, typename Data>
  213. struct impl : proto::transform_impl<Expr, State, Data>
  214. {
  215. typedef typename
  216. proto::result_of::child_c<Expr, 0>::type
  217. lhs;
  218. typedef typename
  219. proto::result_of::value<lhs>::type
  220. tag_type;
  221. typedef typename modify<Domain>::
  222. template result<modify<Domain>(tag_type, Data)>::type
  223. modifier_type;
  224. typedef typename Grammar::
  225. template result<Grammar(
  226. typename proto::result_of::child_c<Expr, 1>::type
  227. , State
  228. , modifier_type
  229. )>::type
  230. rhs_component;
  231. typedef typename
  232. result_of::make_cons<
  233. tag_type
  234. , typename result_of::make_cons<rhs_component>::type
  235. >::type
  236. elements_type;
  237. typedef make_component<Domain, tag::directive> make_component_;
  238. typedef typename
  239. make_component_::template
  240. result<make_component_(elements_type, Data)>::type
  241. result_type;
  242. result_type operator()(
  243. typename impl::expr_param expr
  244. , typename impl::state_param state
  245. , typename impl::data_param data
  246. ) const
  247. {
  248. tag_type tag = proto::value(proto::child_c<0>(expr));
  249. typename remove_reference<modifier_type>::type
  250. modifier = modify<Domain>()(tag, data);
  251. elements_type elements =
  252. detail::make_cons(
  253. tag // LHS
  254. , detail::make_cons(
  255. Grammar()(
  256. proto::child_c<1>(expr) // RHS
  257. , state, modifier)
  258. )
  259. );
  260. return make_component_()(elements, data);
  261. }
  262. };
  263. };
  264. template <typename Domain, typename Grammar>
  265. struct make_action : proto::transform<make_action<Domain, Grammar> >
  266. {
  267. template<typename Expr, typename State, typename Data>
  268. struct impl : proto::transform_impl<Expr, State, Data>
  269. {
  270. typedef typename Grammar::
  271. template result<Grammar(
  272. typename proto::result_of::child_c<Expr, 0>::type
  273. , State
  274. , Data
  275. )>::type
  276. lhs_component;
  277. typedef typename
  278. proto::result_of::value<
  279. typename proto::result_of::child_c<Expr, 1>::type
  280. >::type
  281. rhs_component;
  282. typedef typename
  283. result_of::make_cons<
  284. lhs_component
  285. , typename result_of::make_cons<rhs_component>::type
  286. >::type
  287. elements_type;
  288. typedef make_component<Domain, tag::action> make_component_;
  289. typedef typename
  290. make_component_::template
  291. result<make_component_(elements_type, Data)>::type
  292. result_type;
  293. result_type operator()(
  294. typename impl::expr_param expr
  295. , typename impl::state_param state
  296. , typename impl::data_param data
  297. ) const
  298. {
  299. elements_type elements =
  300. detail::make_cons(
  301. Grammar()(
  302. proto::child_c<0>(expr), state, data) // LHS
  303. , detail::make_cons(
  304. proto::value(proto::child_c<1>(expr))) // RHS
  305. );
  306. return make_component_()(elements, data);
  307. }
  308. };
  309. };
  310. }}}
  311. #endif