Simplify some C-style code

bauss jacobbauss at gmail.com
Thu Dec 26 00:55:02 UTC 2024


On Wednesday, 25 December 2024 at 07:49:28 UTC, sfp wrote:
> I have some code like this:
> ```
> enum DomainType {
>   Ball,
>   Box,
>   CsgDiff
> }
>
> struct Domain(int Dim) {
>   DomainType type;
>   union {
>     Ball!Dim ball;
>     Box!Dim box;
>     CsgDiff!Dim csgDiff;
>   }
>
>   this(Ball!Dim ball) {
>     this.type = DomainType.Ball;
>     this.ball = ball;
>   }
>
>   this(Box!Dim box) {
>     this.type = DomainType.Box;
>     this.box = box;
>   }
>
>   this(CsgDiff!Dim csgDiff) {
>     this.type = DomainType.CsgDiff;
>     this.csgDiff = csgDiff;
>   }
>
>   void doSomething() {
>     switch (type) {
>     case DomainType.Ball:
>       ...
>       break;
>     case DomainType.Box:
>       ...
>       break;
>     case DomainType.CsgDiff:
>       ...
>       break;
>     }
>   }
> }
> ```
> Is there some way I can reduce the amount of boilerplate using 
> D, i.e. generate most of this code at compile time?
>
> For what it's worth, I had checked out `SumType` as an 
> alternative to this mess, but it doesn't play nicely with 
> recursively defined types.

Here's how I would improve upon your code with mixin and static 
foreach.

```
enum DomainType {
   Ball,
   Box,
   CsgDiff
}

const DomainTypeShortNames =
     [
     	DomainType.Ball : "ball",
     	DomainType.Box : "box",
     	DomainType.CsgDiff : "csgDiff"
     ];

struct Domain(int Dim) {
   DomainType type;
   union {
     static foreach (domainType; EnumMembers!DomainType)
     {
         mixin(domainType.to!string ~ "!Dim " ~ 
DomainTypeShortNames[domainType] ~ ";");
     }
   }

   static foreach (domainType; EnumMembers!DomainType)
   {
       mixin(q{
           this(%1$s!Dim %2$s)
           {
               this.type = DomainType.%1$s;
               this.%2$s = %2$s;
           }
       }.format(domainType, DomainTypeShortNames[domainType]));
   }

   ...
}
```


More information about the Digitalmars-d-learn mailing list