Boost logo

Boost Users :

Subject: Re: [Boost-users] [proto] learning proto slowly, a small (math)complex library
From: alfC (alfredo.correa_at_[hidden])
Date: 2011-01-11 02:58:01


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

ok, at the level I am working it seem that the following grammar is
what I need. note that it is not recursive and it is a completely
rigid structure.

struct complex_cartesian_grammar :
        proto::plus<
                proto::terminal<double>,
                proto::multiplies<
                        proto::terminal<double>,
                        proto::terminal<i_tag>
>
>{};
(complete code at the end)

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

not so fast, how do I do that?

I also defined the "domain"
struct complex_cartesian_domain :
        proto::domain<
                proto::generator< complex_cartesian_expr >,
                complex_cartesian_grammar
>{};

I still have to somehow connect the define grammar with the expression
itself. how?
I also understand that the expression convertible to
std::complex<double> must match double + double*i (the simple grammar)
but again I don't understand how to do it.

What follows is the complete code I have far. -- Thank you | Alfredo

#include <boost/proto/core.hpp>
#include <complex>

namespace pretty{

namespace proto = boost::proto;

struct i_tag{};
proto::terminal< i_tag >::type const i = {{}};

template< typename Expr >
struct complex_cartesian_expr;

struct complex_cartesian_grammar :
        proto::plus<
                proto::terminal<double>,
                proto::multiplies<
                        proto::terminal<double>,
                        proto::terminal<i_tag>
>
>{};

struct complex_cartesian_domain :
        proto::domain<
                proto::generator< complex_cartesian_expr >,
                complex_cartesian_grammar
>{};

template<typename Expr>
struct complex_cartesian_expr :
        proto::extends< Expr, complex_cartesian_expr< Expr >,
complex_cartesian_domain >{
        complex_cartesian_expr( Expr const & expr = Expr() ) :
                proto::extends< Expr, complex_cartesian_expr< Expr >,
complex_cartesian_domain >( expr ){}
        template<typename T>
        operator std::complex<T>() const{
                return
                        std::complex<T>(
                                proto::value( proto::child_c<1>(*this) ),
                                proto::value( proto::child_c<1>(proto::child_c<2>(*this)) )
                        )
                ;
        }
};

}

int main(){
        using namespace pretty;
        std::complex<double> z = 4. + 5.*i;
        return 0;
}


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