Boost logo

Boost :

From: Eric Niebler (eric_at_[hidden])
Date: 2007-05-25 19:18:59


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?

You can now do this with make_expr. It would look like this:

   struct my_plus {};
   proto::functional::make_expr<my_plus> const make_my_plus_expr = {};

Then you can say make_my_plus_expr(e1, e2) and get a binary expr with
my_plus as a tag type. If either e1 or e2 are not yet a proto
expression, they are made into proto terminals first.

If you want to specify a domain, so the resulting expr is wrapped in
some extension wrapper, you can specify the domain as the second
template parameter, as

   struct my_plus {};
   proto::functional::make_expr<my_plus, my_domain> const
       make_my_plus_expr = {};

Currently, the domains of the children expressions are *not* considered
in either case. This seemed simpler. Let me know if this doesn't meet
you needs. I can imagine using a pseudo-domain for the second parameter
that means: propagate the domain from the children nodes.

-- 
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