Thread overview
switch with enum
Nov 25, 2015
tcak
Nov 25, 2015
tcak
Nov 25, 2015
Meta
Nov 25, 2015
Meta
Nov 25, 2015
anonymous
Nov 25, 2015
Meta
Nov 25, 2015
Adam D. Ruppe
Nov 25, 2015
Anon
November 25, 2015
I have seen a code a while ago, but even by looking at documentation, I couldn't have found anything about it.

Let's say I have defined an enum;

enum Status: ubyte{
 Busy = 1,
 Active = 2
}

and received a ubyte value from user.

ubyte userValue;

I want to switch over userValue, but that should depend on Status.

switch( userValue ){
...
}

What I mean is that compiler should enforce values of enum "Status" to be declared in switch as it would be done with "final switch", but as you can guess, user might enter a value that is not defined by Status. Thus, I should be able to enter the case "default" as well.

I remember it something like switch( userValue ) with( Status ){...}, but not sure about it. Maybe it was D1 code. Is there anything like this currently?
November 25, 2015
On 11/24/15 10:51 PM, tcak wrote:
> I have seen a code a while ago, but even by looking at documentation, I
> couldn't have found anything about it.
>
> Let's say I have defined an enum;
>
> enum Status: ubyte{
>   Busy = 1,
>   Active = 2
> }
>
> and received a ubyte value from user.
>
> ubyte userValue;
>
> I want to switch over userValue, but that should depend on Status.
>
> switch( userValue ){
> ....
> }
>
> What I mean is that compiler should enforce values of enum "Status" to
> be declared in switch as it would be done with "final switch", but as
> you can guess, user might enter a value that is not defined by Status.
> Thus, I should be able to enter the case "default" as well.

All final switch does is ensure you are covering all possible enums. It assumes that the value is already a valid enum value. If you did final switch on userValue, it would require you handle all 256 possible values for ubyte. So you would have to cast first.

>
> I remember it something like switch( userValue ) with( Status ){...},
> but not sure about it. Maybe it was D1 code. Is there anything like this
> currently?

What this does (and yes, it should work) is make it so you don't have to type "Status.Busy" within your case statements. You can just type "Busy". That's all.

-Steve
November 25, 2015
On Wednesday, 25 November 2015 at 03:59:01 UTC, Steven Schveighoffer wrote:
> On 11/24/15 10:51 PM, tcak wrote:
>> I have seen a code a while ago, but even by looking at documentation, I
>> couldn't have found anything about it.
>>
>> Let's say I have defined an enum;
>>
>> enum Status: ubyte{
>>   Busy = 1,
>>   Active = 2
>> }
>>
>> and received a ubyte value from user.
>>
>> ubyte userValue;
>>
>> I want to switch over userValue, but that should depend on Status.
>>
>> switch( userValue ){
>> ....
>> }
>>
>> What I mean is that compiler should enforce values of enum "Status" to
>> be declared in switch as it would be done with "final switch", but as
>> you can guess, user might enter a value that is not defined by Status.
>> Thus, I should be able to enter the case "default" as well.
>
> All final switch does is ensure you are covering all possible enums. It assumes that the value is already a valid enum value. If you did final switch on userValue, it would require you handle all 256 possible values for ubyte. So you would have to cast first.
>
>>
>> I remember it something like switch( userValue ) with( Status ){...},
>> but not sure about it. Maybe it was D1 code. Is there anything like this
>> currently?
>
> What this does (and yes, it should work) is make it so you don't have to type "Status.Busy" within your case statements. You can just type "Busy". That's all.
>
> -Steve

As far as I see, "default" case is not allowed when final switch
is used. From compiler developer's perspective, it is meaningful
and I can understand, but thinking about use cases as I have
given an example, this limitation prevents writing "tight" code.
(That is the term I could have found to express I am trying to say).
November 25, 2015
On Wednesday, 25 November 2015 at 03:51:48 UTC, tcak wrote:
> I have seen a code a while ago, but even by looking at documentation, I couldn't have found anything about it.
>
> Let's say I have defined an enum;
>
> enum Status: ubyte{
>  Busy = 1,
>  Active = 2
> }
>
> and received a ubyte value from user.
>
> ubyte userValue;
>
> I want to switch over userValue, but that should depend on Status.
>
> switch( userValue ){
> ...
> }
>
> What I mean is that compiler should enforce values of enum "Status" to be declared in switch as it would be done with "final switch", but as you can guess, user might enter a value that is not defined by Status. Thus, I should be able to enter the case "default" as well.
>
> I remember it something like switch( userValue ) with( Status ){...}, but not sure about it. Maybe it was D1 code. Is there anything like this currently?

