Boost logo

Boost Users :

Subject: Re: [Boost-users] [proto] defining function call operators on expressions
From: Manjunath Kudlur (keveman_at_[hidden])
Date: 2010-02-28 22:21:56


On Sun, Feb 28, 2010 at 1:28 AM, Eric Niebler <eric_at_[hidden]> wrote:
>
> On 2/28/2010 7:17 PM, Manjunath Kudlur wrote:
>>
>> I am trying to define operator()(...) for my expressions. I want to be
>> able to form expression of the form Program_(a,b) and call Program_(a,
>> b)(10,20). Here, 'a' and 'b' are terminals and I have a mechanism
>> shown in the code below that somehow gets the type suitable for the
>> parameter position. Suppose 'a' is terminal<Var<int>  >, I want the
>> first parameter position in Program_(a,b) (pos1, pos2) to be of the
>> type 'int'.
>
> <snip>
>
> OK.
>
>> template<int N>
>> struct call_param_type
>>   : proto::or_<
>>     proto::when<
>>     proto::function<
>>     proto::terminal<program_>,
>>     proto::vararg<proto::terminal<Var<proto::_>  >  >  >,
>>     var_type(proto::_child_c<N+1>)>
>> > {};
>
> OK, the call_param_type grammar only matches expressions of the type
> Program_(a, b).
>
>> template<typename Expr>
>> struct program_expr {
>>   BOOST_PROTO_BASIC_EXTENDS(Expr, program_expr<Expr>, program_domain);
>>   BOOST_PROTO_EXTENDS_SUBSCRIPT();
>>
>>   typedef void result_type;
>>
>> #if 0
>>   result_type operator()(typename
>> boost::result_of<call_param_type<0>(const Expr&)>::type x) {
>>     std::cout<<  "program with one arg\n";
>>   }
>
> <snip>
>
> This function definition eagerly evaluates the call_param_type grammar's
> transform against Expr regardless of whether Expr matches call_param_type's
> grammar or not. Trouble. Look at how you define the Program_ function:
>
>> template<typename A0>
>> typename proto::result_of::make_expr<proto::tag::function
>> , program_domain
>> , program_
>> , A0 const &>::type const
>> Program_(A0 const &a0)
>
> This creates an expression node with tag type "tag::function" and two
> children: a program_ terminal and A0. When make_expr turns program_ into a
> Proto terminal, it uses program_domain to wrap the terminal in a
> program_expr. That's bad news because a program_ terminal doesn't match the
> call_param_type grammar. You're violating the transform's precondition.

Yeah, got it. I realise now that the passing a domain to make_expr
wraps all the components of the expression also with the corresponding
expression class. What I am unable to figure out it how to wrap only
the final expression I want with program_expr. In this case I want to
wrap expr<tag::function, vararg<terminal<Var> > > with program_expr.
Is there an example I can look at that does something similar? Or is
this the wrong way to look at the problem? Basically, I want to add
the function call operator to my expressions, but only to expressions
of certain forms. My thinking is, if I only wrap expressions of that
certain form with my expression class, I should be OK, no?

Manjunath

> Suggestion: when you are having problems with evaluating a transform, try
> adding an MPL assertion that the expression you're passing to it actually
> matches the grammar.
>
> HTH,
>
> --
> Eric Niebler
> BoostPro Computing
> http://www.boostpro.com
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
>


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