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









Adam D. Ruppe <destructionator gmail.com> 