123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402 |
- [/==============================================================================
- 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]
|