April 19, 2012
And which version do you use? I use DMD 2.059 on Windows 7.

I get this compile error with your code
object.Error: Access Violation
----------------
41943C
4192C7
40F75B
40BE90
40BECA
40BAEB
4206E1

If i comment out this part

    if (vs2 == vf) {
        writeln("equal");
    }


it works fine.
April 19, 2012
On Thursday, April 19, 2012 10:48:45 Namespace wrote:
> And which version do you use? I use DMD 2.059 on Windows 7.
> 
> I get this compile error with your code
> object.Error: Access Violation
> ----------------
> 41943C
> 4192C7
> 40F75B
> 40BE90
> 40BECA
> 40BAEB
> 4206E1
> 
> If i comment out this part
> 
>      if (vs2 == vf) {
>          writeln("equal");
>      }
> 
> 
> it works fine.

I tried both 2.058 and the latest from github. But I'm on 64-bit Linux, so it's possible that you're seeing a Windows-specific issue.

- Jonathan M Davis
April 19, 2012
On Thursday, 19 April 2012 at 09:05:13 UTC, Jonathan M Davis wrote:
> On Thursday, April 19, 2012 10:48:45 Namespace wrote:
>> And which version do you use? I use DMD 2.059 on Windows 7.
>> 
>> I get this compile error with your code
>> object.Error: Access Violation
>> ----------------
>> 41943C
>> 4192C7
>> 40F75B
>> 40BE90
>> 40BECA
>> 40BAEB
>> 4206E1
>> 
>> If i comment out this part
>> 
>>      if (vs2 == vf) {
>>          writeln("equal");
>>      }
>> 
>> 
>> it works fine.
>
> I tried both 2.058 and the latest from github. But I'm on 64-bit Linux, so
> it's possible that you're seeing a Windows-specific issue.
>
> - Jonathan M Davis

A specific Windows bug with opEquals and opCast? My Windows is 64 bit also.
Can anyone reproduce this behaviour with Windows?
I will download dmd later again to check if i have an older version or beta.
April 19, 2012
> I will download dmd later again to check if i have an older version or beta.

After download dmd again it get still the same compile error.

April 19, 2012
On Thursday, April 19, 2012 11:15:23 Namespace wrote:
> A specific Windows bug with opEquals and opCast?

Maybe. Certainly, it's working on my Linux box, so if you're compiling the same code that I am, and you're using 2.059, it definitely sounds like it's a Windows-specific bug.

> My Windows is 64 bit also.

The fact that it's 64-bit shouldn't matter on Windows, because dmd can't generate 64-bit code on Windows yet.

- Jonathan M Davis
April 19, 2012
On Thursday, 19 April 2012 at 09:22:24 UTC, Jonathan M Davis wrote:
> On Thursday, April 19, 2012 11:15:23 Namespace wrote:
>> A specific Windows bug with opEquals and opCast?
>
> Maybe. Certainly, it's working on my Linux box, so if you're compiling the
> same code that I am, and you're using 2.059, it definitely sounds like it's a
> Windows-specific bug.
>
>> My Windows is 64 bit also.
>
> The fact that it's 64-bit shouldn't matter on Windows, because dmd can't
> generate 64-bit code on Windows yet.
>
> - Jonathan M Davis

Ok. And what schould i do now? Any patches available for that?
Otherwise i must cast up to dmd 2.060 explicit as you do in the first if condition.
April 19, 2012
On Thursday, April 19, 2012 11:27:20 Namespace wrote:
> On Thursday, 19 April 2012 at 09:22:24 UTC, Jonathan M Davis
> 
> wrote:
> > On Thursday, April 19, 2012 11:15:23 Namespace wrote:
> >> A specific Windows bug with opEquals and opCast?
> > 
> > Maybe. Certainly, it's working on my Linux box, so if you're
> > compiling the
> > same code that I am, and you're using 2.059, it definitely
> > sounds like it's a
> > Windows-specific bug.
> > 
> >> My Windows is 64 bit also.
> > 
> > The fact that it's 64-bit shouldn't matter on Windows, because
> > dmd can't
> > generate 64-bit code on Windows yet.
> > 
> > - Jonathan M Davis
> 
> Ok. And what schould i do now? Any patches available for that? Otherwise i must cast up to dmd 2.060 explicit as you do in the first if condition.

Actually, I just re-ran the code on my box, and it does segfault. Either I forgot to run it or I didn't notice the segfault, since it isn't as obvious on Linux with all of the other output:

