Boost logo

Boost :

From: Maurizio Vitale (mav_at_[hidden])
Date: 2007-05-08 22:30:01


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?

  - if I wanted to support the case where left and/or right are not proto
    expressions, it would be enough to call generate<>::make on the non
    proto-ized one(s) to turn them into proto::terminal, right?
    Maybe proto could provide a mechanism for doing this, seems common
    enough [might be enough to raise as_expr_if2 from proto::detail].
    But clearly then people like me will ask for N up to BOOST_PROTO_MAX_ARITY.
    Maybe a separate CPP constant could be used to keep the number of permutations low.
    Or deal separately with >2 args with an mpl (or fusion) sequence.
    Pretty please...

    [btw, if I understand the code in operators.hpp, proto doesn't explicitely
     check that the domains of the two operands are the same. This situation
     doesn't seem really supported, nor desirable, and maybe code doing it wouldn't
     compile anyhow. But in case it did compile and do wrong things you might
     consider slowing down compilation and adding a check]

  - is it correct that all I have to do then is to either:
       - make my_plus disappear before evaluation (via transforms), or
       - provide an evaluation context with the appropriate overload
         for operator()(my_plus, ...). For instance the following would give
         to my_plus the normal meaning of '+':

          template<typename Left, typename Right>
          double operator() (my_plus, const Left& left, const Right& right) const{
            return proto::eval(left, *this) + proto::eval (right, *this);
          }

  - a simple example for this would be very nice for the documentation.

Best regards,

     Maurizio


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