static switch/pattern matching

ketmar via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat Jun 25 02:08:51 PDT 2016


On Saturday, 25 June 2016 at 08:46:05 UTC, John wrote:
> Anyone able to improve on it?

q&d hack:

template tyma(T, Cases...) {
   import std.traits;
   template GetFunc(size_t idx) {
     static if (idx >= Cases.length) {
       static assert(0, "no delegate for match");
     } else static if (isCallable!(Cases[idx])) {
       enum GetFunc = Cases[idx];
     } else {
       enum GetFunc = GetFunc!(idx+1);
     }
   }
   template Matcher(size_t idx) {
     //pragma(msg, "T=", T, "; idx=", idx, "; Cases[idx]=", 
Cases[idx], "; is=", is(typeof(T) == Cases[idx]));
     static if (idx >= Cases.length) {
       static assert(0, "no match, consider adding `void` branch");
     } else static if (isCallable!(Cases[idx])) {
       enum Matcher = Matcher!(idx+1);
     } else static if (is(Cases[idx] == void)) {
       enum Matcher = GetFunc!(idx+1);
     } else static if (is(typeof(Cases[idx]) == string)) {
       mixin("static if (is(T:"~Cases[idx]~")) enum Matcher = 
GetFunc!(idx+1); else enum Matcher = Matcher!(idx+1);");
     } else static if (is(typeof(Cases[idx]))) {
       static assert(0, "unexpected something in cases: 
"~Cases[idx].stringof);
     } else static if (is(T == Cases[idx])) {
       enum Matcher = GetFunc!(idx+1);
     } else {
       enum Matcher = Matcher!(idx+1);
     }
   }
   enum tyma = Matcher!0;
}


void main () {
   import std.stdio;
   auto res = tyma!(int,
     string, () => "string",
     "long", () => "integral",
     void, () => "anything",
   )();
   writeln(res);
}


note that you should separate type names from labdas with "," 
instead of doing `int => "integral`, and have to add `()` at the 
end to actually call the delegate.


More information about the Digitalmars-d-learn mailing list