
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