How use "toHash" without cast

Alex Rønne Petersen alex at lycus.org
Wed Jun 20 19:35:17 PDT 2012


On 21-06-2012 04:30, Alex Rønne Petersen wrote:
> On 21-06-2012 03:13, Jonathan M Davis wrote:
>> On Thursday, June 21, 2012 00:43:49 Namespace wrote:
>>> That is my Code:
>>>
>>> [code]
>>> class Vector2D(T) {
>>> private:
>>> static Vector2D!(T) CastFromObject(Object o) {
>>> import std.typetuple;
>>>
>>> foreach (Type; TypeTuple!(byte, ubyte, short, ushort, int,
>>> uint, long, ulong, float, double, real)) {
>>> if (auto vec = cast(Vector2D!(Type)) o) {
>>> return cast(Vector2D!(T)) vec;
>>> }
>>> }
>>>
>>> return null;
>>> }
>>>
>>> public:
>>> T x;
>>> T y;
>>>
>>> this(T x, T y) {
>>> this.x = x;
>>> this.y = y;
>>> }
>>>
>>> static Vector2D!(T) opCall(T x, T y) {
>>> return new Vector2D!(T)(x, y);
>>> }
>>>
>>> float Summe() const pure nothrow {
>>> return this.x + this.y;
>>> }
>>>
>>> override bool opEquals(Object o) const {
>>> if (o is null) {
>>> debug {
>>> writeln("Object is null ;)");
>>> }
>>>
>>> return false;
>>> }
>>>
>>> const Vector2D!(T) vec = CastFromObject(o);
>>>
>>> if (vec is this) {
>>> return true;
>>> }
>>>
>>> return (vec.x == this.x)&& (vec.y == this.y);
>>> }
>>>
>>> override hash_t toHash() const pure nothrow {
>>> return this.x + this.y;
>>> }
>>>
>>> override int opCmp(Object o) const {
>>> if (o is null) {
>>> return -1;
>>> }
>>>
>>> const Vector2D vec = CastFromObject(o);
>>>
>>> if (vec is this) {
>>> return 0;
>>> }
>>>
>>> if (this.Summe()> vec.Summe()) {
>>> return 1;
>>> }
>>>
>>> if (this.Summe()< vec.Summe()) {
>>> return -1;
>>> }
>>>
>>> return 0;
>>> }
>>>
>>> override string toString() const {
>>> return "Vector2D!(" ~ T.stringof ~ ")(" ~ to!(string)(this.x) ~
>>> ", " ~ to!(string)(this.y) ~ ")";
>>> }
>>> }
>>>
>>> [/code]
>>>
>>> I have dmd 2.059 and with my current version of toHash i get the
>>> compiler errors, that he cannot implicit convert from float,
>>> real, double, long and so on to uint.
>>> I cannot solve the problem with a simple cast or to!uint because
>>> then he said that casts form float to uint are not allowed or
>>> that to! isn't trusted and nothrow. I hate such annoying errors...
>>
>> Eventually, toHash will have to be @safe const pure nothrow, but I
>> don't think
>> that the compiler requires that yet (though work was being done on
>> that, so it
>> may). You didn't mark toHash as @safe though, so it may be inferring
>> it from
>> Object (I believe that it _has_ been changed so that attributes are now
>> inferred from the base class declarations when overriding). So, toHash
>> may be
>> being inferred as @safe. Try marking toHash as @trusted. If that
>> doesn't work,
>> then move its implementation into another function which you mark as
>> @trusted
>> and have toHash call it (since @safe can call @trusted but can't do
>> @system
>> stuff, unlike @trusted).
>>
>> - Jonathan M Davis
>
> It's actually @trusted as per the docs. I do not know why DMD infers
> that to be @safe.....
>
> In any case, the solution here is this:
>
> override hash_t toHash() @trusted const pure nothrow {
> return cast(hash_t)(this.x + this.y);
> }
>

Filed a bug: http://d.puremagic.com/issues/show_bug.cgi?id=8275

-- 
Alex Rønne Petersen
alex at lycus.org
http://lycus.org


More information about the Digitalmars-d-learn mailing list