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);
}