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.

Reply via email to