| [/============================================================================== |
| Copyright (C) 2001-2010 Joel de Guzman |
| Copyright (C) 2001-2005 Dan Marsden |
| Copyright (C) 2001-2010 Thomas Heller |
| |
| Distributed under the Boost Software License, Version 1.0. (See accompanying |
| file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
| ===============================================================================/] |
| |
| [section Function] |
| |
| The `function` class template provides a mechanism for implementing lazily |
| evaluated functions. Syntactically, a lazy function looks like an ordinary C/C++ |
| function. The function call looks familiar and feels the same as ordinary C++ |
| functions. However, unlike ordinary functions, the actual function execution is |
| deferred. |
| |
| #include <boost/phoenix/function.hpp> |
| |
| Unlike ordinary function pointers or functor objects that need to be explicitly |
| bound through the bind function (see [link phoenix.modules.bind Bind]), |
| the argument types of these functions are automatically lazily bound. |
| |
| In order to create a lazy function, we need to implement a model of the |
| __PFO__ concept. For a function that takes `N` arguments, a model of __PFO__ must |
| provide: |
| |
| * An `operator()` that takes `N` arguments, and implements |
| the function logic. This is also true for ordinary function pointers. |
| * A nested metafunction `result<Signature>` or nested typedef `result_type`, following the __boost_result_of__ Protocol |
| |
| [/ |
| * A nested metafunction `result<A1, ... AN>` that takes the types of the `N` arguments to |
| the function and returns the result type of the function. (There is a special case for function |
| objects that accept no arguments. Such nullary functors are only required to define a typedef |
| `result_type` that reflects the return type of its `operator()`). |
| ] |
| |
| For example, the following type implements the FunctionEval concept, in order to provide a |
| lazy factorial function: |
| |
| struct factorial_impl |
| { |
| template <typename Sig> |
| struct result; |
| |
| template <typename This, typename Arg> |
| struct result<This(Arg const &)> |
| { |
| typedef Arg type; |
| }; |
| |
| template <typename Arg> |
| Arg operator()(Arg const & n) const |
| { |
| return (n <= 0) ? 1 : n * (*this)(n-1); |
| } |
| }; |
| |
| (See [@../../example/factorial.cpp factorial.cpp]) |
| |
| [/note The type of Arg is either a const-reference or non-const-reference |
| (depending on whether your argument to the actor evaluation is a const-ref or |
| non-const-ref).] |
| |
| Having implemented the `factorial_impl` type, we can declare and instantiate a lazy |
| `factorial` function this way: |
| |
| function<factorial_impl> factorial; |
| |
| Invoking a lazy function such as `factorial` does not immediately execute the function |
| object `factorial_impl`. Instead, an [link phoenix.actor actor] object is |
| created and returned to the caller. Example: |
| |
| factorial(arg1) |
| |
| does nothing more than return an actor. A second function call will invoke |
| the actual factorial function. Example: |
| |
| std::cout << factorial(arg1)(4); |
| |
| will print out "24". |
| |
| Take note that in certain cases (e.g. for function objects with state), an |
| instance of the model of __PFO__ may be passed on to the constructor. Example: |
| |
| function<factorial_impl> factorial(ftor); |
| |
| where ftor is an instance of factorial_impl (this is not necessary in this case |
| as `factorial_impl` does not require any state). |
| |
| [important Take care though when using function objects with state because they are |
| often copied repeatedly, and state may change in one of the copies, rather than the |
| original.] |
| |
| [section Adapting Functions] |
| |
| If you want to adapt already existing functions or function objects it will become |
| a repetetive task. Therefor the following boilerplate macros are provided to help |
| you adapt already exsiting functions, thus reducing the need to |
| [link phoenix.modules.bind] functions. |
| |
| [section BOOST_PHOENIX_ADAPT_FUNCTION_NULLARY] |
| |
| [heading Description] |
| `BOOST_PHOENIX_ADAPT_FUNCTION_NULLARY` is a macro that can be used to generate |
| all the necessary boilerplate to make an arbitrary nullary function a lazy |
| function. |
| |
| [note These macros generate no global objects. The resulting lazy functions are real functions |
| that create the lazy function expression object] |
| |
| [heading Synopsis] |
| |
| BOOST_PHOENIX_ADAPT_FUNCTION_NULLARY( |
| RETURN_TYPE |
| , LAZY_FUNCTION |
| , FUNCTION |
| ) |
| |
| [heading Semantics] |
| |
| The above macro generates all necessary code to have a nullary lazy function |
| `LAZY_FUNCTION` which calls the nullary `FUNCTION` that has the return type |
| `RETURN_TYPE` |
| |
| [heading Header] |
| |
| #include <boost/phoenix/function/adapt_function.hpp> |
| |
| [heading Example] |
| |
| namespace demo |
| { |
| int foo() |
| { |
| return 42; |
| } |
| } |
| |
| BOOST_PHOENIX_ADAPT_FUNCTION_NULLARY(int, foo, demo::foo) |
| |
| int main() |
| { |
| using boost::phoenix::placeholders::_1; |
| |
| assert((_1 + foo())(1) == 43); |
| } |
| |
| [endsect] |
| |
| [section BOOST_PHOENIX_ADAPT_FUNCTION] |
| |
| [heading Description] |
| `BOOST_PHOENIX_ADAPT_FUNCTION` is a macro that can be used to generate |
| all the necessary boilerplate to make an arbitrary function a lazy function. |
| |
| [heading Synopsis] |
| |
| BOOST_PHOENIX_ADAPT_FUNCTION( |
| RETURN_TYPE |
| , LAZY_FUNCTION |
| , FUNCTION |
| , FUNCTION_ARITY |
| ) |
| |
| [heading Semantics] |
| |
| The above macro generates all necessary code to have a lazy function |
| `LAZY_FUNCTION` which calls `FUNCTION` that has the return type |
| `RETURN_TYPE` with `FUNCTION_ARITY` number of arguments. |
| |
| [heading Header] |
| |
| #include <boost/phoenix/function/adapt_function.hpp> |
| |
| [heading Example] |
| |
| namespace demo |
| { |
| int plus(int a, int b) |
| { |
| return a + b; |
| } |
| |
| template <typename T> |
| T |
| plus(T a, T b, T c) |
| { |
| return a + b + c; |
| } |
| } |
| |
| BOOST_PHOENIX_ADAPT_FUNCTION(int, plus, demo::plus, 2) |
| |
| BOOST_PHOENIX_ADAPT_FUNCTION( |
| typename remove_reference<A0>::type |
| , plus |
| , demo::plus |
| , 3 |
| ) |
| |
| int main() |
| { |
| using boost::phoenix::arg_names::arg1; |
| using boost::phoenix::arg_names::arg2; |
| |
| int a = 123; |
| int b = 256; |
| |
| assert(plus(arg1, arg2)(a, b) == a+b); |
| assert(plus(arg1, arg2, 3)(a, b) == a+b+3); |
| } |
| |
| [endsect] |
| |
| [/ |
| |
| [section BOOST_PHOENIX_ADAPT_FUNCTION_VARARG] |
| |
| [heading Description] |
| `BOOST_PHOENIX_ADAPT_FUNCTION_VARARG` is a macro that can be used to generate |
| all the necessary boilerplate to make an arbitrary function a lazy |
| function. |
| |
| [heading Synopsis] |
| |
| BOOST_PHOENIX_ADAPT_FUNCTION_VARARG( |
| RETURN_TYPE |
| , LAZY_FUNCTION |
| , FUNCTION |
| ) |
| |
| [heading Semantics] |
| |
| [heading Header] |
| |
| #include <boost/phoenix/function/adapt_function.hpp> |
| |
| [heading Example] |
| |
| [endsect] |
| ] |
| |
| [section BOOST_PHOENIX_ADAPT_CALLABLE_NULLARY] |
| |
| [heading Description] |
| `BOOST_PHOENIX_ADAPT_CALLABLE_NULLARY` is a macro that can be used to generate |
| all the necessary boilerplate to make an arbitrary nullary function object a |
| lazy function. |
| |
| [heading Synopsis] |
| |
| BOOST_PHOENIX_ADAPT_CALLABLE_NULLARY( |
| LAZY_FUNCTION |
| , CALLABLE |
| ) |
| |
| [heading Semantics] |
| |
| The above macro generates all necessary code to create `LAZY_FUNCTION` which |
| creates a lazy function object that represents a nullary call to `CALLABLE`. |
| The return type is specified by `CALLABLE` conforming to the __boost_result_of__ |
| protocol. |
| |
| [heading Header] |
| |
| #include <boost/phoenix/function/adapt_callable.hpp> |
| |
| [heading Example] |
| |
| namespace demo |
| { |
| struct foo |
| { |
| typedef int result_type; |
| |
| result_type operator()() const |
| { |
| return 42; |
| } |
| } |
| } |
| |
| BOOST_PHOENIX_ADAPT_CALLABLE_NULLARY(foo, demo::foo) |
| |
| int main() |
| { |
| using boost::phoenix::placeholders::_1; |
| |
| assert((_1 + foo())(1) == 43); |
| } |
| |
| [endsect] |
| |
| [section BOOST_PHOENIX_ADAPT_CALLABLE] |
| |
| [heading Description] |
| `BOOST_PHOENIX_ADAPT_CALLABLE` is a macro that can be used to generate |
| all the necessary boilerplate to make an arbitrary function object a lazy |
| function. |
| |
| [heading Synopsis] |
| |
| BOOST_PHOENIX_ADAPT_CALLABLE( |
| LAZY_FUNCTION |
| , FUNCTION_NAME |
| , FUNCTION_ARITY |
| ) |
| |
| [heading Semantics] |
| |
| The above macro generates all necessary code to create `LAZY_FUNCTION` which |
| creates a lazy function object that represents a call to `CALLABLE` with `FUNCTION_ARITY` |
| arguments. |
| The return type is specified by `CALLABLE` conforming to the __boost_result_of__ |
| protocol. |
| |
| [heading Header] |
| |
| #include <boost/phoenix/function/adapt_callable.hpp> |
| |
| [heading Example] |
| |
| namespace demo |
| { |
| struct plus |
| { |
| template <typename Sig> |
| struct result; |
| |
| template <typename This, typename A0, typename A1> |
| struct result<This(A0, A1)> |
| : remove_reference<A0> |
| {}; |
| |
| template <typename This, typename A0, typename A1, typename A2> |
| struct result<This(A0, A1, A2)> |
| : remove_reference<A0> |
| {}; |
| |
| template <typename A0, typename A1> |
| A0 operator()(A0 const & a0, A1 const & a1) const |
| { |
| return a0 + a1; |
| } |
| |
| template <typename A0, typename A1, typename A2> |
| A0 operator()(A0 const & a0, A1 const & a1, A2 const & a2) const |
| { |
| return a0 + a1 + a2; |
| } |
| }; |
| } |
| |
| BOOST_PHOENIX_ADAPT_CALLABLE(plus, demo::plus, 2) |
| |
| BOOST_PHOENIX_ADAPT_CALLABLE(plus, demo::plus, 3) |
| |
| int main() |
| { |
| using boost::phoenix::arg_names::arg1; |
| using boost::phoenix::arg_names::arg2; |
| |
| int a = 123; |
| int b = 256; |
| |
| assert(plus(arg1, arg2)(a, b) == a+b); |
| assert(plus(arg1, arg2, 3)(a, b) == a+b+3); |
| } |
| |
| [endsect] |
| |
| [/ |
| [section BOOST_PHOENIX_ADAPT_CALLABLE_VARARG] |
| |
| [heading Description] |
| `BOOST_PHOENIX_ADAPT_CALLABLE_VARARG` is a macro that can be used to generate |
| all the necessary boilerplate to make an arbitrary function object a lazy |
| function. |
| |
| [heading Synopsis] |
| |
| BOOST_PHOENIX_ADAPT_CALLABLE_VARARG( |
| LAZY_FUNCTION_NAME |
| , FUNCTION_NAME |
| ) |
| |
| [heading Semantics] |
| |
| [heading Header] |
| |
| #include <boost/phoenix/function/adapt_callable.hpp> |
| |
| [heading Example] |
| |
| [endsect] |
| /] |
| |
| [endsect] |
| |
| [endsect] |