vs.x: 23, vs.y: 42
raw.Vector2D!(short).Vector2D
raw.Vector2D!(short).Vector2D
equal
raw.Vector2D!(float).Vector2D
null
Segmentation fault

What's going wrong is that this cast in opEquals:

        Vector2D!(T) vec = cast(Vector2D!(T)) o;

is failing. The result is null. That's what you'd expect if the built-in cast is being used rather than opCast. And if I put print statements in all three of the opCasts, none of them are called.

Upon thinking further about it, I believe that the problem is that you're casting from _Object_ rather than one of the other instantiations of Vector2D, and Object obviously doesn't define an opCast for your type. So, it uses the normal, built-in cast, and it fails, because the type that you're attempting to cast to is not derived from the one that you're trying to cast to. If you could get it to its actual type and _then_ cast it, you could do it. But that's a rather nasty problem. After messing with it a bit though, I do believe that I've come up with a solution. Change opEquals to this:

    override bool opEquals(Object o) const {
        writeln(o);

        auto vec = castFromObject(o);
        assert(vec !is null);

        writeln(vec);

        return vec.x == this.x && vec.y == this.y;
    }


    private static Vector2D castFromObject(Object o)
    {
        import std.typetuple;
        foreach(U; TypeTuple!(byte, ubyte, short, ushort, int, uint,
                              long, ulong, float, double, real))
        {
            if(auto vec = cast(Vector2D!U)o)
                return cast(Vector2D)vec;
        }

        return null;
    }

I believe that that takes care of the problem.

By the way, inside of a template, you don't need to reuse the template arguments when refering to it. So, inside of Vector2D, you can use Vector2D instead of Vector2D!T.

- Jonathan M Davis
April 19, 2012
A great thanks to you. But any of my tries to make
"const Vector2D vec = castFromObject(o);" possible i get an error. Didn't i must only write "private static const(Vector2D) castFromObject(Object o)" instead of "private static Vector2D castFromObject(Object o)"?
April 19, 2012
It seems that i can't cast if i want a const Vector2D, neither with castFromtObject nor with opCast. If i do it i get a very long list of compile errors. It's no problem because i can deal without cast to const but it would be usefull if you can show me how i can use both, const and normal casts.
April 19, 2012
On Thursday, 19 April 2012 at 15:48:29 UTC, Namespace wrote:
> It seems that i can't cast if i want a const Vector2D, neither with castFromtObject nor with opCast. If i do it i get a very long list of compile errors. It's no problem because i can deal without cast to const but it would be usefull if you can show me how i can use both, const and normal casts.

For example in this case

void foo(T)(const Vector2D!(T) vec) {
	bar(cast(Vector2s) vec);
}

void bar(const Vector2s vec) {

}

const Vector2f vf = Vector2f(23, 42);

Vector2s vs = Vector2s(vf);
Vector2s vs_ = cast(Vector2s) vf;

Vector2f vf_ = cast(Vector2f) vs;

Vector2s vs2 = Vector2s(23, 42);

if (vs2 == vf) {
	writeln("equal!");
}

foo(vf);
foo(vs);

i get this compiler errors:

cast.d(323): Error: template cast.Vector2D!(short).Vector2D.opCast matches more
than one template declaration, cast.d(285):opCast(U) if (is(Unqual!(U) == Vector
2D!(byte)) || is(Unqual!(U) == Vector2D!(ubyte)) || is(Unqual!(U) == Vector2D!(s
hort)) || is(Unqual!(U) == Vector2D!(ushort)) || is(Unqual!(U) == Vector2D!(int)
) || is(Unqual!(U) == Vector2D!(uint)) || is(Unqual!(U) == Vector2D!(long)) || i
s(Unqual!(U) == Vector2D!(ulong)) || is(Unqual!(U) == Vector2D!(float)) || is(Un
qual!(U) == Vector2D!(double)) || is(Unqual!(U) == Vector2D!(real))) and cast.d(
306):opCast(T) if (isImplicitlyConvertible!(typeof(this),const(T)))
cast.d(360): Error: template instance cast.foo!(short) error instantiating

I can avoid them if i change bar to

void foo(T)(const Vector2D!(T) vec) {
	static if (is(typeof(vec.x) == const float)) {
		bar(cast(Vector2s) vec);
	} else {
		bar(vec);
	}
}

Of course i must check for more then only "const float" but it is only a test case.
So it seems i have to change the cast operator. But i have no idea how.
I thougth that "inout" would help me, but i was wrong. So maybe you have some ideas?