No more fall through in case statement?
BC
notmi_emayl_adreznot at hotmail.com.remove.not
Fri Jan 4 09:09:21 PST 2008
On Thu, 03 Jan 2008 10:30:09 -0000, davidl <davidl at 126.com> wrote:
> http://pragmatic.oreilly.com/pub/a/oreilly/dotnet/news/programmingCsharp_0801.html
>
> I think I love the trap no.9
>
i had a go at rolling my own, here it is if anyone's interested:
//public domain
import std.stdio;
import std.variant;
import std.traits;
struct SwitchFrame
{
Variant val;
bool active;
bool _break;
static SwitchFrame opCall(Variant val, bool active, bool _break)
{
SwitchFrame result;
result.val = val;
result.active = active;
result._break = _break;
return result;
}
}
SwitchFrame[] switchStack;
void _continue() //execute next case after this one
{
switchStack[$ - 1].active = true;
switchStack[$ - 1]._break = false;
}
void _rematch() //execute the next case that matches
{
switchStack[$ - 1].active = false;
switchStack[$ - 1]._break = false;
}
void _break() //don't execute any more cases
{
switchStack[$ - 1].active = false;
switchStack[$ - 1]._break = true;
}
struct _range(T)
{
T min;
T max;
}
_range!(T) range(T)(T min, T max)
{
_range!(T) result;
result.min = min;
result.max = max;
return result;
}
struct rangedg(T)
{
T min;
T max;
bool func(T val)
{
return min <= val && val <= max;
}
}
void myswitch(T, U)(T switchVal, U block)
{
Variant v = switchVal;
switchStack ~= SwitchFrame(v, false, false);
block();
switchStack.length = switchStack.length - 1;
}
void mycase(T...)(T args)
{
SwitchFrame* frame = &switchStack[$ - 1];
if (frame._break) return;
if (!frame.active)
{
foreach (i, arg; args[0 .. $-1])
{
if (typeid(T[i]) == frame.val.type && arg ==
frame.val.get!(T[i])) goto success;
static if (is (typeof(*arg) U == function))
{
//writefln("function");
if (arg(frame.val.get!(U))) goto success;
}
static if (is (T[i] U == delegate))
{
//writefln("delegate");
if (arg(frame.val.get!(ParameterTypeTuple!(U)))) goto success;
}
static if (is (T[i] U == _range!(V), V))
{
V switchVal1 = frame.val.get!(V);
if (arg.min <= switchVal1 && switchVal1 <= arg.max) goto
success;
}
}
}
else
{
success:
_break();// <- change this to change the default action
args[$-1]();
}
}
bool always(int a)
{
return true;
}
void main()
{
myswitch(24,
{
mycase(10, 11, 12, { writefln("10, 11, 12");
_continue; });
mycase(24, { writefln("24" );
_rematch; });
mycase(range(3, 25), { writefln("range" );
_rematch; });
mycase((int a) { return a > 40; }, { writefln(">40" );
_rematch; });
mycase(&always, { writefln("always" );
_rematch; });
});
_range!(int) ra = {2,3};
}
More information about the Digitalmars-d
mailing list