Boost logo

Boost :

Subject: Re: [boost] [proto] Problems with operator <<
From: Eric Niebler (eric_at_[hidden])
Date: 2011-08-26 13:11:04


On 8/26/2011 12:53 PM, John Maddock wrote:
>> Yes. You want:
>>
>> // Match any integral terminal
>> proto::and_<
>> proto::terminal< proto::_ >,
>> proto::if_ < boost::is_integral< proto::_value >() >
>> >
>
> That works a treat, thanks!
>
> Now I have another question about refining those terminals, when I have:
>
> struct big_number_grammar
> : proto::or_<
> proto::terminal<proto::_>
> , proto::plus< big_number_grammar, big_number_grammar >
> , proto::multiplies< big_number_grammar, big_number_grammar >
> , proto::minus< big_number_grammar, big_number_grammar >
> , proto::divides< big_number_grammar, big_number_grammar >
> , proto::unary_plus< big_number_grammar >
> , proto::negate< big_number_grammar >
> , proto::or_<
> proto::modulus<big_number_grammar, big_number_grammar>
> , proto::shift_left<big_number_grammar, integer_terminal>
> , proto::shift_right<big_number_grammar, integer_terminal>
> , proto::bitwise_and<big_number_grammar, big_number_grammar>
> >
> >
> {};
>
> Then the operator overloads work just fine, but if I try and refine it to:
>
> struct big_number_grammar
> : proto::or_<
> proto::terminal<boost::math::big_number<proto::_> >
> , proto::plus< big_number_grammar, big_number_grammar >
> , proto::multiplies< big_number_grammar, big_number_grammar >
> , proto::minus< big_number_grammar, big_number_grammar >
> , proto::divides< big_number_grammar, big_number_grammar >
> , proto::unary_plus< big_number_grammar >
> , proto::negate< big_number_grammar >
> , proto::or_<
> proto::modulus<big_number_grammar, big_number_grammar>
> , proto::shift_left<big_number_grammar, integer_terminal>
> , proto::shift_right<big_number_grammar, integer_terminal>
> , proto::bitwise_and<big_number_grammar, big_number_grammar>
> >
> >
> {};
>
> Then trying to add two big_number's results in:
>
> 1>m:\data\boost\sandbox\big_number\libs\math\ide\extended_real\scrap\scrap.cpp(24):
> error C2893: Failed to specialize function template 'const
> boost::proto::detail::enable_binary<boost::proto::domainns_::deduce_domain,boost::proto::detail::not_a_grammar,boost::mpl::or_<boost::proto::is_extension<T>,boost::proto::is_extension<Right>>,boost::proto::tag::plus,const
> Left,const Right>::type boost::proto::exprns_::operator +(const Left
> &,const Right &)'
> With the following template arguments:
> 'boost::math::mpf_real_50'
> 'boost::math::mpf_real_50'
>
> Where mpf_real_50 is just a typedef for "big_number<some_backend_type>".
>
> Is there anything obvious I'm doing wrong here? I'm using VC10 BTW, and
> big_number inherits from proto::terminal<big_number*> in case that makes
> any difference.

That last bit does make a difference. Proto grammar matching keys off
the underlying proto expression type. So change this:

  proto::terminal<boost::math::big_number<proto::_> >

to this:

  proto::terminal<big_number*>

(Not sure exactly what you mean by "big_number inherits from
proto::terminal<big_number*>. You clearly don't mean that. You mean
either i/ big_number extends proto::terminal<big_number*>::type or ii/
big_number inherits from proto::terminal<big_number*>::type. Either way,
the answer is the same.)

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

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk