
-----Original Message----- From: boost-users-bounces@lists.boost.org [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Eric Niebler Sent: 05 March 2009 17:54 To: boost-users@lists.boost.org 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
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_tagstd::sin >::type const sinfct = {{}};
// Define a lazy sin // template<typename Arg> typename proto::result_of::make_expr< proto::tag::function, // Tag type basic_function_tagstd::sin, // First child (by value) Arg const & // Second child (by reference)
::type sin(Arg const &arg) { return proto::make_exprproto::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
> // 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
struct is_basic_function_tag : mpl::true_ {};
proto::function< proto::and_< proto::terminal<_> , proto::if_< is_basic_function_tagproto::_value() > > , proto::_
I'll play with this. Thank you very much, Hicham