afd2fd836d
[SVN r71247]
403 lines
10 KiB
Plaintext
403 lines
10 KiB
Plaintext
[/==============================================================================
|
|
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]
|