digitalmars.D.learn - Qualified class opEquals()
- Per =?UTF-8?B?Tm9yZGzDtnc=?= (122/122) Dec 24 2018 Is it in the following code possible to make the statement
- Paul Backus (6/10) Dec 24 2018 No, because equality comparison between classes lowers to
- Per =?UTF-8?B?Tm9yZGzDtnc=?= (3/5) Dec 25 2018 This is a severe limitation. Are there any plans on fixing this
- Adam D. Ruppe (2/4) Dec 25 2018 Ignore opEquals and use your own interface.
- Jonathan M Davis (6/11) Dec 27 2018 ProtoObject _is_ the proposed fix, but if you want to use Object's opEqu...
Is it in the following code possible to make the statement assert(car1 == car2); in the function testEqual() compile in a ` safe pure nothrow nogc context`? Code: import core.internal.hash : hashOf; /** Hash that distinguishes `Expr(X)` from `NounExpr(X)`. * * See_Also: https://forum.dlang.org/post/lxqoknwuujbymolnlyfw forum.dlang.org */ hash_t hashOfPolymorphic(Class)(Class aClassInstance) trusted pure nothrow nogc if (is(Class == class)) { assert(Class.alignof == 8); return (cast(hash_t)(cast(void*)typeid(Class)) >> 3) ^ hashOf(aClassInstance); } version(unittest) { private static: class Thing { property override bool opEquals(const scope Object that) const safe pure nothrow nogc { if (typeid(this) !is typeid(that)) { return false; } assert(0); } property final bool opEquals(const scope typeof(this) that) const safe pure nothrow nogc { assert(0); } } class Expr : Thing { safe pure nothrow nogc: alias Data = string; this(Data data) { this.data = data; } property override bool opEquals(const scope Object that) const safe pure nothrow nogc { if (typeid(this) !is typeid(that)) { return false; } return data == (cast(typeof(this))(that)).data; } property final bool opEquals(const scope typeof(this) that) const safe pure nothrow nogc { if (typeid(this) !is typeid(that)) { return false; } return data == (cast(typeof(this))(that)).data; } property override hash_t toHash() const safe pure nothrow nogc { return hashOf(data); } Data data; } class NounExpr : Expr { safe pure nothrow nogc: this(Data data) { super(data); } property override hash_t toHash() const safe pure nothrow nogc { return hashOf(data); } } class Year : Thing { safe pure nothrow nogc: alias Data = long; property override hash_t toHash() const safe pure nothrow nogc { return hashOf(data); } Data data; } } safe pure nothrow unittest { auto car1 = new Expr("car"); auto car2 = new Expr("car"); auto bar1 = new Expr("bar"); auto ncar = new NounExpr("car"); void testEqual() safe pure nothrow nogc { assert(car1.opEquals(car2)); assert(!car1.opEquals(bar1)); assert(!car2.opEquals(bar1)); // TODO should compile: assert(car1 == car2); assert(hashOf(car1) == hashOf(car2)); assert(hashOfPolymorphic(car1) == hashOfPolymorphic(car2)); } void testDifferent1() safe pure nothrow nogc { assert(!car1.opEquals(bar1)); // TODO should compile: assert(car1 != bar1); assert(hashOf(car1) != hashOf(bar1)); assert(hashOfPolymorphic(car1) != hashOfPolymorphic(bar1)); } void testDifferent2() safe pure nothrow nogc { assert(hashOf(car1) == hashOf(ncar)); assert(hashOfPolymorphic(car1) != hashOfPolymorphic(ncar)); } testEqual(); testDifferent1(); testDifferent2(); }
Dec 24 2018
On Monday, 24 December 2018 at 22:58:03 UTC, Per Nordlöw wrote:Is it in the following code possible to make the statement assert(car1 == car2); in the function testEqual() compile in a ` safe pure nothrow nogc context`?No, because equality comparison between classes lowers to `object.opEquals` [1], which takes both parameters as `Object`. If you call car1.opEquals(car2) directly, it should work. [1] https://github.com/dlang/druntime/blob/master/src/object.d#L1051
Dec 24 2018
On Tuesday, 25 December 2018 at 00:32:55 UTC, Paul Backus wrote:No, because equality comparison between classes lowers to `object.opEquals` [1], which takes both parameters as `Object`.This is a severe limitation. Are there any plans on fixing this or do I have to wait for Andrei's proposed ProtoObject?
Dec 25 2018
On Tuesday, 25 December 2018 at 14:27:39 UTC, Per Nordlöw wrote:This is a severe limitation. Are there any plans on fixing this or do I have to wait for Andrei's proposed ProtoObject?Ignore opEquals and use your own interface.
Dec 25 2018
On Tuesday, December 25, 2018 7:27:39 AM MST Per Nordlöw via Digitalmars-d- learn wrote:On Tuesday, 25 December 2018 at 00:32:55 UTC, Paul Backus wrote:ProtoObject _is_ the proposed fix, but if you want to use Object's opEquals in safe code, you can always create a wrapper function that's marked trusted and call that instead. - Jonathan M DavisNo, because equality comparison between classes lowers to `object.opEquals` [1], which takes both parameters as `Object`.This is a severe limitation. Are there any plans on fixing this or do I have to wait for Andrei's proposed ProtoObject?
Dec 27 2018