Boost.YAP expressions are evaluated explicitly, by calling the evaluate()
function or calling transform()
using a transform object
returned from evaluation()
. The former is a convenince
function that does the latter.
evaluate()
simply removes all the Boost.YAP
machinery from an expression and evaluates it exactly as it would have been
if Boost.YAP were not used. This means that functions are called, operators
evaluated, etc. all as normal. To illustrate this, take a look at the implementation
of operator,()
used in evaluate()
:
template<typename T, typename U> constexpr decltype(auto) operator()(expr_tag<expr_kind::comma>, T && t, U && u) const { return transform( as_expr<minimal_expr>(static_cast<T &&>(t)), *this), transform( as_expr<minimal_expr>(static_cast<U &&>(u)), *this); }
What this transformation does is transform the left and right expressions,
and then use the built-in operator,()
on the result. The evaluation transformations
for the other operators do the same thing — evaluate the operands,
then return the result of applying the built-in operator to the operands.
Function calls are done in a similar way, except that the callable is also a subexpression that needs to be evaluated before being called:
template<typename Callable, typename... Args> constexpr decltype(auto) operator()( expr_tag<expr_kind::call>, Callable && callable, Args &&... args) const { return transform(as_expr<minimal_expr>(static_cast<Callable &&>(callable)), *this)( transform(as_expr<minimal_expr>(static_cast<Args &&>(args)), *this)... ); }