View source code
Display the source code in object.d from which this
page was generated on github.
Report a bug
If you spot a problem with this page, click here to create a
Bugzilla issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page.
Requires a signed-in GitHub account. This works well for small changes.
If you'd like to make larger changes you may want to consider using
local clone.
Function object.opEquals
Implementation for class opEquals override. Calls the class-defined methods after a null check. Please note this is not nogc right now, even if your implementation is, because of the typeinfo name string compare. This is because of dmd's dll implementation. However, it can infer to @safe if your class' opEquals is.
bool opEquals(LHS, RHS)
(
LHS lhs,
RHS rhs
)
if ((is(LHS : const(Object)) || is(LHS : shared(const(Object)))) && (is(RHS : const(Object)) || is(RHS : shared(const(Object)))));
Example
If aliased to the same object or both null => equal
class F { int flag; this(int flag) { this .flag = flag; } }
F f;
assert(f == f); // both null
f = new F(1);
assert(f == f); // both aliased to the same object
Example
If either is null => non-equal
class F { int flag; this(int flag) { this .flag = flag; } }
F f;
assert(!(new F(0) == f));
assert(!(f == new F(0)));
Example
If same exact type => one call to method opEquals
This test passes @safe
because it defines a new opEquals with @safe
class F
{
int flag;
this(int flag)
{
this .flag = flag;
}
bool opEquals(const F o) const @safe nothrow pure
{
return flag == o .flag;
}
}
F f;
writeln(new F(0)); // new F(0)
assert(!(new F(0) == new F(1)));
Example
General case => symmetric calls to method opEquals
int fEquals, gEquals;
class Base
{
int flag;
this(int flag)
{
this .flag = flag;
}
}
class F : Base
{
this(int flag) { super(flag); }
bool opEquals(const Base o) @safe
{
fEquals++;
return flag == o .flag;
}
}
class G : Base
{
this(int flag) { super(flag); }
bool opEquals(const Base o) @safe
{
gEquals++;
return flag == o .flag;
}
}
writeln(new F(1)); // new G(1)
writeln(fEquals); // 1
writeln(gEquals); // 1
Example
This test shows an example for a comprehensive inheritance equality chain too.
static class Base
{
int member;
this(int member) pure @safe nothrow @nogc
{
this .member = member;
}
override bool opEquals(Object rhs) const
{
return this .opEquals(cast(Base) rhs);
}
bool opEquals(const Base rhs) const @nogc pure nothrow @safe
{
if (rhs is null)
return false;
return this .member == rhs .member;
}
}
// works through the direct class with attributes enabled, except for pure and nogc in the current TypeInfo implementation
bool testThroughBase() nothrow @safe
{
Base b1 = new Base(0);
Base b2 = new Base(0);
writeln(b1); // b2
Base b3 = new Base(1);
assert(b1 != b3);
return true;
}
static assert(testThroughBase());
// also works through the base class interface thanks to the override, but no more attributes
bool testThroughObject()
{
Object o1 = new Base(0);
Object o2 = new Base(0);
writeln(o1); // o2
Object o3 = new Base(1);
assert(o1 != o3);
return true;
}
static assert(testThroughObject());
// Each time you make a child, you want to override all old opEquals
// and add a new overload for the new child.
static class Child : Base
{
int member2;
this(int member, int member2) pure @safe nothrow @nogc
{
super(member);
this .member2 = member2;
}
// override the whole chain so it works consistently though any base
override bool opEquals(Object rhs) const
{
return this .opEquals(cast(Child) rhs);
}
override bool opEquals(const Base rhs) const
{
return this .opEquals(cast(const Child) rhs);
}
// and then add the new overload, if necessary, to handle new members
bool opEquals(const Child rhs) const @nogc pure nothrow @safe
{
if (rhs is null)
return false;
// can call back to the devirtualized base test with implicit conversion
// then compare the new member too. or we could have just compared the base
// member directly here as well.
return Base .opEquals(rhs) && this .member2 == rhs .member2;
}
// a mixin template, of course, could automate this.
}
bool testThroughChild()
{
Child a = new Child(0, 0);
Child b = new Child(0, 1);
assert(a != b);
Base ba = a;
Base bb = b;
assert(ba != bb);
Object oa = a;
Object ob = b;
assert(oa != ob);
return true;
}
static assert(testThroughChild());
Authors
Walter Bright, Sean Kelly
License
Copyright © 1999-2024 by the D Language Foundation | Page generated by ddox.