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
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
, proto::nary_expr<_, proto::vararg >
>
{};
template
struct simd_expr;
template<typename T>
struct simd_generator
{
template<typename Sig>
struct result;
template
struct result
{
typedef simd_expr type;
};
template<typename Expr>
simd_expr const operator()(Expr const &expr) const
{
simd_expr that = {expr};
return that;
}
};
template<typename T>
struct simd_domain
: proto::domain
{};
template
struct simd_expr
{
BOOST_PROTO_EXTENDS(Expr, simd_expr, simd_domain<T>)
};
simd_expr::type, char> const simd_char
= {{{}}};
simd_expr::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