Mixin replacement for switch...case?
Philippe Sigaud
philippe.sigaud at gmail.com
Tue Oct 23 12:48:05 PDT 2012
> The solution (not variadic though) would be:
>
> mixin template Select!(alias value,
> alias if0, alias then0,
> alias if1, alias then1,
> alias if2, alias then2,
> alias thenDefault)
>
> {
> switch(value) {
> case if0 : { then0(); } break;
> case if1 : { then1(); } break;
> case if2 : { then2(); } break;
> default : thenDefault();
> }
> }
You can get something interesting a few lines of code:
template select(cases...) if (cases.length % 2 == 1)
{
auto select(Input)(Input input)
{
static if (cases.length == 1) // Default case
return cases[0]();
else // standard case
{
if (input == cases[0])
return cases[1]();
else
return .select!(cases[2..$])(input);
}
}
}
void main()
{
// With block delegates
alias select!(0, { writeln("Zero.");},
1, { writeln("One."); },
{ writeln("Something else.");}) counter;
counter(0);
counter(1);
counter(10_000);
// With anonymous functions:
alias select!(0, ()=> "Zero.",
1, ()=> "One.",
()=> "Something else.") counter2;
writeln(counter2(0));
writeln(counter2(1));
writeln(counter2(10_000));
}
A slightly more generic version takes predicates as first arguments,
as Lisp's cond form:
template cond(cases...) if (cases.length % 2 == 1)
{
auto cond(Input)(Input input)
{
static if (cases.length == 1) // Default case
return cases[0]();
else // standard case
{
if (cases[0](input)) // The only difference with select
return cases[1]();
else
return .cond!(cases[2..$])(input);
}
}
}
void main()
{
alias cond!((a) => a < 0, ()=> "Negative.",
(a) => a > 0, ()=> "Positive.",
()=> "Zero.") counter3;
writeln(counter3(-10));
writeln(counter3(1));
writeln(counter3(0));
}
Philippe
More information about the Digitalmars-d
mailing list