www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - switch with enum

reply tcak <1ltkrs+3wyh1ow7kzn1k sharklasers.com> writes:
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?
Nov 24 2015
next sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
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
Nov 24 2015
parent reply tcak <1ltkrs+3wyh1ow7kzn1k sharklasers.com> writes:
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).
Nov 24 2015
parent Steven Schveighoffer <schveiguy yahoo.com> writes:
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
Nov 30 2015
prev sibling parent reply Meta <jared771 gmail.com> writes:
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 }
Nov 25 2015
parent reply Meta <jared771 gmail.com> writes:
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.
Nov 25 2015
parent reply anonymous <anonymous example.com> writes:
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.
Nov 25 2015
parent reply Meta <jared771 gmail.com> writes:
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?
Nov 25 2015
next sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
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.
Nov 25 2015
prev sibling parent Anon <anon anon.anon> writes:
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
Nov 25 2015