import std.stdio, std.traits, std.range, std.algorithm;
void truthTable(alias fun)(in string expression, in char[] operands...)
if (isCallable!fun && is(ReturnType!fun == bool)) {
immutable len = operands.length;
writefln("\n\n%( %2c %) %s\n", operands, expression);
foreach (immutable i; 0 .. 2 ^^ len) {
const bits = len.iota.map!(j => !!(i & (1 << j))).array;
writefln("%(%2d %) : %d", bits, fun(bits));
}
}
bool xor(in bool[] vals...) pure nothrow
in {
assert(vals.length == 2);
} body {
return vals[0] != vals[1];
}
bool stu(in bool[] vals...) pure nothrow
in {
assert(vals.length == 3);
} body {
return vals[0] || (vals[1] ^ vals[2]);
}
bool abcd(in bool[] vals...) pure nothrow
in {
assert(vals.length == 4);
} body {
return vals[0] ^ (vals[1] ^ (vals[2] ^ vals[3]));
}
void main() {
truthTable!xor("A ^ B", "AB");
truthTable!stu("S | ( T ^ U )", "STU");
truthTable!abcd("A ^ (B ^ (C ^ D))", "ABCD");
}