$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
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