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

Boost-users list run by williamkempf at, kalb at, bjorn.karlsson at, gregod at, wekempf at