/Src/Dependencies/Boost/boost/proto/transform/arg.hpp

http://hadesmem.googlecode.com/ · C++ Header · 380 lines · 215 code · 35 blank · 130 comment · 0 complexity · 80d04965681fc829cdd6391c3ad60efa MD5 · raw file

  1. ///////////////////////////////////////////////////////////////////////////////
  2. /// \file arg.hpp
  3. /// Contains definition of the argN transforms.
  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_ARG_HPP_EAN_11_01_2007
  9. #define BOOST_PROTO_TRANSFORM_ARG_HPP_EAN_11_01_2007
  10. #include <boost/proto/proto_fwd.hpp>
  11. #include <boost/proto/traits.hpp>
  12. #include <boost/proto/transform/impl.hpp>
  13. #include <boost/type_traits/is_array.hpp>
  14. namespace boost { namespace proto
  15. {
  16. /// \brief A PrimitiveTransform that returns the current expression
  17. /// unmodified
  18. ///
  19. /// Example:
  20. ///
  21. /// \code
  22. /// proto::terminal<int>::type i = {42};
  23. /// proto::terminal<int>::type & j = proto::_expr()(i);
  24. /// assert( boost::addressof(i) == boost::addressof(j) );
  25. /// \endcode
  26. struct _expr : transform<_expr>
  27. {
  28. template<typename Expr, typename State, typename Data>
  29. struct impl : transform_impl<Expr, State, Data>
  30. {
  31. typedef Expr result_type;
  32. /// Returns the current expression.
  33. /// \param e The current expression.
  34. /// \return \c e
  35. /// \throw nothrow
  36. #ifdef BOOST_PROTO_STRICT_RESULT_OF
  37. result_type
  38. #else
  39. typename impl::expr_param
  40. #endif
  41. operator()(
  42. typename impl::expr_param e
  43. , typename impl::state_param
  44. , typename impl::data_param
  45. ) const
  46. {
  47. return e;
  48. }
  49. };
  50. };
  51. /// \brief A PrimitiveTransform that returns the current state
  52. /// unmodified
  53. ///
  54. /// Example:
  55. ///
  56. /// \code
  57. /// proto::terminal<int>::type i = {42};
  58. /// char ch = proto::_state()(i, 'a');
  59. /// assert( ch == 'a' );
  60. /// \endcode
  61. struct _state : transform<_state>
  62. {
  63. template<typename Expr, typename State, typename Data>
  64. struct impl : transform_impl<Expr, State, Data>
  65. {
  66. typedef State result_type;
  67. /// Returns the current state.
  68. /// \param s The current state.
  69. /// \return \c s
  70. /// \throw nothrow
  71. #ifdef BOOST_PROTO_STRICT_RESULT_OF
  72. result_type
  73. #else
  74. typename impl::state_param
  75. #endif
  76. operator ()(
  77. typename impl::expr_param
  78. , typename impl::state_param s
  79. , typename impl::data_param
  80. ) const
  81. {
  82. return s;
  83. }
  84. };
  85. };
  86. /// \brief A PrimitiveTransform that returns the current data
  87. /// unmodified
  88. ///
  89. /// Example:
  90. ///
  91. /// \code
  92. /// proto::terminal<int>::type i = {42};
  93. /// std::string str("hello");
  94. /// std::string & data = proto::_data()(i, 'a', str);
  95. /// assert( &str == &data );
  96. /// \endcode
  97. struct _data : transform<_data>
  98. {
  99. template<typename Expr, typename State, typename Data>
  100. struct impl : transform_impl<Expr, State, Data>
  101. {
  102. typedef Data result_type;
  103. /// Returns the current data.
  104. /// \param d The current data.
  105. /// \return \c d
  106. /// \throw nothrow
  107. #ifdef BOOST_PROTO_STRICT_RESULT_OF
  108. result_type
  109. #else
  110. typename impl::data_param
  111. #endif
  112. operator ()(
  113. typename impl::expr_param
  114. , typename impl::state_param
  115. , typename impl::data_param d
  116. ) const
  117. {
  118. return d;
  119. }
  120. };
  121. };
  122. /// \brief A PrimitiveTransform that returns N-th child of the current
  123. /// expression.
  124. ///
  125. /// Example:
  126. ///
  127. /// \code
  128. /// proto::terminal<int>::type i = {42};
  129. /// proto::terminal<int>::type & j = proto::_child_c<0>()(-i);
  130. /// assert( boost::addressof(i) == boost::addressof(j) );
  131. /// \endcode
  132. template<int N>
  133. struct _child_c : transform<_child_c<N> >
  134. {
  135. template<typename Expr, typename State, typename Data>
  136. struct impl : transform_impl<Expr, State, Data>
  137. {
  138. typedef
  139. typename result_of::child_c<Expr, N>::type
  140. result_type;
  141. /// Returns the N-th child of \c e
  142. /// \pre <tt>arity_of\<Expr\>::value \> N</tt>
  143. /// \param e The current expression.
  144. /// \return <tt>proto::child_c\<N\>(e)</tt>
  145. /// \throw nothrow
  146. #ifdef BOOST_PROTO_STRICT_RESULT_OF
  147. result_type
  148. #else
  149. typename result_of::child_c<typename impl::expr_param, N>::type
  150. #endif
  151. operator ()(
  152. typename impl::expr_param e
  153. , typename impl::state_param
  154. , typename impl::data_param
  155. ) const
  156. {
  157. return proto::child_c<N>(e);
  158. }
  159. };
  160. };
  161. /// \brief A PrimitiveTransform that returns the value of the
  162. /// current terminal expression.
  163. ///
  164. /// Example:
  165. ///
  166. /// \code
  167. /// proto::terminal<int>::type i = {42};
  168. /// int j = proto::_value()(i);
  169. /// assert( 42 == j );
  170. /// \endcode
  171. struct _value : transform<_value>
  172. {
  173. template<typename Expr, typename State, typename Data>
  174. struct impl : transform_impl<Expr, State, Data>
  175. {
  176. typedef
  177. typename result_of::value<Expr>::type
  178. result_type;
  179. /// Returns the value of the specified terminal expression.
  180. /// \pre <tt>arity_of\<Expr\>::value == 0</tt>.
  181. /// \param e The current expression.
  182. /// \return <tt>proto::value(e)</tt>
  183. /// \throw nothrow
  184. #ifdef BOOST_PROTO_STRICT_RESULT_OF
  185. typename mpl::if_c<is_array<result_type>::value, result_type &, result_type>::type
  186. #else
  187. typename result_of::value<typename impl::expr_param>::type
  188. #endif
  189. operator ()(
  190. typename impl::expr_param e
  191. , typename impl::state_param
  192. , typename impl::data_param
  193. ) const
  194. {
  195. return proto::value(e);
  196. }
  197. };
  198. };
  199. /// \brief A PrimitiveTransform that does nothing
  200. /// and returns void.
  201. struct _void : transform<_void>
  202. {
  203. template<typename Expr, typename State, typename Data>
  204. struct impl : transform_impl<Expr, State, Data>
  205. {
  206. typedef void result_type;
  207. /// Does nothing and returns void
  208. void operator ()(
  209. typename impl::expr_param
  210. , typename impl::state_param
  211. , typename impl::data_param
  212. ) const
  213. {}
  214. };
  215. };
  216. /// \brief A unary CallableTransform that wraps its argument
  217. /// in a \c boost::reference_wrapper\<\>.
  218. ///
  219. /// Example:
  220. ///
  221. /// \code
  222. /// proto::terminal<int>::type i = {42};
  223. /// boost::reference_wrapper<proto::terminal<int>::type> j
  224. /// = proto::when<_, proto::_byref(_)>()(i);
  225. /// assert( boost::addressof(i) == boost::addressof(j.get()) );
  226. /// \endcode
  227. struct _byref : callable
  228. {
  229. template<typename Sig>
  230. struct result;
  231. template<typename This, typename T>
  232. struct result<This(T)>
  233. {
  234. typedef boost::reference_wrapper<T const> const type;
  235. };
  236. template<typename This, typename T>
  237. struct result<This(T &)>
  238. {
  239. typedef boost::reference_wrapper<T> const type;
  240. };
  241. /// Wrap the parameter \c t in a \c boost::reference_wrapper\<\>
  242. /// \param t The object to wrap
  243. /// \return <tt>boost::ref(t)</tt>
  244. /// \throw nothrow
  245. template<typename T>
  246. boost::reference_wrapper<T> const operator ()(T &t) const
  247. {
  248. return boost::reference_wrapper<T>(t);
  249. }
  250. /// \overload
  251. ///
  252. template<typename T>
  253. boost::reference_wrapper<T const> const operator ()(T const &t) const
  254. {
  255. return boost::reference_wrapper<T const>(t);
  256. }
  257. };
  258. /// \brief A unary CallableTransform that strips references
  259. /// and \c boost::reference_wrapper\<\> from its argument.
  260. ///
  261. /// Example:
  262. ///
  263. /// \code
  264. /// proto::terminal<int>::type i = {42};
  265. /// int j = 67;
  266. /// int k = proto::when<_, proto::_byval(proto::_state)>()(i, boost::ref(j));
  267. /// assert( 67 == k );
  268. /// \endcode
  269. struct _byval : callable
  270. {
  271. template<typename Sig>
  272. struct result;
  273. template<typename This, typename T>
  274. struct result<This(T)>
  275. {
  276. typedef T type;
  277. };
  278. template<typename This, typename T>
  279. struct result<This(T &)>
  280. : result<This(T)>
  281. {};
  282. template<typename This, typename T>
  283. struct result<This(boost::reference_wrapper<T>)>
  284. : result<This(T)>
  285. {};
  286. /// \param t The object to unref
  287. /// \return <tt>t</tt>
  288. /// \throw nothrow
  289. template<typename T>
  290. T operator ()(T const &t) const
  291. {
  292. return t;
  293. }
  294. /// \overload
  295. ///
  296. template<typename T>
  297. T operator ()(boost::reference_wrapper<T> const &t) const
  298. {
  299. return t;
  300. }
  301. };
  302. /// INTERNAL ONLY
  303. ///
  304. template<>
  305. struct is_callable<_expr>
  306. : mpl::true_
  307. {};
  308. /// INTERNAL ONLY
  309. ///
  310. template<>
  311. struct is_callable<_state>
  312. : mpl::true_
  313. {};
  314. /// INTERNAL ONLY
  315. ///
  316. template<>
  317. struct is_callable<_data>
  318. : mpl::true_
  319. {};
  320. /// INTERNAL ONLY
  321. ///
  322. template<int N>
  323. struct is_callable<_child_c<N> >
  324. : mpl::true_
  325. {};
  326. /// INTERNAL ONLY
  327. ///
  328. template<>
  329. struct is_callable<_value>
  330. : mpl::true_
  331. {};
  332. /// INTERNAL ONLY
  333. ///
  334. template<>
  335. struct is_callable<_byref>
  336. : mpl::true_
  337. {};
  338. /// INTERNAL ONLY
  339. ///
  340. template<>
  341. struct is_callable<_byval>
  342. : mpl::true_
  343. {};
  344. }}
  345. #endif