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