Boost logo

Boost :

From: Eric Niebler (eric_at_[hidden])
Date: 2007-05-15 19:24:56


Maurizio Vitale wrote:
> Waiting for Eric, the following works, although it is way more verbose than if a single eval overload could
> be spliced in, before other operator() overloads. The trick is to only specialize eval, rather than mixing
> eval and operator ()s.

I'm a bit rushed, so forgive me if I've misunderstood your requirements,
but it seems to me you could accomplish this with a layered context
struct. See the following for an idea (totally untested):

struct my_context_aux
   : proto::callable_context<my_context_aux const>
{
     typedef unsigned int result_type;

     // handle int terminals. Everything else is handled by default.
     result_type operator()(proto::tag::terminal, int) const
     {
         return 0;
     }
};

struct my_context
{
     // Use this eval when we don't know the result at compile time.
     // It defers to the internal aux context.
     template<typename Expr, typename EnableIf = void>
     struct eval
     {
         typedef my_context_aux::result_type result_type;
         result_type operator()(Expr &expr, my_context const &ctx) const
         {
             // Defer to the aux context
             return proto::eval(expr, ctx.aux_ctx_);
         }
     };

     // Use this eval when we know the result at compile time
     // based on the type of Expr
     template<typename Expr>
     struct eval<Expr, typename disable_if< is_same<run_time, ...
determine return type ... > >
     {
         typedef ... result_type;
         result_type operator()(Expr &expr, my_context const &ctx) const
         {
             return result_type();
         }
     };

     my_context_aux aux_ctx_;
};

HTH,

-- 
Eric Niebler
Boost Consulting
www.boost-consulting.com

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk