Boost logo

Boost Users :

Subject: Re: [Boost-users] [proto] Question on grammar and operator overloading
From: Eric Niebler (eric_at_[hidden])
Date: 2009-10-06 08:56:46


Hal Finkel wrote:
> Hello,
>
> I'm writing a complex number class using boost::proto by extending
> proto::terminal< boost::array<_, 2> >. I've attached a copy of my
> current code, which compiles, runs, and (at least with both g++ and icc
> on my machine) demonstrates a significant speed improvement compared to
> std::complex.
>
> However, there is (at least) one thing which don't work as it should:
>
> In the grammar I have to specify lazy_complex< double > instead of
> lazy_complex< _ >, otherwise the compiler cannot find proto's operator
> overloads, why?

In your grammar, lazy_complex<_> is equivalent to proto::terminal<
boost::array< _, 2 > >; that is, they describe the same set of
expression types. Unfortunately, Proto cannot handle a grammar like
that. The problem is the "2". Proto can only peer inside template
instantiations as long as none of the template parameters are non-type
template parameters.

There are a number of hackish solutions. You could define your own type:

   template<typename T, typename Size = mpl::int_<2> >
   struct my_array : boost::array< T, Size::value > {};

and use my_array throughout. Then your grammar becomes proto::terminal<
boost::array< _, mpl::int_<2> > >, or just proto::terminal<
boost::array< _, _ > >.

The other alternative is to define a predicate that matches boost::array
types:

   template<typename T>
   struct is_boost_array : mpl::false_ {};
   template<typename T, int I>
   struct is_boost_array<boost::array<T,I> > : mpl::true_ {};

and change your grammar to:

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

Either way. You could even just use some other terminal type besides
boost::array. std::complex or std::pair would do.

> Note: This code will not compile under 1.37, but will compile under
> 1.40, because of some issue in 1.37 which manifests itself as a problem
> with the overloading of the '<<' operator. I've not tested the releases
> in between 1.37 and 1.40.

Yes, I've fixed some bugs in this area.

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