What's a good approach to DRY with the block code of a case-statement?

ag0aep6g anonymous at example.com
Mon Apr 26 20:59:35 UTC 2021


On Monday, 26 April 2021 at 20:39:55 UTC, Jack wrote:
> I have a block of code that the only thing that change is the 
> type passed in one of the template functions called so I'd like 
> to make a DRY for this. But I'm not just replacing by a 
> function due to control-flow, for example, there are 
> if-statements where one just break and the other return 0. I 
> think I could do something with mixin() that would kinda mimic 
> C's macro but I still find it messy. Any alternatives?
>
> ```d
> static int doSomething()
> {
> 	switch(val)
> 	{
> 		case VAL_FOO:
> 			auto obj = getObject!MyType(someData); // this is the type
> 												   // that changes
> 			if(obj.shouldExit()) break;
> 		
> 			auto m = Message(...);
> 			if(obj.doSomethingElse(m)) return 0;
> 		break;
>
> 	   // ...
> 	
> 	   default:
> 	}
>
> 	return doSomethingY();
> }
> ```

I think you're looking for this D idiom:

```d
sw: switch (rt_value)
{
     static foreach (ct_value; ct_values)
     {
         case ct_value: some_template!ct_value; break sw;
     }
}
```

Applied to your code it might look like this:

```d
import std.meta: AliasSeq;
alias stuff = AliasSeq!(VAL_FOO, MyType, VAL_BAR, MyOtherType, /* 
... */);
sw: switch (val)
{
     static foreach (i; 0 .. stuff.length / 2)
     {
         case stuff[i]:
         auto obj = getObject!(stuff[i + 1])(someData);
         if(obj.shouldExit()) break sw;
         auto m = Message(...);
         if(obj.doSomethingElse(m)) return 0;
         break sw;
     }
}
```


More information about the Digitalmars-d-learn mailing list