1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402
|
[/==============================================================================
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]
|