traits: how to split parametrized type into basic type and parameters
Philippe Sigaud
philippe.sigaud at gmail.com
Mon Feb 14 05:18:21 PST 2011
On Mon, Feb 14, 2011 at 13:09, Martin Kinkelin <noone at spam.com> wrote:
> Hi Philippe,
>
> thank you very much!
You're welcome.
> I added your isVector!T template as well as the two aliases.
> opCast!NewType is implemented like this:
>
> V opCast(V)() if (isVector!V)
> // parameters {d2,T2} of V are checked when instantiating V: d2 >= 1 && isNumeric!T2
> {
> V r;
> foreach (i; 0 .. (d < V.dim ? d : V.dim))
Nice one, the compile-time ternary operator.
> r._data[i] = cast(V.Type) _data[i];
> return r;
> }
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.
> thereby allowing to cast to arbitrary component types as well as to arbitrary
> dimensions. Works like a charm:
>
> auto f3 = float3(1,2,3);
> assert((cast(double2) f3) == double2(1,2));
> assert((cast(int3) f3) == int3(1,2,3));
> assert((cast(int4) f3) == int4(1,2,3,0));
You can also use cast(float2) f3 to get rid of the third coordinate.
That's cool.
You could also have a look at opAssign (for v1 = v2 expresions), and alias this.
Try putting:
alias _data this;
into your Vector code. That way a Vector will 'become' a T[d] when it
makes sense. You gain direct access to the underlying coordinates:
v[2] instead of v._data[2]
This allows to use functions taking T[n] as an argument: pass them a
Vector, it will expose its _data member. This should affect casting
also.
Another D idiom would be to define an .as!(SomeType) inner template
that does the casting. Some people do not like cast. Though, as you
saw, opCast can tightly control what kind of casting you authorize.
struct Vector() {
(...)
auto as(Target)() if (isVector!Target && Target.dim < ... etc)
{
Target target;
(fill the target)
return target;
}
Very close to your opCast, really. Usage would be very close also:
assert( f3.as!(double2) == double2(1,2) );
assert( f3.as!(int3) == int3(1,2,3) );
Philippe
More information about the Digitalmars-d-learn
mailing list