Boost logo

Boost Users :

Subject: Re: [Boost-users] proto: analytical-only math functions
From: Eric Niebler (eric_at_[hidden])
Date: 2009-03-05 12:53:34


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?

> 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::_
>

HTH,

-- 
Eric Niebler
BoostPro Computing
http://www.boostpro.com

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