Jason Spencer: > I had thought of the switch, and it would be too large. Can you give me an > idea of what > the mixin solution would look like? Suppose I have three strings, type, > rows, and cols > that get set at runtime, where type = ["int" | "float" | "short"], rows and > cols = > ["100" | "200" | "250"]. What I want is to take these 3 variables and come > up with: > foo!(int[100][100])(...) > foo!(int[100][200])(...) > ... > foo!(short[250][250])(...) > > for the right cases, without switching on type, rows, or cols.
The brutal way: import std.stdio: writeln; void foo(T, int N, int M)() { writeln(typeid(T), " ", N, " ", M); } enum Type { int_type, float_type, short_type } enum Size { small = 100, medium = 200, large = 250 } void main() { Type type = Type.int_type; Size n = Size.medium; Size m = Size.small; final switch (type) { case Type.int_type: final switch (n) { case Size.small: final switch (m) { case Size.small: foo!(int, Size.small, Size.small)(); break; case Size.medium: foo!(int, Size.small, Size.medium)(); break; case Size.large: foo!(int, Size.small, Size.large)(); break; } break; case Size.medium: final switch (m) { case Size.small: foo!(int, Size.medium, Size.small)(); break; case Size.medium: foo!(int, Size.medium, Size.medium)(); break; case Size.large: foo!(int, Size.medium, Size.large)(); break; } break; case Size.large: final switch (m) { case Size.small: foo!(int, Size.large, Size.small)(); break; case Size.medium: foo!(int, Size.large, Size.medium)(); break; case Size.large: foo!(int, Size.large, Size.large)(); break; } break; } break; case Type.float_type: final switch (n) { case Size.small: final switch (m) { case Size.small: foo!(float, Size.small, Size.small)(); break; case Size.medium: foo!(float, Size.small, Size.medium)(); break; case Size.large: foo!(float, Size.small, Size.large)(); break; } break; case Size.medium: final switch (m) { case Size.small: foo!(float, Size.medium, Size.small)(); break; case Size.medium: foo!(float, Size.medium, Size.medium)(); break; case Size.large: foo!(float, Size.medium, Size.large)(); break; } break; case Size.large: final switch (m) { case Size.small: foo!(float, Size.large, Size.small)(); break; case Size.medium: foo!(float, Size.large, Size.medium)(); break; case Size.large: foo!(float, Size.large, Size.large)(); break; } break; } break; case Type.short_type: final switch (n) { case Size.small: final switch (m) { case Size.small: foo!(short, Size.small, Size.small)(); break; case Size.medium: foo!(short, Size.small, Size.medium)(); break; case Size.large: foo!(short, Size.small, Size.large)(); break; } break; case Size.medium: final switch (m) { case Size.small: foo!(short, Size.medium, Size.small)(); break; case Size.medium: foo!(short, Size.medium, Size.medium)(); break; case Size.large: foo!(short, Size.medium, Size.large)(); break; } break; case Size.large: final switch (m) { case Size.small: foo!(short, Size.large, Size.small)(); break; case Size.medium: foo!(short, Size.large, Size.medium)(); break; case Size.large: foo!(short, Size.large, Size.large)(); break; } break; } break; } } A more compressed way: import std.metastrings: Format; import std.stdio: writeln; void foo(T, int N, int M)() { writeln(typeid(T), " ", N, " ", M); } enum Type { int_type, float_type, short_type } enum Size { small = 100, medium = 200, large = 250 } void main() { Type type = Type.short_type; Size n = Size.medium; Size m = Size.small; enum string inner = " case Size.small: foo!(%s, Size.%s, Size.small)(); break; case Size.medium: foo!(%s, Size.%s, Size.medium)(); break; case Size.large: foo!(%s, Size.%s, Size.large)(); break; "; enum string medial = " final switch (m) { mixin(Format!(inner, ty, si, ty, si, ty, si)); } break; "; enum string outer = ` final switch (n) { case Size.small: enum string si = "small"; mixin(medial); case Size.medium: enum string si = "medium"; mixin(medial); case Size.large: enum string si = "large"; mixin(medial); } break; `; final switch (type) { case Type.int_type: enum string ty = "int"; mixin(outer); case Type.float_type: enum string ty = "float"; mixin(outer); case Type.short_type: enum string ty = "short"; mixin(outer); } } It's a mess still :-) Bye, bearophile