 # Boost :

Subject: Re: [boost] [proto] Writing a transform to get at an inner constant of a transform result type
From: Thomas Heller (thom.heller_at_[hidden])
Date: 2010-10-12 07:07:39

On Tue, Oct 12, 2010 at 12:14 PM, Sebastian Redl
<sebastian.redl_at_[hidden]> 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.
>

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