One way you could do it:

import std.conv: to;

try
{
    switch (userValue.to!Status)
    {
        ...
    }
}
catch (ConvException c)
{
    //Default case
}
November 25, 2015
On Wednesday, 25 November 2015 at 20:00:01 UTC, Meta wrote:
> One way you could do it:
>
> import std.conv: to;
>
> try
> {
>     switch (userValue.to!Status)
>     {
>         ...
>     }
> }
> catch (ConvException c)
> {
>     //Default case
> }

...Which doesn't work because it won't compile without a default case. Is this a recent change? I don't remember D doing this before.
November 25, 2015
On 25.11.2015 21:06, Meta wrote:
> ...Which doesn't work because it won't compile without a default case.
> Is this a recent change? I don't remember D doing this before.

Use `final switch`. Ordinary `switch`es need an explicit default case. `final switch`es have to cover all possibilities individually. Implicit default cases are not allowed.
November 25, 2015
On Wednesday, 25 November 2015 at 20:47:35 UTC, anonymous wrote:
> Use `final switch`. Ordinary `switch`es need an explicit default case. `final switch`es have to cover all possibilities individually. Implicit default cases are not allowed.

>Ordinary `switch`es need an explicit default case

Since when?
November 25, 2015
On Wednesday, 25 November 2015 at 21:26:09 UTC, Meta wrote:
> Since when?

A long time, at least with the -w switch turned on when compiling.
November 25, 2015
On Wednesday, 25 November 2015 at 21:26:09 UTC, Meta wrote:
> On Wednesday, 25 November 2015 at 20:47:35 UTC, anonymous wrote:
>> Use `final switch`. Ordinary `switch`es need an explicit default case. `final switch`es have to cover all possibilities individually. Implicit default cases are not allowed.
>
>>Ordinary `switch`es need an explicit default case
>
> Since when?

Non-final switch without a default case was deprecated in 2011: http://dlang.org/changelog/2.054.html


November 30, 2015
On 11/25/15 12:17 AM, tcak wrote:
> On Wednesday, 25 November 2015 at 03:59:01 UTC, Steven Schveighoffer wrote:
>> On 11/24/15 10:51 PM, tcak wrote:
>>> I have seen a code a while ago, but even by looking at documentation, I
>>> couldn't have found anything about it.
>>>
>>> Let's say I have defined an enum;
>>>
>>> enum Status: ubyte{
>>>   Busy = 1,
>>>   Active = 2
>>> }
>>>
>>> and received a ubyte value from user.
>>>
>>> ubyte userValue;
>>>
>>> I want to switch over userValue, but that should depend on Status.
>>>
>>> switch( userValue ){
>>> ....
>>> }
>>>
>>> What I mean is that compiler should enforce values of enum "Status" to
>>> be declared in switch as it would be done with "final switch", but as
>>> you can guess, user might enter a value that is not defined by Status.
>>> Thus, I should be able to enter the case "default" as well.
>>
>> All final switch does is ensure you are covering all possible enums.
>> It assumes that the value is already a valid enum value. If you did
>> final switch on userValue, it would require you handle all 256
>> possible values for ubyte. So you would have to cast first.
>>
>>>
>>> I remember it something like switch( userValue ) with( Status ){...},
>>> but not sure about it. Maybe it was D1 code. Is there anything like this
>>> currently?
>>
>> What this does (and yes, it should work) is make it so you don't have
>> to type "Status.Busy" within your case statements. You can just type
>> "Busy". That's all.
>>
>
> As far as I see, "default" case is not allowed when final switch
> is used. From compiler developer's perspective, it is meaningful
> and I can understand, but thinking about use cases as I have
> given an example, this limitation prevents writing "tight" code.
> (That is the term I could have found to express I am trying to say).

I can see what you mean -- you want the compiler to warn that you haven't covered all the cases, but you don't want to have the expectation that the program should be in an undefined state if the default case is executed (currently there *is* a default case in final switch, which is basically assert(0)).

I think this is a worthy possibility for an enhancement -- if default case of a final switch is provided, then it should override automatic "assert(0)" default case.

-Steve