Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext
default_context

The proto::default_context is an evaluation context that assigns the usual C++ meanings to all the operators. For example, addition nodes are handled by evaluating the left and right children and then adding the results. The proto::default_context uses Boost.Typeof to deduce the types of the expressions it evaluates.

For example, consider the following "Hello World" example:

#include <iostream>
#include <boost/proto/proto.hpp>
#include <boost/proto/context.hpp>
#include <boost/typeof/std/ostream.hpp>
using namespace boost;

proto::terminal< std::ostream & >::type cout_ = { std::cout };

template< typename Expr >
void evaluate( Expr const & expr )
{
    // Evaluate the expression with default_context,
    // to give the operators their C++ meanings:
    proto::default_context ctx;
    proto::eval(expr, ctx);
}

int main()
{
    evaluate( cout_ << "hello" << ',' << " world" );
    return 0;
}

This program outputs the following:

hello, world

proto::default_context is trivially defined in terms of a default_eval<> template, as follows:

// Definition of default_context
struct default_context
{
    template<typename Expr>
    struct eval
      : default_eval<
            Expr
          , default_context const
          , typename tag_of<Expr>::type
        >
    {};
};

There are a bunch of default_eval<> specializations, each of which handles a different C++ operator. Here, for instance, is the specialization for binary addition:

// A default expression evaluator for binary addition
template<typename Expr, typename Context>
struct default_eval<Expr, Context, proto::tag::plus>
{
private:
    static Expr    & s_expr;
    static Context & s_ctx;

public:
    typedef
        decltype(
            proto::eval(proto::child_c<0>(s_expr), s_ctx)
          + proto::eval(proto::child_c<1>(s_expr), s_ctx)
        )
    result_type;

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

The above code uses decltype to calculate the return type of the function call operator. decltype is a new keyword in the next version of C++ that gets the type of any expression. Most compilers do not yet support decltype directly, so default_eval<> uses the Boost.Typeof library to emulate it. On some compilers, that may mean that default_context either doesn't work or that it requires you to register your types with the Boost.Typeof library. Check the documentation for Boost.Typeof to see.


PrevUpHomeNext