semi-final switch?

jfondren julian.fondren at gmail.com
Fri Jun 18 04:24:19 UTC 2021


On Thursday, 17 June 2021 at 21:41:28 UTC, Steven Schveighoffer 
wrote:
> A final switch on an enum complains if you don't handle all the 
> enum's cases. I like this feature.
...
> Oh, and to throw a monkey wrench in here, the value is a 
> string, not an integer. So I can't use std.conv.to to verify 
> the enum is valid (plus, then I'm running a switch twice).

Wanting to avoid more work than a switch means generating a 
switch.
I think that's the real monkey wrench.

Something like:

```d
T enumCases(T, E, T[E] cases)(string x) {
     import std.format : format;
     import std.algorithm : map, all, joiner;
     import std.array : array;
     import std.traits : EnumMembers;
     import std.conv : to;

     mixin("switch (x) {\n" ~
         [EnumMembers!E].map!(e =>
             format!"case %(%s%): return %(%s%);\n"([e.to!string], 
[cases[e]]))
         .joiner.array ~
         "default: assert(0);\n}");
}

unittest {
     enum C { ABC, XYZ }

     assert("x\tb" == enumCases!(string, C, [
         C.ABC: "x\tb",  // error to omit an enum value
         C.XYZ: "ab",    // impossible to have a bad enum value
     ])("ABC"));

     // the first problem with this solution: the following is an 
error...
     // unless the preceding usage is commented out.
     /+assert(2 == enumCases!(int, C, [
         C.ABC: 1,
         C.XYZ: 2,
     ])("XYZ"));+/
}
```


More information about the Digitalmars-d-learn mailing list