Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext
null_context

The proto::null_context<> is a simple context that recursively evaluates children but does not combine the results in any way and returns void. It is useful in conjunction with callable_context<>, or when defining your own contexts which mutate an expression tree in-place rather than accumulate a result, as we'll see below.

proto::null_context<> is trivially implemented in terms of null_eval<> as follows:

// Definition of null_context
struct null_context
{
    template<typename Expr>
    struct eval
      : null_eval<Expr, null_context const, Expr::proto_arity::value>
    {};
};

And null_eval<> is also trivially implemented. Here, for instance is a binary null_eval<>:

// Binary null_eval<>
template<typename Expr, typename Context>
struct null_eval<Expr, Context, 2>
{
    typedef void result_type;

    void operator()(Expr &expr, Context &ctx) const
    {
        proto::eval(proto::child_c<0>(expr), ctx);
        proto::eval(proto::child_c<1>(expr), ctx);
    }
};

When would such classes be useful? Imagine you have an expression tree with integer terminals, and you would like to increment each integer in-place. You might define an evaluation context as follows:

struct increment_ints
{
    // By default, just evaluate all children by delegating
    // to the null_eval<>
    template<typename Expr, typename Arg = proto::result_of::child<Expr>::type>
    struct eval
      : null_eval<Expr, increment_ints const>
    {};

    // Increment integer terminals
    template<typename Expr>
    struct eval<Expr, int>
    {
        typedef void result_type;

        void operator()(Expr &expr, increment_ints const &) const
        {
            ++proto::child(expr);
        }
    };
};

In the next section on proto::callable_context<>, we'll see an even simpler way to achieve the same thing.


PrevUpHomeNext