traits: how to split parametrized type into basic type and parameters

Martin Kinkelin noone at spam.com
Mon Feb 14 13:09:04 PST 2011


> Did you try without the cast? Since we know that _data components can
> be cast to r._data elements, the compiler should take care of that for
> you.

Nope, I didn't try that because, for instance, floats shouldn't be
implicitly castable to ints.

> You can also use cast(float2) f3 to get rid of the third coordinate.
> That's cool.

Yep, in case you want a copy. Additionally, I defined a to!(int d2)
method which returns a reference to the lower-dimensional components
(downcasting):

ref Vector!(d2,T) to(int d2)()
    if (d2 <= d)
{
    return *(cast(Vector!(d2,T)*) &this);
}

allowing for:
auto f3 = float3(1,2,3);
f3.to!2() = float2(-1,-2);
assert(f3 == float3(-1,-2,3));

> You could also have a look at opAssign (for v1 = v2 expresions), and
> alias this.

Well, _data is private (and afaik I cannot modify a symbol's
visibility via alias), so I overloaded the indexing operators (as well
as most of the other operators as well). I only use _data here
directly to aid the compiler and facilitate optimizations. But thanks
for pointing 'alias ... this' out, I was looking for a concept similar
to implicit type conversions in C++.

The vector data is actually defined like this in Vector!(d,T):

union
{
    private T[d] _data;
    public struct
    {
                           T x;
        static if (d >= 2) T y;
        static if (d >= 3) T z;
        static if (d >= 4) T w;
    }
}

So from the outside, components are accessed either via indexing or
via x,y,z and w (analog to HLSL/GLSL). I also added some downcasting
shortcuts via properties, e.g.:

auto f4 = float4(1,2,3,4);
auto r = f4.xyz + 2.0; // downcast f4 to float3 w/o copying, add double
assert(r == double3(3,4,5)); // element type of r is double :)


Martin


More information about the Digitalmars-d-learn mailing list