No more fall through in case statement?
Bill Baxter
dnewsgroup at billbaxter.com
Fri Jan 4 09:15:29 PST 2008
BC wrote:
> 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};
> }
Neat, but too many braces. :-(((({(}
--bb
More information about the Digitalmars-d
mailing list