UDAs on enum members

user1234 via Digitalmars-d digitalmars-d at puremagic.com
Wed Jul 13 05:49:51 PDT 2016


On Wednesday, 13 July 2016 at 11:57:21 UTC, Tomer Filiba wrote:
> It would be really nice if I could put UDAs on enum members as 
> well, e.g.,
>
> enum MyEnum {
>     @("SOM") SomeMember,
>     @("ANO") AnotherMemberWithAVeryLongName,
> }
>
> I can think of many reasons why that would be desired, but the 
> concrete one is the following: I have an interchangeable data 
> format, and my enum might gain members over time. I don't care 
> about the value of the member, so I don't want to number them 
> myself, but I can't control where users would choose to place 
> the new member, so they might cause renumbering of existing 
> members, breaking the interchangeable format.
>
> So what I wanted is to assign each member a "short stable name" 
> that would be used to serialize the value (using my own 
> dump/load functions)... But I had to resort to a long, ugly 
> switch statement, mapping members to their names and vice 
> versa. The dumping function uses final-switch, so you won't 
> forget to update it, but the loading one can't (it takes a 
> string) so it would be easy to people to forget.
>
> Given that UDAs can be used practically everywhere (including 
> struct/union members), is there an objection to make them legal 
> on enum members as well?
>
> And while we're on the subject, why can't enums have methods? 
> At the risk of sounding as if I like Java (I don't :) ), it's a 
> really nice language feature. Back to our example:
>
> enum MyEnum {
>     @("SOM") SomeMember,
>     @("ANO") AnotherMemberWithAVeryLongName;
>
>     string dump() {
>         ...  // `this` is a value, not a ref here
>     }
>     static MyEnum load(string name) {
>         ...
>     }
> }
>
> Basically just allow a semicolon at the end of the members, 
> after which methods could appear. Adding members or whatever 
> else Java has is an overkill -- just use a struct for that. But 
> instead of lots of dumpMyEnum(MyEnum e)/loadMyEnum(string s) 
> pairs, you could write myMember.dump()/MyEnum.load(s)
>
>
> -tomer

To the risk of not being usefull I wonder if what you want 
wouldn't be easier to obtain with a union and a bit of 
discipline. If you put only manifest constants inside a union you 
can have methods and UDAs. The union can be verified by a 
template.

union Enum
{
      int value;
      @("SOM") enum SomeMember = int(0);
      @("ANO") enum AnotherMemberWithAVeryLongName = int(1);
}

template validateEnum(T)
{
     // check for unique-ness of each value
     // check other things.
     enum validateEnum = check();
}

To the question of mapping, since each member has an unique 
value, the member value itself can be used as hash in an AA 
without producing clustering. This works well if values are 
integers or floats.


More information about the Digitalmars-d mailing list