Boost logo

Boost Users :

Subject: Re: [Boost-users] [proto] learning proto slowly, a small (math)complex library
From: Thomas Heller (thom.heller_at_[hidden])
Date: 2011-01-10 15:47:55


alfC wrote:

> Hi,

<snip>

> This is what I have done so far:
>
> #include <boost/proto/core.hpp>
> namespace pretty{
> namespace proto = boost::proto;
> struct i_tag{};
> proto::terminal< i_tag >::type const i = {{}};
> }
>
> int main(){
> using namespace pretty;
> 4. + 5.*i; //this will be a complex number (in some sense)
> return 0;
> }

<snip>

> Since the first concern is to be able to use the new code with old
> code at all intermediate steps in the development, duppose I want to
> use this kind of expression to construct (in the c++ sense) an
> existing type, namely std::complex<double>. i.e. I want to be able to
> write:
>
> std::complex<double> z = 4. + 5.*i;
> or
> std::complex<double> z(4. + 5.*i);
> (forget about alternative notations, like 5.*i + 4. or 4. + i*5)
>
> The only ways I see this is possible is by adding either a constructor
> to std::complex<double> or a cast operator of the "expression of type
> 4.+5.*i" to std::complex<double>.
> The question for this post,
>
> 1) is this true?
> 2) if yes, then that means that one of the 2 types (type complex or
> typeof(4.+5.*i) ), will have to be modified (or extendended) in other
> to accept this syntax.
> 3) if no , how can I allow this syntax?
> 4) if the std::complex type is not modifiable, what is the mechanism
> in proto to define a cast over a certain set of expressions, e.g. of
> the type of 4.+5.*i.
> 5) if not, is this syntax not possible at all? is it here where we
> need to introduce those "eval" functions such as std::complex<double>
> z = eval_as_complex(4. + 5.*i).
>
> The idea is that once I resolve this general questions about the
> library I will continue building up. (And excuse me for these naive
> questions along the way).
>
> (Note: I know that std::complex<double> had constructor
> std::complex<double>(4.,5.) and that should be the preferred use, but
> this post is all about "syntax" and how to use proto, these are just
> examples).

As Joel pointed out already, you need to wrap your expression templates to
give them their domain specific meaning. In your case, the cast operator.
This cast operator would need to have a context, or preferably a transform
(a transform is a grammar is a transform) to evaluate your expression to
std::complex<double>.
See:
http://www.boost.org/doc/libs/1_45_0/doc/html/proto/users_guide.html#boost_proto.users_guide.getting_started.hello_calculator.customizing_expression_trees
for an example with contexts.

The steps to define a grammar that does the transformation are the
following:
1) define a grammar that matches your expression (proto::matches,
proto::display_expr are a great help here, i also use std::cout <<
typeid(Expr).name() << "\n"; quite often).

2) attach semantic actions, step by step to your grammar rules

That's it :)

HTH,
Thomas

> Thank you,
> Alfredo


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net