Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
December 24, 2018 Qualified class opEquals() | ||||
---|---|---|---|---|
| ||||
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(); } |
December 25, 2018 Re: Qualified class opEquals() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Per Nordlöw | 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 |
December 25, 2018 Re: Qualified class opEquals() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Paul Backus | 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?
|
December 25, 2018 Re: Qualified class opEquals() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Per Nordlöw | 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.
|
December 27, 2018 Re: Qualified class opEquals() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Per Nordlöw | 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:
> > 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?
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 Davis
|
Copyright © 1999-2021 by the D Language Foundation