Enable opEquals between two TaggedAlgebraic!T values.
This commit is contained in:
parent
c7f4533d17
commit
5fc3e16a83
|
@ -189,7 +189,18 @@ struct TaggedAlgebraic(U) if (is(U == union) || is(U == struct))
|
|||
/// Enables accessing properties/fields of the stored value.
|
||||
@property auto opDispatch(string name, this TA, ARGS...)(auto ref ARGS args) if (hasOp!(TA, OpKind.field, name, ARGS) && !hasOp!(TA, OpKind.method, name, ARGS)) { return implementOp!(OpKind.field, name)(this, args); }
|
||||
/// Enables equality comparison with the stored value.
|
||||
auto opEquals(T, this TA)(auto ref T other) if (hasOp!(TA, OpKind.binary, "==", T)) { return implementOp!(OpKind.binary, "==")(this, other); }
|
||||
auto opEquals(T, this TA)(auto ref T other)
|
||||
if (is(Unqual!T == TaggedAlgebraic) || hasOp!(TA, OpKind.binary, "==", T))
|
||||
{
|
||||
static if (is(Unqual!T == TaggedAlgebraic)) {
|
||||
if (this.kind != other.kind) return false;
|
||||
final switch (this.kind)
|
||||
foreach (i, fname; fieldNames)
|
||||
case __traits(getMember, Kind, fname):
|
||||
return trustedGet!fname == other.trustedGet!fname;
|
||||
assert(false); // never reached
|
||||
} else return implementOp!(OpKind.binary, "==")(this, other);
|
||||
}
|
||||
/// Enables relational comparisons with the stored value.
|
||||
auto opCmp(T, this TA)(auto ref T other) if (hasOp!(TA, OpKind.binary, "<", T)) { assert(false, "TODO!"); }
|
||||
/// Enables the use of unary operators with the stored value.
|
||||
|
@ -362,6 +373,28 @@ unittest { // std.conv integration
|
|||
assert(ta.kind == TA.Kind.null_);
|
||||
}
|
||||
|
||||
@safe unittest { // comparison of whole TAs
|
||||
static union Test {
|
||||
typeof(null) a;
|
||||
typeof(null) b;
|
||||
Void c;
|
||||
Void d;
|
||||
int e;
|
||||
int f;
|
||||
}
|
||||
alias TA = TaggedAlgebraic!Test;
|
||||
|
||||
assert(TA(null, TA.Kind.a) == TA(null, TA.Kind.a));
|
||||
assert(TA(null, TA.Kind.a) != TA(null, TA.Kind.b));
|
||||
assert(TA(null, TA.Kind.a) != TA(Void.init, TA.Kind.c));
|
||||
assert(TA(null, TA.Kind.a) != TA(0, TA.Kind.e));
|
||||
assert(TA(Void.init, TA.Kind.c) == TA(Void.init, TA.Kind.c));
|
||||
assert(TA(Void.init, TA.Kind.c) != TA(Void.init, TA.Kind.d));
|
||||
assert(TA(1, TA.Kind.e) == TA(1, TA.Kind.e));
|
||||
assert(TA(1, TA.Kind.e) != TA(2, TA.Kind.e));
|
||||
assert(TA(1, TA.Kind.e) != TA(1, TA.Kind.f));
|
||||
}
|
||||
|
||||
unittest {
|
||||
// test proper type modifier support
|
||||
static struct S {
|
||||
|
@ -1310,3 +1343,12 @@ private void rawSwap(T)(ref T a, ref T b)
|
|||
ab[] = bb[];
|
||||
bb[] = tmp[];
|
||||
}
|
||||
|
||||
|
||||
unittest {
|
||||
struct TU { int i; }
|
||||
alias TA = TaggedAlgebraic!TU;
|
||||
|
||||
auto ta = TA(12);
|
||||
static assert(!is(typeof(ta.put(12))));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue