Boost logo

Boost Users :

Subject: Re: [Boost-users] [Proto] Extracting types of sub-expression in transform
From: Eric Niebler (eric_at_[hidden])
Date: 2008-10-18 16:07:46


Joel Falcou wrote:
> Eric Niebler a écrit :
>> This question has come up a couple of times. The solution isn't very
>> pretty ... write a grammar that allows expressions with incompatible
>> terminals, and then write a separate transform that checks the
>> terminals for compatibility. This issue came up during Proto's review
>> and I posted some example code here (see the SameTerminals transform):
> Well I thought to have template grammar ;)
> aka :
>
> template<class T> struct simd_grammar : terminal< simd<T> > .... {};
>
> Then vec<T> extends a domain which is based on simd_grammar<T>.
> Not sure it's more elegant though. I'll dig this during the week.

Ah, well that's a clever thought. Here's some code to get you started ...

     #include <boost/proto/proto.hpp>

     namespace mpl = boost::mpl;
     namespace proto = boost::proto;
     using proto::_;

     template<typename T>
     struct simd
     {};

     template<typename T>
     struct simd_grammar
       : proto::or_<
             proto::terminal<simd<T> >
           , proto::nary_expr<_, proto::vararg<simd_grammar<T> > >
>
     {};

     template<typename Expr, typename T>
     struct simd_expr;

     template<typename T>
     struct simd_generator
     {
         template<typename Sig>
         struct result;

         template<typename This, typename Expr>
         struct result<This(Expr)>
         {
             typedef simd_expr<Expr, T> type;
         };

         template<typename Expr>
         simd_expr<Expr, T> const operator()(Expr const &expr) const
         {
             simd_expr<Expr, T> that = {expr};
             return that;
         }
     };

     template<typename T>
     struct simd_domain
       : proto::domain<simd_generator<T>, simd_grammar<T> >
     {};

     template<typename Expr, typename T>
     struct simd_expr
     {
         BOOST_PROTO_EXTENDS(Expr, simd_expr, simd_domain<T>)
     };

     simd_expr<proto::terminal<simd<char> >::type, char> const simd_char
= {{{}}};
     simd_expr<proto::terminal<simd<int> >::type, int> const simd_int =
{{{}}};

     int main()
     {
         (simd_char + simd_char) * simd_char;

         (simd_int + simd_int) * simd_int;

         // ERROR, these are in different domains
         // (simd_char + simd_char) * simd_int;
     }

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