On Sunday, 25 October 2015 at 05:45:15 UTC, Nerve wrote:
On Sunday, 25 October 2015 at 05:05:47 UTC, Rikki Cattermole wrote:
Since I have no idea what the difference between Some(_), None and default. I'll assume it's already doable.

_ represents all existing values not matched. In this case, Some(_) represents any integer value that is not 7. None specifically matches the case where no value has been returned. We are, in most languages, also able to unwrap the value:

match x {
    Some(7) => "Lucky number 7!",
    Some(n) => "Not a lucky number: " ~ n,
    None => "No value found"
}

You can do something very similar to that. With slightly different syntax.

import std.traits;
import std.conv;
import std.variant;
struct CMatch(T...) if(T.length == 1)
{
   alias U = typeof(T[0]);
   static bool match(Variant v)
   {
      if(auto p = v.peek!U)
         return *p == T[0];
      return false;
   }
}

auto ref match(Handlers...)(Variant v)
{
   foreach(handler; Handlers)
   {
      alias P = Parameters!handler;
      static if(P.length == 1)
      {
         static if(isInstanceOf!(CMatch, P[0]))
         {
            if(P[0].match(v))
               return handler(P[0].init);
         }
         else
         {
            if(auto p = v.peek!(P[0]))
               return handler(*p);
         }
      }
      else
      {
         return handler();
      }
   }

   assert(false, "No matching pattern");
}

unittest
{
    Variant v = 5;
    string s = v.match!(
        (CMatch!7) => "Lucky number seven",
        (int n)    => "Not a lucky number: " ~ n.to!string,
        ()         => "No value found!");

   writeln(s);
}

Reply via email to