xxxxxxxxxx
/+dub.sdl:
name "foo"
+/
struct Foo
{
int i;
float f;
auto opEquals()(auto ref const(typeof(this)) rhs)
{
import std.math : approxEqual, isNaN;
import std.traits : isFloatingPoint, isIntegral;
alias F = typeof(this);
static foreach (i; 0..Foo.tupleof.length)
{
{ // adding scope to be able to declare `enum fname` on every
// loop iteration
// Field Type
alias FType = typeof(F.tupleof[i]);
// Field Name
enum fname = F.tupleof[i].stringof;
// Floating types are being processed by using approxEqual
static if (isFloatingPoint!FType)
{
if (!mixin("this." ~ fname).isNaN || !mixin("rhs." ~ fname).isNaN)
{
if (!approxEqual(mixin("this." ~ F.tupleof[i].stringof), mixin("rhs." ~ F.tupleof[i].stringof)))
return false;
}
}
else static if (isIntegral!FType)
{
if (mixin("this." ~ fname) != mixin("rhs." ~ fname))
return false;
}
else
static assert (0);
} // end of auxillary scope
}
return true;
}
}
void main(string[] args)
{
Foo f1, f2;
assert (f1 == f2);
f2.f = 10;
assert (f1 != f2);
}