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