static switch over is expression cases?

Witold witold.baryluk+dlang at gmail.com
Sat Oct 28 03:36:21 UTC 2023


Just something I realized, when I was coding something.

```d
struct ReservedBit {
}
struct ReservedBits {
   int width;
}
struct Bit {
   string name;
}
struct Bits {
   int width;
   string name;
}


string genWrapped(Fields...)() {
   static if (Fields.length == 0) {
     return "struct Wrapped { ubyte v; }";
   }
   string ret = "struct Wrapped {\n";
   int bit_offset = 0;
   static foreach (Field; Fields) {
     static if (is(typeof(Field) : Bit) || is(typeof(Field) : 
ReservedBit)) {
       bit_offset += 1;
     } else static if (is(typeof(Field) : Bits) || 
is(typeof(Field) : ReservedBits)) {
       bit_offset += Field.width;
     } else {
       static assert(false);
     }
   }
   // ...
   return ret ~ "}\n";
}

mixin(genWrapped!(Bit("x"), ReservedBits(2), Bits(3, "y"), 
ReservedBits(2))());
```

Hmm. Wouldn't it be nice to be able to do this (or something 
similar) instead?

```d
string genWrapped(Fields...)() {
   static if (Fields.length == 0) {
     return "struct Wrapped { ubyte v; }";
   }
   string ret = "struct Wrapped {\n";
   int bit_offset = 0;
   static foreach (Field; Fields) {
     static /*final*/ switch {
       case is(typeof(Field) : Bit):
       case is(typeof(Field) : ReservedBit):
         bit_offset += 1;
         /*static?*/ break;
       case is(typeof(Field) : Bits))):
       case is(typeof(Field) : ReservedBits):
         bit_offset += Field.width;
         /*static?*/ break;
       // default: static assert(false);
     }
   }
   // ...
   return ret ~ "}\n";
}
```

And using template specialization pattern matching in the `is` 
expression, it should be available in the specific `case` 
"branch" too.

I know I could have just passed these struct values by value as 
arguments, to the CTFE string builder, but sometimes you want to 
pass as types (when using some alias template arguments for 
example).



More information about the Digitalmars-d mailing list