digitalmars.D.learn - How use "toHash" without cast
- Namespace (7/7) Jun 20 2012 hello, iI have written a template vector class. Now I need to
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (7/13) Jun 20 2012 I don't really understand the problem. I think you need to show some cod...
- Namespace (79/79) Jun 20 2012 That is my Code:
- Jonathan M Davis (11/104) Jun 20 2012 Eventually, toHash will have to be @safe const pure nothrow, but I don't...
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (11/115) Jun 20 2012 It's actually @trusted as per the docs. I do not know why DMD infers
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (6/126) Jun 20 2012 Filed a bug: http://d.puremagic.com/issues/show_bug.cgi?id=8275
- Namespace (4/10) Jun 21 2012 Yes, it's already trusted.
- Jonathan M Davis (15/30) Jun 21 2012 Apparently, when you override an @trusted method, the method in the deri...
- Namespace (2/2) Jun 21 2012 I see, a bit confusing but I think I understand.
hello, iI have written a template vector class. Now I need to rewrite the tohash function in dependence to the coords. But i have no clue because it doesn't allow any casts or convertions, because its a trusted method. Because of that i cannot override toHash for float, real or double. Any ideas?
Jun 20 2012
On 21-06-2012 00:31, Namespace wrote:hello, iI have written a template vector class. Now I need to rewrite the tohash function in dependence to the coords. But i have no clue because it doesn't allow any casts or convertions, because its a trusted method. Because of that i cannot override toHash for float, real or double. Any ideas?I don't really understand the problem. I think you need to show some code. trusted doesn't actually affect whether you can cast or convert anything. -- Alex Rønne Petersen alex lycus.org http://lycus.org
Jun 20 2012
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...
Jun 20 2012
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
Jun 20 2012
On 21-06-2012 03:13, Jonathan M Davis wrote:On Thursday, June 21, 2012 00:43:49 Namespace wrote: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); } -- Alex Rønne Petersen alex lycus.org http://lycus.orgThat 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
Jun 20 2012
On 21-06-2012 04:30, Alex Rønne Petersen wrote:On 21-06-2012 03:13, Jonathan M Davis wrote:Filed a bug: http://d.puremagic.com/issues/show_bug.cgi?id=8275 -- Alex Rønne Petersen alex lycus.org http://lycus.orgOn Thursday, June 21, 2012 00:43:49 Namespace wrote: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); }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
Jun 20 2012
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); }Yes, it's already trusted. If I write " trusted const pure nothrow" it works fine, but if i write "const pure nothrow" not. Why? I thought the compiler is orientating at the base method which is overriden.
Jun 21 2012
On Thursday, June 21, 2012 09:48:52 Namespace wrote:Apparently, when you override an trusted method, the method in the derived class is inferred to be safe - which makes sense when you think about it, since the derived class' function hasn't done anything system. If it calls the base class' version, which is trusted, then it can be safe. So, as long as it doesn't do anything system itself, it can be safe. However, since the compiler doesn't infer any attributes from the derived class' function's body (since it's not templated), if you do any system stuff in there, it'll give you a compilation error rather than treating it as system - though that makes sense too, since having a derived class function with worse guarantees than a base class function isn't valid. So, even if the attributes _were_ inferred from the function's body, it would _still_ have to give you an error, since the body would be system when it needed to be at least trusted. http://d.puremagic.com/issues/show_bug.cgi?id=8275 - Jonathan M DavisIt'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); }Yes, it's already trusted. If I write " trusted const pure nothrow" it works fine, but if i write "const pure nothrow" not. Why? I thought the compiler is orientating at the base method which is overriden.
Jun 21 2012
I see, a bit confusing but I think I understand. Thank you. :)
Jun 21 2012