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]));
  }

  ...
}
```

Reply via email to