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