From: Maurizio Vitale (mav_at_[hidden])
Date: 2007-05-18 22:00:19


Eric Niebler <eric_at_[hidden]> writes:

> Tough questions. You've touched on a weakness of proto. I hope to make
> improvements in this area after BoostCon ...
>
>
> Maurizio Vitale wrote:
>> Suppose I needed a new tag for representing some high-level concept that I do not want
>> to express in terms of C++ operators [it could be a get_bit(N) operation that has very
>> different implementation when for my numbers the unserlyining implementation is a
>> builtin type or a GMP big int]
>>
>> Here's my code for adding a binary operator my_plus:
>>
>> struct my_plus {};
>>
>> template<typename Left, typename Right>
>> proto::expr<my_plus, proto::args2<proto::ref_<Left>, proto::ref_<Right> > > const
>> make_my_plus_expr(Left& left, Right& right)
>> {
>> typedef proto::expr<my_plus, proto::args2<proto::ref_<Left>, proto::ref_<Right> > > expr_type;
>> expr_type that={left,right};
>> return proto::generate<typename Left::domain, expr_type>::make (that);
>> }
>>
>> Questions:
>>
>> - is the above the right way, or is there some friendlier interface?

There's another way to achieve the same effect by just declaring a nullary my_plus and then let the
proto machinery do its job by mean of operator()().
In this case the result would be:
   (function (terminal my_plus expr0 expr1))

The grammar can take care that only binary applications are allowed [my_plus could even declare its arity so that this
can be done in a generic way].
What are pro/cons of the two solutions?

Compile-time evaluation should be the same (albeit probably more expensive at compile-time).

For evaluation in contexts I think the matching becomes more difficult to express (haven't tired it, maybe it doesn't
even work) in that you need to overload on function_tag and then use boost::{dis,en}able_if to control the
overload set. Run-time cost should be the same.

Eric, are the two approach equivalent? or you see particular advantages for one of them?

Regards,

        Maurizio