This is better, probably it can be improves a bit more: import std.stdio: writeln; import std.metastrings: Format; import std.typetuple: TypeTuple;
template Iota(int stop) { static if (stop <= 0) alias TypeTuple!() Iota; else alias TypeTuple!(Iota!(stop-1), stop-1) Iota; } void foo(T, int N, int M)() { writeln(typeid(T), " ", N, " ", M); } enum string[] types = ["int", "float", "short"]; enum string[] sizes = ["small", "medium", "large"]; enum Type : string { int_type = types[0], float_type = types[1], short_type = types[2] } enum Size { small = 100, medium = 200, large = 250 } void main() { Type run_t = Type.int_type; Size run_n = Size.medium; Size run_m = Size.small; enum string pattern = "if (run_t == Type.%s_type && run_n == Size.%s && run_m == Size.%s) { foo!(%s, Size.%s, Size.%s)(); goto END; }"; foreach (t; Iota!(types.length)) foreach (n; Iota!(sizes.length)) foreach (m; Iota!(sizes.length)) mixin(Format!(pattern, types[t], sizes[n], sizes[m], types[t], sizes[n], sizes[m])); END: {} } Bye, bearophile