// fields: type + name sS tok_genEqualsAndHashCode(S className, LPairS fields, O... _) { optPar S qualifier = ""; optPar bool flexEq; S argName = "o"; while (pairsB(fields).contains(argName)) argName = "_" + argName; StringBuilder buf = new("\n\npublic bool equals(O \*argName*/) {\n"); S instanceCheck = flexEq ? "_getClass(\*argName*/) == getClass()" : "\*argName*/ instanceof " + qualifier + className; if (empty(fields)) buf.append("ret \*instanceCheck*/;\n"); else { S x = makeVar(); buf.append("if (!(" + instanceCheck + [[)) false; ]] + className + " \*x*/ = cast " + argName + [[; ret ]] + join(" && ", map(fields, func(PairS p) -> S { tok_isPrimitiveType(p.a) ? p.b + " == \*x*/." + p.b : "eq(" + p.b + ", \*x*/." + p.b + ")" })) + ";\n"); } buf.append("}\n"); buf.append([[ public int hashCode() { int h = ]] + hashCode(className) + [[; ]] + concatMap_strings(fields, func(Pair p) { "h = boostHashCombine(h, _hashCode(" + p.b + [[)); ]]}) + [[ret h; } ]]); ret str(buf); }