THRIFT-2916 Add default toHash method to 'class' and 'struct' to meet D's associative arrays requirement.
Client: D
Patch: Phongphan Phuttha <phongphan@acm.org>
This closes #503
diff --git a/lib/d/src/thrift/codegen/base.d b/lib/d/src/thrift/codegen/base.d
index 35e566a..9061d0b 100644
--- a/lib/d/src/thrift/codegen/base.d
+++ b/lib/d/src/thrift/codegen/base.d
@@ -419,6 +419,10 @@
return (cast()super).opEquals(other);
}
+
+ size_t toHash() const {
+ return thriftToHashImpl();
+ }
} else {
string toString() const {
return thriftToStringImpl();
@@ -427,6 +431,10 @@
bool opEquals(ref const This other) const {
return thriftOpEqualsImpl(other);
}
+
+ size_t toHash() const @safe nothrow {
+ return thriftToHashImpl();
+ }
}
private string thriftToStringImpl() const {
@@ -459,6 +467,15 @@
return true;
}
+ private size_t thriftToHashImpl() const @trusted nothrow {
+ size_t hash = 0;
+ foreach (name; FieldNames!This) {
+ auto val = mixin("this." ~ name);
+ hash += typeid(val).getHash(&val);
+ }
+ return hash;
+ }
+
static if (any!`!a.defaultValue.empty`(mergeFieldMeta!(This, fieldMetaData))) {
static if (is(This _ == class)) {
this() {
@@ -941,6 +958,29 @@
static assert(__traits(compiles, { Test t; t.write(cast(TProtocol)null); }));
}
+// Ensure opEquals and toHash consistency.
+unittest {
+ struct TestEquals {
+ int a1;
+
+ mixin TStructHelpers!([
+ TFieldMeta("a1", 1, TReq.OPT_IN_REQ_OUT),
+ ]);
+ }
+
+ TestEquals a, b;
+ assert(a == b);
+ assert(a.toHash() == b.toHash());
+
+ a.a1 = 42;
+ assert(a != b);
+ assert(a.toHash() != b.toHash());
+
+ b.a1 = 42;
+ assert(a == b);
+ assert(a.toHash() == b.toHash());
+}
+
private {
/*
* Returns a D code string containing the matching TType value for a passed