std.sumtype?

Paul Backus snarwin at gmail.com
Thu Mar 25 15:17:31 UTC 2021


On Thursday, 25 March 2021 at 15:03:37 UTC, drug wrote:
> In general I agree to Steven. I can add to his post that kind 
> lets you do:
> ```D
> 	switch(kind)
> 	{
> 	case Kind.foo0..case Kind.foo5:
> 		doSomething1;
> 		break;
> 	case Kind.bar:
> 	case Kind.baz:
> 	case Kind.foobar:
> 		doSomething2;
> 		break;
> 	default:
> 		doDefaultThings;
> 	}
> ```
> using handlers:
> ```D
> 	someType.match!(
> 		(Foo0 foo) => doSomething1,
> 		(Foo1 foo) => doSomething1,
> 		(Foo2 foo) => doSomething1,
> 		(Foo3 foo) => doSomething1,
> 		(Foo4 foo) => doSomething1,
> 		(Bar  bar) => doSomething2,
> 		(Baz  baz) => doSomething2,
> 		(FooBar fb) => doSomething2,
> 		(_) => doDefaultThings;
> 	);
> ```
> These examples are verbose equally but the first version 
> contains less boilerplate.

Only if you don't know what you're doing. Check this out:

     template restrictTo(Args...)
         if (Args.length >= 1)
     {
         import std.meta : IndexOf = staticIndexOf;

         alias Types = Args[0 .. $-1];
         alias fun = Args[$];

         auto ref restrictTo(T)(auto ref T value)
             if (IndexOf!(T, Types) >= 0);
         {
             import core.lifetime: forward

             static assert(IndexOf!(T, Types) >= 0);
             return fun(forward!value);
         }
     }

Usage:

     someType.match!(
         restrictTo!(Foo0, Foo1, Foo2, Foo3, Foo4,
             val => doSomething1
         ),
         restrictTo!(Bar, Baz, FooBar,
             val => doSomething2
         ),
         _ => doDefaultThings
     );


More information about the Digitalmars-d mailing list