Boost logo

Boost Users :

Subject: Re: [Boost-users] proto: analytical-only math functions
From: Hicham Mouline (hicham_at_[hidden])
Date: 2009-03-05 18:01:31


-----Original Message-----
From: boost-users-bounces_at_[hidden]
[mailto:boost-users-bounces_at_[hidden]] On Behalf Of Eric Niebler
Sent: 05 March 2009 17:54
To: boost-users_at_[hidden]
Subject: Re: [Boost-users] proto: analytical-only math functions

Hicham Mouline wrote:
> Eric Niebler wrote:
>> You really need to reread the section on domains again. The parameter to
>> proto::generator must be an expression extension class template.
>> That's all I have for now. Good luck. And be sure to check the docs,
>> because you could have found many of these answers there.
>
> The complication comes in my case from the fact that the grammar is not
> stand alone type but an inner-type.

>Why does that make a difference?
Rather I meant to say that the grammar "constdef_rhs_grammar" is an inner
type of

template<typename Expr>
struct constant_wrapper
{
...
};

And so in
struct contants_domain
  : proto::domain< proto::pod_generator<constant_wrapper>,
constant_wrapper<Expr>::constdef_rhs_grammar >
{};
obviously wouldn't work.

I could then make contants_domain templated on the Expr

template <typename Expr>
struct contants_domain
  : proto::domain< proto::pod_generator<constant_wrapper>,
constant_wrapper<Expr>::constdef_rhs_grammar >
{};

And then

template<typename Expr>
struct constant_wrapper
{
  BOOST_PROTO_BASIC_EXTENDS(Expr, constant_wrapper< Expr >,
contants_domain<Expr> )
}

This would create DIFFERENT domains, one for each constant.

Does this seem a sensible way to go... I saw Joel's problems with different
domains,
was that related to this at all?

> I have a new question. I am trying to make my basic functions (the cmath
> ones) lazy functions as in the user guide.
>
> // to represent the c++03 math functions
> // c++0x math functions are commented out.
> template < double (*basic_function_ptr)(double) >
> struct basic_function_tag {
> typedef double result_type;
> result_type operator()(double d) const { return basic_function_ptr(d); }

> };
>
> proto::terminal< basic_function_tag<std::sin> >::type const sinfct = {{}};
>
> // Define a lazy sin
> //
> template<typename Arg>
> typename proto::result_of::make_expr<
> proto::tag::function, // Tag type
> basic_function_tag<std::sin>, // First child (by value)
> Arg const & // Second child (by
> reference)
>> ::type
> sin(Arg const &arg)
> {
> return proto::make_expr<proto::tag::function>(
> basic_function_tag< std::sin >(), // First child (by value)
> boost::ref(arg) // Second child (by
> reference)
> );
> }
>
> This should work for sin( literals and c++ vars ) and for sin( proto
> expressions ).
>
> As in my grammar I used to accept basic functions as proto terminals ,
> How can I change the grammar to take this new sin() instead?

>Well, what you really want is to say is something like this:

>proto::function<
> proto::terminal<basic_function_tag<_> > // Whoops! :-(
> , proto::_
> >

>But proto::_ only matches types, not non-type template parameters. What
>you can do instead is something like this:

>template<typename T>
>struct is_basic_function_tag : mpl::false_ {};

>template<double (*F)(double)>
>struct is_basic_function_tag<basic_function_tag<F> > : mpl::true_ {};

>proto::function<
> proto::and_<
> proto::terminal<_>
> , proto::if_< is_basic_function_tag<proto::_value>() >
> >
> , proto::_
> >

I'll play with this.
Thank you very much,

Hicham


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