[proto] Writing a transform to get at an inner constant of a transform result type

Hi, The subject is probably very confusing. I'm back to playing with a proto-based library for vector types. I have a basic underlying vector template, simd_impl: template <typename T> struct simd_impl { static const size_t size = VECTOR_BYTES / sizeof(T); // data }; And I have a grammar, Simd struct Simd : proto::or_< SimdLiteral, SimdUnary, SimdVectorBinary, SimdMixedBinary
{};
where SimdLiteral is an enumeration of proto::terminal<simd_impl<T>> where T are various underlying types, SimdUnary are unary operations, SimdVectorBinary are combinations of two vectors, and SimdMixedBinary are combinations of vectors with scalars. SimdVectorBinary is currently defined approximately like this: struct SimdVectorBinary : proto::or_< proto::when<proto::plus<Simd, Simd>, exec::simd_plus(Simd(_left), Simd(_right))>, // more operators here
{};
Now I want to validate, in the grammar, that you only add two vectors of the same arity together. That is, I'm fine with adding simd_impl<long> and simd_impl<int> together if they have the same size, because both have the same number of elements, but adding simd_impl<short> and simd_impl<int> together doesn't work, as one has twice the number of elements as the other. But I can't figure out how to write a grammar that validates this. I've started something like this: struct VSizeMatches : proto::if_<mpl::equal_to<Arity(proto::_left), Arity(proto::right)>()> {}; but I think that's wrong, and I can't figure out how to write Arity anyway. Basically, I have to find the simd_impl<T> type that the result of my Simd transform has and then access the size member. But I'm kinda afraid that this will get me into a world of trouble with prematurely instantiated templates. Any advice? Sebastian

On Tue, Oct 12, 2010 at 12:14 PM, Sebastian Redl <sebastian.redl@getdesigned.at> wrote:
Hi,
The subject is probably very confusing. I'm back to playing with a proto-based library for vector types. I have a basic underlying vector template, simd_impl:
template <typename T> struct simd_impl { static const size_t size = VECTOR_BYTES / sizeof(T); // data };
And I have a grammar, Simd
struct Simd : proto::or_< SimdLiteral, SimdUnary, SimdVectorBinary, SimdMixedBinary
{};
where SimdLiteral is an enumeration of proto::terminal<simd_impl<T>> where T are various underlying types, SimdUnary are unary operations, SimdVectorBinary are combinations of two vectors, and SimdMixedBinary are combinations of vectors with scalars.
SimdVectorBinary is currently defined approximately like this:
struct SimdVectorBinary : proto::or_< proto::when<proto::plus<Simd, Simd>, exec::simd_plus(Simd(_left), Simd(_right))>, // more operators here
{};
Now I want to validate, in the grammar, that you only add two vectors of the same arity together. That is, I'm fine with adding simd_impl<long> and simd_impl<int> together if they have the same size, because both have the same number of elements, but adding simd_impl<short> and simd_impl<int> together doesn't work, as one has twice the number of elements as the other. But I can't figure out how to write a grammar that validates this.
I've started something like this:
struct VSizeMatches : proto::if_<mpl::equal_to<Arity(proto::_left), Arity(proto::right)>()> {};
but I think that's wrong, and I can't figure out how to write Arity anyway. Basically, I have to find the simd_impl<T> type that the result of my Simd transform has and then access the size member. But I'm kinda afraid that this will get me into a world of trouble with prematurely instantiated templates.
Any advice?
I am assuming Simd returns some simd_impl, but i hope you get the idea if not. given that i could imagine something like that: template <typename Lhs, typename Rhs> struct compatible : mpl::bool_<Lhs::size == Rhs::size> {}; struct SimdVectorBinary : proto::or_< proto::when< proto::and_< proto::plus<Simd, Simd> , proto::if_<compatible<Simd(_left), Simd(_right)>()> > , exec::simd_plus(Simd(_left), Simd(_right))> > > // more operators here
{};
Note, no premature templates where instantiated, cause you want to recurse down your tree eventually.

On 12.10.2010 13:07, Thomas Heller wrote:
template <typename Lhs, typename Rhs> struct compatible : mpl::bool_<Lhs::size == Rhs::size> {};
struct SimdVectorBinary : proto::or_< proto::when< proto::and_< proto::plus<Simd, Simd> , proto::if_<compatible<Simd(_left), Simd(_right)>()> > , exec::simd_plus(Simd(_left), Simd(_right))> > > // more operators here
{};
Thank you, works perfectly! Sebastian
participants (2)
-
Sebastian Redl
-
Thomas Heller