www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Request: nested enums

reply "JS" <js.mdnq gmail.com> writes:
I think it would be nice to have such a feature:

enum A
{
    a, b, c
    enum B
    {
       d, e, f
    }
}

this helps with logically nested types.

Possibly A.B returns the first(or possibly default) entry of the 
list(d).

Also, a useful property would be to uniformly distribute the 
enums inside the int range(or make it optional). This makes 
changes to an enum less likely to break things such as 
communications with older apps that use an older version of the 
enum.

Basically each nested enum occupies a range of 1 to N with N 
being relatively large but a fraction of int.max.
Jul 15 2013
parent reply "JS" <js.mdnq gmail.com> writes:
Here is a better example that can actually be implemented but not 
pretty:



final immutable struct Msg
{
     immutable int Foo = 0;
     immutable int Bar = 1;
     final immutable struct Type
     {
         immutable int Error = 10000;
         immutable int Ok = 10001;
     }
}

Here type is not necessarily a logical subtype of Msg but better 
stated as Msg.Type.Error rather than MsgType.Error.

If a flag distribution was used, we could do Msg.Foo || 
Msg.Type.Error.

In any case generating such a structure is a bit of a pain 
compared to a normal enum.
Jul 15 2013
parent reply "Yota" <yotaxp thatGoogleMailThing.com> writes:
On Monday, 15 July 2013 at 13:47:21 UTC, JS wrote:
 Here is a better example that can actually be implemented but 
 not pretty:



 final immutable struct Msg
 {
     immutable int Foo = 0;
     immutable int Bar = 1;
     final immutable struct Type
     {
         immutable int Error = 10000;
         immutable int Ok = 10001;
     }
 }

 Here type is not necessarily a logical subtype of Msg but 
 better stated as Msg.Type.Error rather than MsgType.Error.

 If a flag distribution was used, we could do Msg.Foo || 
 Msg.Type.Error.

 In any case generating such a structure is a bit of a pain 
 compared to a normal enum.
That could cause a bit of readability issue. If you know Msg is an enum, and then see in the code Msg.Foo, Msg.Bar, and Msg.Type, any programmer is gonna instantly assume that Msg.Type is just another value. If they see Msg.Type.Error, and are still certain that Msg is an enum, they they might reason that the enum is of a user defined type, and you're reading the Error field/property. Either way, it seems a bit counterproductive. I do see the appeal of nesting types though, as I dislike dumping things into the global namespace, so I might advise something like this: struct Msg { enum Type { Foo, Bar } enum Result { Error, OK } } Be careful with ORing values from different enums though, as the result type won't be an enum.
Jul 16 2013
parent reply "JS" <js.mdnq gmail.com> writes:
On Tuesday, 16 July 2013 at 15:50:54 UTC, Yota wrote:
 On Monday, 15 July 2013 at 13:47:21 UTC, JS wrote:
 Here is a better example that can actually be implemented but 
 not pretty:



 final immutable struct Msg
 {
    immutable int Foo = 0;
    immutable int Bar = 1;
    final immutable struct Type
    {
        immutable int Error = 10000;
        immutable int Ok = 10001;
    }
 }

 Here type is not necessarily a logical subtype of Msg but 
 better stated as Msg.Type.Error rather than MsgType.Error.

 If a flag distribution was used, we could do Msg.Foo || 
 Msg.Type.Error.

 In any case generating such a structure is a bit of a pain 
 compared to a normal enum.
That could cause a bit of readability issue. If you know Msg is an enum, and then see in the code Msg.Foo, Msg.Bar, and Msg.Type, any programmer is gonna instantly assume that Msg.Type is just another value. If they see Msg.Type.Error, and are still certain that Msg is an enum, they they might reason that the enum is of a user defined type, and you're reading the Error field/property. Either way, it seems a bit counterproductive.
I can't do anything about invalid assumptions people make. Alias has the exact same issue you state. If the programmer doesn't want to take the time to look at the code properly then it's their fault. If one wants to avoid
 I do see the appeal of nesting types though, as I dislike 
 dumping
 things into the global namespace, so I might advise something
 like this:

 struct Msg {
 	enum Type { Foo, Bar }
 	enum Result { Error, OK }
 }

 Be careful with ORing values from different enums though, as the
 result type won't be an enum.
Jul 16 2013
parent "JS" <js.mdnq gmail.com> writes:
If one want's to avoid that problem, just don't allow the nested 
enum also have a value. It's not a huge deal but just a sort of 
alias this concept applied to enums:

enum A { default, a, b, c; alias a this; }
Jul 16 2013