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