impl.hpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. ///////////////////////////////////////////////////////////////////////////////
  2. /// \file impl.hpp
  3. /// Contains definition of transform<> and transform_impl<> helpers.
  4. //
  5. // Copyright 2008 Eric Niebler. Distributed under the Boost
  6. // Software License, Version 1.0. (See accompanying file
  7. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  8. #ifndef BOOST_PROTO_TRANSFORM_IMPL_HPP_EAN_04_03_2008
  9. #define BOOST_PROTO_TRANSFORM_IMPL_HPP_EAN_04_03_2008
  10. #include <boost/config.hpp>
  11. #include <boost/mpl/bool.hpp>
  12. #include <boost/type_traits/add_const.hpp>
  13. #include <boost/type_traits/add_reference.hpp>
  14. #include <boost/proto/proto_fwd.hpp>
  15. #include <boost/proto/detail/any.hpp>
  16. #include <boost/proto/detail/static_const.hpp>
  17. #if defined(_MSC_VER)
  18. # pragma warning(push)
  19. # pragma warning(disable : 4714) // function 'xxx' marked as __forceinline not inlined
  20. #endif
  21. namespace boost { namespace proto
  22. {
  23. namespace envns_
  24. {
  25. ////////////////////////////////////////////////////////////////////////////////////////////
  26. struct key_not_found
  27. {};
  28. ////////////////////////////////////////////////////////////////////////////////////////////
  29. // empty_env
  30. struct empty_env
  31. {
  32. typedef void proto_environment_;
  33. template<typename OtherTag, typename OtherValue = key_not_found>
  34. struct lookup
  35. {
  36. typedef OtherValue type;
  37. typedef
  38. typename add_reference<typename add_const<OtherValue>::type>::type
  39. const_reference;
  40. };
  41. key_not_found operator[](detail::any) const
  42. {
  43. return key_not_found();
  44. }
  45. template<typename T>
  46. T const &at(detail::any, T const &t) const
  47. {
  48. return t;
  49. }
  50. };
  51. }
  52. ////////////////////////////////////////////////////////////////////////////////////////////
  53. // is_env
  54. template<typename T, typename Void>
  55. struct is_env
  56. : mpl::false_
  57. {};
  58. template<typename T>
  59. struct is_env<T, typename T::proto_environment_>
  60. : mpl::true_
  61. {};
  62. template<typename T>
  63. struct is_env<T &, void>
  64. : is_env<T>
  65. {};
  66. #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES
  67. /// INTERNAL ONLY
  68. ///
  69. #define BOOST_PROTO_TRANSFORM_(PrimitiveTransform, X) \
  70. BOOST_PROTO_CALLABLE() \
  71. typedef X proto_is_transform_; \
  72. typedef PrimitiveTransform transform_type; \
  73. \
  74. template<typename Sig> \
  75. struct result \
  76. { \
  77. typedef typename boost::proto::detail::apply_transform<Sig>::result_type type; \
  78. }; \
  79. \
  80. template<typename Expr> \
  81. BOOST_FORCEINLINE \
  82. typename boost::proto::detail::apply_transform<transform_type(Expr &)>::result_type \
  83. operator ()(Expr &e) const \
  84. { \
  85. boost::proto::empty_state s = 0; \
  86. boost::proto::empty_env d; \
  87. return boost::proto::detail::apply_transform<transform_type(Expr &)>()(e, s, d); \
  88. } \
  89. \
  90. template<typename Expr> \
  91. BOOST_FORCEINLINE \
  92. typename boost::proto::detail::apply_transform<transform_type(Expr const &)>::result_type \
  93. operator ()(Expr const &e) const \
  94. { \
  95. boost::proto::empty_state s = 0; \
  96. boost::proto::empty_env d; \
  97. return boost::proto::detail::apply_transform<transform_type(Expr const &)>()(e, s, d); \
  98. } \
  99. \
  100. template<typename Expr, typename State> \
  101. BOOST_FORCEINLINE \
  102. typename boost::proto::detail::apply_transform<transform_type(Expr &, State &)>::result_type \
  103. operator ()(Expr &e, State &s) const \
  104. { \
  105. boost::proto::empty_env d; \
  106. return boost::proto::detail::apply_transform<transform_type(Expr &, State &)>()(e, s, d); \
  107. } \
  108. \
  109. template<typename Expr, typename State> \
  110. BOOST_FORCEINLINE \
  111. typename boost::proto::detail::apply_transform<transform_type(Expr const &, State &)>::result_type \
  112. operator ()(Expr const &e, State &s) const \
  113. { \
  114. boost::proto::empty_env d; \
  115. return boost::proto::detail::apply_transform<transform_type(Expr const &, State &)>()(e, s, d); \
  116. } \
  117. \
  118. template<typename Expr, typename State> \
  119. BOOST_FORCEINLINE \
  120. typename boost::proto::detail::apply_transform<transform_type(Expr &, State const &)>::result_type \
  121. operator ()(Expr &e, State const &s) const \
  122. { \
  123. boost::proto::empty_env d; \
  124. return boost::proto::detail::apply_transform<transform_type(Expr &, State const &)>()(e, s, d); \
  125. } \
  126. \
  127. template<typename Expr, typename State> \
  128. BOOST_FORCEINLINE \
  129. typename boost::proto::detail::apply_transform<transform_type(Expr const &, State const &)>::result_type \
  130. operator ()(Expr const &e, State const &s) const \
  131. { \
  132. boost::proto::empty_env d; \
  133. return boost::proto::detail::apply_transform<transform_type(Expr const &, State const &)>()(e, s, d); \
  134. } \
  135. \
  136. template<typename Expr, typename State, typename Data> \
  137. BOOST_FORCEINLINE \
  138. typename boost::proto::detail::apply_transform<transform_type(Expr &, State &, Data &)>::result_type \
  139. operator ()(Expr &e, State &s, Data &d) const \
  140. { \
  141. return boost::proto::detail::apply_transform<transform_type(Expr &, State &, Data &)>()(e, s, d); \
  142. } \
  143. \
  144. template<typename Expr, typename State, typename Data> \
  145. BOOST_FORCEINLINE \
  146. typename boost::proto::detail::apply_transform<transform_type(Expr const &, State &, Data &)>::result_type \
  147. operator ()(Expr const &e, State &s, Data &d) const \
  148. { \
  149. return boost::proto::detail::apply_transform<transform_type(Expr const &, State &, Data &)>()(e, s, d); \
  150. } \
  151. \
  152. template<typename Expr, typename State, typename Data> \
  153. BOOST_FORCEINLINE \
  154. typename boost::proto::detail::apply_transform<transform_type(Expr &, State const &, Data &)>::result_type \
  155. operator ()(Expr &e, State const &s, Data &d) const \
  156. { \
  157. return boost::proto::detail::apply_transform<transform_type(Expr &, State const &, Data &)>()(e, s, d); \
  158. } \
  159. \
  160. template<typename Expr, typename State, typename Data> \
  161. BOOST_FORCEINLINE \
  162. typename boost::proto::detail::apply_transform<transform_type(Expr const &, State const &, Data &)>::result_type \
  163. operator ()(Expr const &e, State const &s, Data &d) const \
  164. { \
  165. return boost::proto::detail::apply_transform<transform_type(Expr const &, State const &, Data &)>()(e, s, d); \
  166. } \
  167. /**/
  168. #else
  169. /// INTERNAL ONLY
  170. ///
  171. #define BOOST_PROTO_TRANSFORM_(PrimitiveTransform, X) \
  172. BOOST_PROTO_CALLABLE() \
  173. typedef X proto_is_transform_; \
  174. typedef PrimitiveTransform transform_type; \
  175. \
  176. template<typename Sig> \
  177. struct result \
  178. { \
  179. typedef typename boost::proto::detail::apply_transform<Sig>::result_type type; \
  180. }; \
  181. \
  182. template<typename Expr> \
  183. BOOST_FORCEINLINE \
  184. typename boost::proto::detail::apply_transform<transform_type(Expr const &)>::result_type \
  185. operator ()(Expr &&e) const \
  186. { \
  187. boost::proto::empty_state s = 0; \
  188. boost::proto::empty_env d; \
  189. return boost::proto::detail::apply_transform<transform_type(Expr const &)>()(e, s, d); \
  190. } \
  191. \
  192. template<typename Expr, typename State> \
  193. BOOST_FORCEINLINE \
  194. typename boost::proto::detail::apply_transform<transform_type(Expr const &, State const &)>::result_type \
  195. operator ()(Expr &&e, State &&s) const \
  196. { \
  197. boost::proto::empty_env d; \
  198. return boost::proto::detail::apply_transform<transform_type(Expr const &, State const &)>()(e, s, d); \
  199. } \
  200. \
  201. template<typename Expr, typename State, typename Data> \
  202. BOOST_FORCEINLINE \
  203. typename boost::proto::detail::apply_transform<transform_type(Expr const &, State const &, Data const &)>::result_type \
  204. operator ()(Expr &&e, State &&s, Data &&d) const \
  205. { \
  206. return boost::proto::detail::apply_transform<transform_type(Expr const &, State const &, Data const &)>()(e, s, d); \
  207. } \
  208. /**/
  209. #endif
  210. #define BOOST_PROTO_TRANSFORM(PrimitiveTransform) \
  211. BOOST_PROTO_TRANSFORM_(PrimitiveTransform, void) \
  212. /**/
  213. namespace detail
  214. {
  215. template<typename Sig>
  216. struct apply_transform;
  217. template<typename PrimitiveTransform, typename Expr>
  218. struct apply_transform<PrimitiveTransform(Expr)>
  219. : PrimitiveTransform::template impl<Expr, empty_state, empty_env>
  220. {};
  221. template<typename PrimitiveTransform, typename Expr, typename State>
  222. struct apply_transform<PrimitiveTransform(Expr, State)>
  223. : PrimitiveTransform::template impl<Expr, State, empty_env>
  224. {};
  225. template<typename PrimitiveTransform, typename Expr, typename State, typename Data>
  226. struct apply_transform<PrimitiveTransform(Expr, State, Data)>
  227. : PrimitiveTransform::template impl<Expr, State, Data>
  228. {};
  229. }
  230. template<typename PrimitiveTransform, typename X>
  231. struct transform
  232. {
  233. BOOST_PROTO_TRANSFORM_(PrimitiveTransform, X)
  234. };
  235. template<typename Expr, typename State, typename Data>
  236. struct transform_impl
  237. {
  238. typedef Expr const expr;
  239. typedef Expr const &expr_param;
  240. typedef State const state;
  241. typedef State const &state_param;
  242. typedef Data const data;
  243. typedef Data const &data_param;
  244. };
  245. template<typename Expr, typename State, typename Data>
  246. struct transform_impl<Expr &, State, Data>
  247. {
  248. typedef Expr expr;
  249. typedef Expr &expr_param;
  250. typedef State const state;
  251. typedef State const &state_param;
  252. typedef Data const data;
  253. typedef Data const &data_param;
  254. };
  255. template<typename Expr, typename State, typename Data>
  256. struct transform_impl<Expr, State &, Data>
  257. {
  258. typedef Expr const expr;
  259. typedef Expr const &expr_param;
  260. typedef State state;
  261. typedef State &state_param;
  262. typedef Data const data;
  263. typedef Data const &data_param;
  264. };
  265. template<typename Expr, typename State, typename Data>
  266. struct transform_impl<Expr, State, Data &>
  267. {
  268. typedef Expr const expr;
  269. typedef Expr const &expr_param;
  270. typedef State const state;
  271. typedef State const &state_param;
  272. typedef Data data;
  273. typedef Data &data_param;
  274. };
  275. template<typename Expr, typename State, typename Data>
  276. struct transform_impl<Expr &, State &, Data>
  277. {
  278. typedef Expr expr;
  279. typedef Expr &expr_param;
  280. typedef State state;
  281. typedef State &state_param;
  282. typedef Data const data;
  283. typedef Data const &data_param;
  284. };
  285. template<typename Expr, typename State, typename Data>
  286. struct transform_impl<Expr &, State, Data &>
  287. {
  288. typedef Expr expr;
  289. typedef Expr &expr_param;
  290. typedef State const state;
  291. typedef State const &state_param;
  292. typedef Data data;
  293. typedef Data &data_param;
  294. };
  295. template<typename Expr, typename State, typename Data>
  296. struct transform_impl<Expr, State &, Data &>
  297. {
  298. typedef Expr const expr;
  299. typedef Expr const &expr_param;
  300. typedef State state;
  301. typedef State &state_param;
  302. typedef Data data;
  303. typedef Data &data_param;
  304. };
  305. template<typename Expr, typename State, typename Data>
  306. struct transform_impl<Expr &, State &, Data &>
  307. {
  308. typedef Expr expr;
  309. typedef Expr &expr_param;
  310. typedef State state;
  311. typedef State &state_param;
  312. typedef Data data;
  313. typedef Data &data_param;
  314. };
  315. }} // namespace boost::proto
  316. #if defined(_MSC_VER)
  317. # pragma warning(pop)
  318. #endif
  319. #endif