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-12 03:58:26


Hi Eric,

On Jan 11, 9:33 pm, Eric Niebler <e..._at_[hidden]> wrote:
> See attached.

Thank you very much for the example, it definitely works and does even
more that I was expecting to achieve in this example. However, just in
order to make it more understandable (to me) at the beginning I want
to go even simpler that what you did.

I understand that proto is ideal for recursive expression (grammars?)
but I just want to define a fixed/rigid grammar that only accepts a
rigid expression of the type of 4. + 5.*i. Besides that I don't want
proto to evaluate things for me, I want to be able to "see" the
expression structure and contained values from a single place.
In other words I want a glorified (simulated) constructor.

std::complex<double> z = 5. + 6.*i;

I guess the "grammar" is simply (correct me if I am wrong):

struct i_tag{};

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

yes, it is a very stupid rigid expression. (It just should accept a
certain expression.). For this, I striped down your version, to the
point it didn't compile but I think the intention of the code is
there.
The complete code is attached below. In my opinion...
 what it has:
 1) defines abstract symbol "i"
 2) defines the only allowed expression in the syntax.
 3) defines the domain (I don't know what this does)
 what it lacks:
 4) be able to compile
 5) proper conversion of the expression tree to extract the relevant
data.
 6) expression matches verification??
 for the future:
 7) allow a few more allowable expressions compatible with the
constructor of std::complex<double>, just of the types 4.+5.*i, 4.,
5.*i and that's it.

Sorry to using your powerful library for such an unpowerful
application, I am just trying to learn.

The current code gives naturally this error:
error: conversion from ‘const
boost::proto::exprns_::expr<boost::proto::tag::plus, ... >’ to non-
scalar type ‘std::complex<double>’ requested

The code follows // Thank you // Alfredo

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

namespace proto=boost::proto;

namespace pretty{
        struct i_tag{};

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

        template< typename Expr >
        struct complex_cartesian_expr;

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

        template<typename Expr>
        struct complex_cartesian_expr
        {
                BOOST_PROTO_EXTENDS(
                        Expr,
                        complex_cartesian_expr,
                        complex_cartesian_domain
                )
                template<typename T>
                operator std::complex<T>() const{
                        return std::complex<double>(proto::child_c<0>(*this),
proto::child_c<0>(*this));
                }
        };
        proto::terminal<i_tag>::type const i = {{}};

}

int main(){
        using namespace pretty;
        std::complex<double> z = 5. + 6.*i;
        std::cout << z << std::endl;
        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