Simplify some C-style code
sfp
sfp at hush.ai
Thu Dec 26 17:53:00 UTC 2024
On Wednesday, 25 December 2024 at 07:49:28 UTC, sfp wrote:
> I have some code like this:
>
> ...
Thanks again for all the helpful feedback. This is where I landed:
```
import std.algorithm : map;
import std.algorithm.iteration : joiner;
import std.array : array;
string uncap(string s) {
import std.format;
import std.uni;
return format("%s%s", s[0].toLower, s[1..$]);
}
enum string[] domains = [
"Ball",
"Box",
"CsgDiff",
"CsgIsect",
"CsgUnion",
"Rect",
];
auto getTypeString(string[] types) {
return "enum Type {" ~ types.joiner(", ").array ~ "}";
}
auto getUnionString(string[] types) {
return (
["union {"] ~
types.map!(s => s ~ "!Dim " ~ uncap(s) ~ ";").array ~
["}"]
).joiner("\n").array;
}
string getCtorString(string s) {
return
"this(" ~ s ~ "!Dim " ~ uncap(s) ~ ") {\n" ~
" this.type = Type." ~ s ~ ";\n" ~
" this." ~ uncap(s) ~ " = " ~ uncap(s) ~ ";\n" ~
"}\n";
}
auto getCtorStrings(string[] types) {
return types.map!(getCtorString).array;
}
struct Domain(int Dim) {
mixin(getTypeString(domains));
Type type;
mixin(getUnionString(domains));
static foreach (ctorString; getCtorStrings(domains))
mixin(ctorString);
Rect!Dim getBoundingBox() const {
final switch (type)
static foreach (s; domains) case mixin("Type." ~ s):
return mixin(uncap(s) ~ ".getBoundingBox()");
}
Domain!Dim intersect(const ref Domain!Dim other) const {
final switch (type)
static foreach (s1; domains) case mixin("Type." ~ s1):
final switch (other.type)
static foreach (s2; domains) case mixin("Type." ~ s2):
return mixin(uncap(s1) ~ ".intersect(other." ~ uncap(s2) ~
")");
}
}
```
This is enough to get me unstuck so I can write more actual code,
but it still seems less than ideal:
1. It would be nice to be able to define the list of domains in
terms of the actual types rather than strings.
2. As an added bonus, if I could validate that the types are all
compatible with each other as templates (e.g., in this case
they're all template classes with a single integer parameter),
that would be useful.
3. It would be nice to come up with an abbreviated syntax for
`getBoundingBox` and `intersect`, so that this starts looking a
little more like a DSL for stubbing out interfaces.
More information about the Digitalmars-d-learn
mailing list