Comment #0 by bearophile_hugs — 2011-03-07T04:31:23Z
This is a low-priority enhancement suggestion.
If the type to final-switch on has a natural ordering (so it's not an enum!), like a char/ubyte/byte, then in some situations I'd like to use the range syntax:
void main() {
ubyte u;
final switch (u) {
case 0: .. case 100: break;
case 101: .. case 255: break;
}
}
Currently DMD 2.052 gives the errors:
test.d(4): Error: case ranges not allowed in final switch
test.d(5): Error: case ranges not allowed in final switch
See also bug 5713
If case ranges are not allowed on full-range int values, then you can't use them in a final switch.
Comment #1 by andrej.mitrovich — 2012-12-02T05:55:57Z
(In reply to comment #0)
> If case ranges are not allowed on full-range int values, then you can't use
> them in a final switch.
Basically the compiler just translates this:
case 1: .. case 3: call()
into:
case 1:
case 2:
case 3:
call()
And it also limits the number of cases to 256 (for optimization purposes?).
So a final switch would only work on byte-types. I'm not sure if Walter would like a feature that only works with one fundamental type. Note also that because `final switch` currently works on ints (personally I would reject such code), people would assume they could add case ranges for the full int type, but they would get the 256 case limitation error instead.
As a current workaround you could use a mixin that generates the case statements and a 'default' which throws a SwitchError.
Comment #2 by bearophile_hugs — 2012-12-02T06:05:59Z
(In reply to comment #1)
> So a final switch would only work on byte-types. I'm not sure if Walter would
> like a feature that only works with one fundamental type.
There are also chars, and ubytes.
> `final switch` currently works on ints (personally I would reject such
> code),
It's indeed wrong, there is another enhancement request/bug report that asks for it to be fixed!
> As a current workaround you could use a mixin that generates the case
> statements and a 'default' which throws a SwitchError.
You can't have a default in static switches.
Comment #3 by andrej.mitrovich — 2012-12-02T06:34:36Z
(In reply to comment #2)
> (In reply to comment #1)
>
> > So a final switch would only work on byte-types. I'm not sure if Walter would
> > like a feature that only works with one fundamental type.
>
> There are also chars, and ubytes.
They have the same range so it doesn't matter what you call them, the range is limited to 0 .. 255.
> You can't have a default in static switches.
Yes, you would use a normal switch for that. But you could have a helper template mixin that could error internally if you don't provide all the cases, which is a workaround for final switches not providing case ranges.
Comment #4 by nick — 2023-01-21T15:36:57Z
(In reply to Andrej Mitrovic from comment #1)
> And it also limits the number of cases to 256 (for optimization purposes?).
>
> So a final switch would only work on byte-types.
See issue 15279 which seems to be an implementation issue rather than a design decision (the pull comment suggests lowering case range statements to an if/else instead).
Comment #5 by qs.il.paperinik — 2024-07-02T16:00:23Z
The limitation of the number of `case` labels is entirely orthogonal to allowing case ranges for `final switch`, as the ranges are just syntactic sugar for writing them out.
This errors:
---
void main()
{
ubyte u;
final switch (u)
{
case 0: .. case 100: break;
case 101: .. case 255: break;
}
}
---
This is fine:
---
void main() {
ubyte u;
Lswitch: final switch (u)
{
static foreach (i; 0 .. 100 + 1)
{
case i: break Lswitch;
}
static foreach (i; 101 .. 255 + 1)
{
case i: break Lswitch;
}
}
}
---
The error makes no sense. It might have made sense in 2011, but in 2024, it just requires some boilerplate to work.
Comment #6 by robert.schadek — 2024-12-13T17:55:03Z