various questions
bearophile
bearophileHUGS at lycos.com
Wed Jul 28 17:18:05 PDT 2010
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
More information about the Digitalmars-d-learn
mailing list