// 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 buf.append("if (!(" + instanceCheck + [[)) false; ]] + className + [[ x = cast ]] + argName + [[; ret ]] + join(" && ", map(fields, func(Pair p) -> S { // TODO: use == for primitive fields "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); }