function.qbk 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. [/==============================================================================
  2. Copyright (C) 2001-2010 Joel de Guzman
  3. Copyright (C) 2001-2005 Dan Marsden
  4. Copyright (C) 2001-2010 Thomas Heller
  5. Distributed under the Boost Software License, Version 1.0. (See accompanying
  6. file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. ===============================================================================/]
  8. [section Function]
  9. The `function` class template provides a mechanism for implementing lazily
  10. evaluated functions. Syntactically, a lazy function looks like an ordinary C/C++
  11. function. The function call looks familiar and feels the same as ordinary C++
  12. functions. However, unlike ordinary functions, the actual function execution is
  13. deferred.
  14. #include <boost/phoenix/function.hpp>
  15. Unlike ordinary function pointers or functor objects that need to be explicitly
  16. bound through the bind function (see [link phoenix.modules.bind Bind]),
  17. the argument types of these functions are automatically lazily bound.
  18. In order to create a lazy function, we need to implement a model of the
  19. __PFO__ concept. For a function that takes `N` arguments, a model of __PFO__ must
  20. provide:
  21. * An `operator()` that takes `N` arguments, and implements
  22. the function logic. This is also true for ordinary function pointers.
  23. * A nested metafunction `result<Signature>` or nested typedef `result_type`, following the __boost_result_of__ Protocol
  24. [/
  25. * A nested metafunction `result<A1, ... AN>` that takes the types of the `N` arguments to
  26. the function and returns the result type of the function. (There is a special case for function
  27. objects that accept no arguments. Such nullary functors are only required to define a typedef
  28. `result_type` that reflects the return type of its `operator()`).
  29. ]
  30. For example, the following type implements the FunctionEval concept, in order to provide a
  31. lazy factorial function:
  32. struct factorial_impl
  33. {
  34. template <typename Sig>
  35. struct result;
  36. template <typename This, typename Arg>
  37. struct result<This(Arg const &)>
  38. {
  39. typedef Arg type;
  40. };
  41. template <typename Arg>
  42. Arg operator()(Arg const & n) const
  43. {
  44. return (n <= 0) ? 1 : n * (*this)(n-1);
  45. }
  46. };
  47. (See [@../../example/factorial.cpp factorial.cpp])
  48. [/note The type of Arg is either a const-reference or non-const-reference
  49. (depending on whether your argument to the actor evaluation is a const-ref or
  50. non-const-ref).]
  51. Having implemented the `factorial_impl` type, we can declare and instantiate a lazy
  52. `factorial` function this way:
  53. function<factorial_impl> factorial;
  54. Invoking a lazy function such as `factorial` does not immediately execute the function
  55. object `factorial_impl`. Instead, an [link phoenix.actor actor] object is
  56. created and returned to the caller. Example:
  57. factorial(arg1)
  58. does nothing more than return an actor. A second function call will invoke
  59. the actual factorial function. Example:
  60. std::cout << factorial(arg1)(4);
  61. will print out "24".
  62. Take note that in certain cases (e.g. for function objects with state), an
  63. instance of the model of __PFO__ may be passed on to the constructor. Example:
  64. function<factorial_impl> factorial(ftor);
  65. where ftor is an instance of factorial_impl (this is not necessary in this case
  66. as `factorial_impl` does not require any state).
  67. [important Take care though when using function objects with state because they are
  68. often copied repeatedly, and state may change in one of the copies, rather than the
  69. original.]
  70. [section Adapting Functions]
  71. If you want to adapt already existing functions or function objects it will become
  72. a repetetive task. Therefor the following boilerplate macros are provided to help
  73. you adapt already exsiting functions, thus reducing the need to
  74. [link phoenix.modules.bind] functions.
  75. [section BOOST_PHOENIX_ADAPT_FUNCTION_NULLARY]
  76. [heading Description]
  77. `BOOST_PHOENIX_ADAPT_FUNCTION_NULLARY` is a macro that can be used to generate
  78. all the necessary boilerplate to make an arbitrary nullary function a lazy
  79. function.
  80. [note These macros generate no global objects. The resulting lazy functions are real functions
  81. that create the lazy function expression object]
  82. [heading Synopsis]
  83. BOOST_PHOENIX_ADAPT_FUNCTION_NULLARY(
  84. RETURN_TYPE
  85. , LAZY_FUNCTION
  86. , FUNCTION
  87. )
  88. [heading Semantics]
  89. The above macro generates all necessary code to have a nullary lazy function
  90. `LAZY_FUNCTION` which calls the nullary `FUNCTION` that has the return type
  91. `RETURN_TYPE`
  92. [heading Header]
  93. #include <boost/phoenix/function/adapt_function.hpp>
  94. [heading Example]
  95. namespace demo
  96. {
  97. int foo()
  98. {
  99. return 42;
  100. }
  101. }
  102. BOOST_PHOENIX_ADAPT_FUNCTION_NULLARY(int, foo, demo::foo)
  103. int main()
  104. {
  105. using boost::phoenix::placeholders::_1;
  106. assert((_1 + foo())(1) == 43);
  107. }
  108. [endsect]
  109. [section BOOST_PHOENIX_ADAPT_FUNCTION]
  110. [heading Description]
  111. `BOOST_PHOENIX_ADAPT_FUNCTION` is a macro that can be used to generate
  112. all the necessary boilerplate to make an arbitrary function a lazy function.
  113. [heading Synopsis]
  114. BOOST_PHOENIX_ADAPT_FUNCTION(
  115. RETURN_TYPE
  116. , LAZY_FUNCTION
  117. , FUNCTION
  118. , FUNCTION_ARITY
  119. )
  120. [heading Semantics]
  121. The above macro generates all necessary code to have a lazy function
  122. `LAZY_FUNCTION` which calls `FUNCTION` that has the return type
  123. `RETURN_TYPE` with `FUNCTION_ARITY` number of arguments.
  124. [heading Header]
  125. #include <boost/phoenix/function/adapt_function.hpp>
  126. [heading Example]
  127. namespace demo
  128. {
  129. int plus(int a, int b)
  130. {
  131. return a + b;
  132. }
  133. template <typename T>
  134. T
  135. plus(T a, T b, T c)
  136. {
  137. return a + b + c;
  138. }
  139. }
  140. BOOST_PHOENIX_ADAPT_FUNCTION(int, plus, demo::plus, 2)
  141. BOOST_PHOENIX_ADAPT_FUNCTION(
  142. typename remove_reference<A0>::type
  143. , plus
  144. , demo::plus
  145. , 3
  146. )
  147. int main()
  148. {
  149. using boost::phoenix::arg_names::arg1;
  150. using boost::phoenix::arg_names::arg2;
  151. int a = 123;
  152. int b = 256;
  153. assert(plus(arg1, arg2)(a, b) == a+b);
  154. assert(plus(arg1, arg2, 3)(a, b) == a+b+3);
  155. }
  156. [endsect]
  157. [/
  158. [section BOOST_PHOENIX_ADAPT_FUNCTION_VARARG]
  159. [heading Description]
  160. `BOOST_PHOENIX_ADAPT_FUNCTION_VARARG` is a macro that can be used to generate
  161. all the necessary boilerplate to make an arbitrary function a lazy
  162. function.
  163. [heading Synopsis]
  164. BOOST_PHOENIX_ADAPT_FUNCTION_VARARG(
  165. RETURN_TYPE
  166. , LAZY_FUNCTION
  167. , FUNCTION
  168. )
  169. [heading Semantics]
  170. [heading Header]
  171. #include <boost/phoenix/function/adapt_function.hpp>
  172. [heading Example]
  173. [endsect]
  174. ]
  175. [section BOOST_PHOENIX_ADAPT_CALLABLE_NULLARY]
  176. [heading Description]
  177. `BOOST_PHOENIX_ADAPT_CALLABLE_NULLARY` is a macro that can be used to generate
  178. all the necessary boilerplate to make an arbitrary nullary function object a
  179. lazy function.
  180. [heading Synopsis]
  181. BOOST_PHOENIX_ADAPT_CALLABLE_NULLARY(
  182. LAZY_FUNCTION
  183. , CALLABLE
  184. )
  185. [heading Semantics]
  186. The above macro generates all necessary code to create `LAZY_FUNCTION` which
  187. creates a lazy function object that represents a nullary call to `CALLABLE`.
  188. The return type is specified by `CALLABLE` conforming to the __boost_result_of__
  189. protocol.
  190. [heading Header]
  191. #include <boost/phoenix/function/adapt_callable.hpp>
  192. [heading Example]
  193. namespace demo
  194. {
  195. struct foo
  196. {
  197. typedef int result_type;
  198. result_type operator()() const
  199. {
  200. return 42;
  201. }
  202. }
  203. }
  204. BOOST_PHOENIX_ADAPT_CALLABLE_NULLARY(foo, demo::foo)
  205. int main()
  206. {
  207. using boost::phoenix::placeholders::_1;
  208. assert((_1 + foo())(1) == 43);
  209. }
  210. [endsect]
  211. [section BOOST_PHOENIX_ADAPT_CALLABLE]
  212. [heading Description]
  213. `BOOST_PHOENIX_ADAPT_CALLABLE` is a macro that can be used to generate
  214. all the necessary boilerplate to make an arbitrary function object a lazy
  215. function.
  216. [heading Synopsis]
  217. BOOST_PHOENIX_ADAPT_CALLABLE(
  218. LAZY_FUNCTION
  219. , FUNCTION_NAME
  220. , FUNCTION_ARITY
  221. )
  222. [heading Semantics]
  223. The above macro generates all necessary code to create `LAZY_FUNCTION` which
  224. creates a lazy function object that represents a call to `CALLABLE` with `FUNCTION_ARITY`
  225. arguments.
  226. The return type is specified by `CALLABLE` conforming to the __boost_result_of__
  227. protocol.
  228. [heading Header]
  229. #include <boost/phoenix/function/adapt_callable.hpp>
  230. [heading Example]
  231. namespace demo
  232. {
  233. struct plus
  234. {
  235. template <typename Sig>
  236. struct result;
  237. template <typename This, typename A0, typename A1>
  238. struct result<This(A0, A1)>
  239. : remove_reference<A0>
  240. {};
  241. template <typename This, typename A0, typename A1, typename A2>
  242. struct result<This(A0, A1, A2)>
  243. : remove_reference<A0>
  244. {};
  245. template <typename A0, typename A1>
  246. A0 operator()(A0 const & a0, A1 const & a1) const
  247. {
  248. return a0 + a1;
  249. }
  250. template <typename A0, typename A1, typename A2>
  251. A0 operator()(A0 const & a0, A1 const & a1, A2 const & a2) const
  252. {
  253. return a0 + a1 + a2;
  254. }
  255. };
  256. }
  257. BOOST_PHOENIX_ADAPT_CALLABLE(plus, demo::plus, 2)
  258. BOOST_PHOENIX_ADAPT_CALLABLE(plus, demo::plus, 3)
  259. int main()
  260. {
  261. using boost::phoenix::arg_names::arg1;
  262. using boost::phoenix::arg_names::arg2;
  263. int a = 123;
  264. int b = 256;
  265. assert(plus(arg1, arg2)(a, b) == a+b);
  266. assert(plus(arg1, arg2, 3)(a, b) == a+b+3);
  267. }
  268. [endsect]
  269. [/
  270. [section BOOST_PHOENIX_ADAPT_CALLABLE_VARARG]
  271. [heading Description]
  272. `BOOST_PHOENIX_ADAPT_CALLABLE_VARARG` is a macro that can be used to generate
  273. all the necessary boilerplate to make an arbitrary function object a lazy
  274. function.
  275. [heading Synopsis]
  276. BOOST_PHOENIX_ADAPT_CALLABLE_VARARG(
  277. LAZY_FUNCTION_NAME
  278. , FUNCTION_NAME
  279. )
  280. [heading Semantics]
  281. [heading Header]
  282. #include <boost/phoenix/function/adapt_callable.hpp>
  283. [heading Example]
  284. [endsect]
  285. /]
  286. [endsect]
  287. [endsect]