Implicit enum conversions are a stupid PITA

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Sun Mar 28 15:52:30 PDT 2010


On 03/28/2010 03:44 AM, Lutger wrote:
> bearophile wrote:
>
>> To invent a software you can first find the best syntax. This seems a nice
>> syntax, very similar to the enum one (that ubyte is optional):
>>
>> flags ubyte Todo {
>>      do_nothing,
>>      walk_dog,
>>      cook_breakfast,
>>      deliver_newspaper,
>>      visit_miss_kerbopple,
>>      wash_covers
>> }
>>
>> Todo todo = Todo.walk_dog | Todo.deliver_newspaper | Todo.wash_covers;
>> if (todo == (Todo.walk_dog | Todo.deliver_newspaper)) { ...
>> if ((Todo.walk_dog | Todo.deliver_newspaper) in todo) { ...
>> if ((Todo.walk_dog | Todo.deliver_newspaper)&  todo) { ...
>> assert((Todo.walk_dog | Todo.walk_dog) == Todo.walk_dog); // OK
>>
>>
>> A way to implement it with current D2 syntax:
>>
>>
>> alias Flags!(ubyte, "do_nothing",
>>                      "walk_dog"
>>                      "cook_breakfast"
>>                      "deliver_newspaper"
>>                      "visit_miss_kerbopple"
>>                      "wash_covers") Todo;
>>
>>
>> Where Flags defines a struct, "do_nothing" are compile-time constants. It
>> can overload 8 operators:
>> =   ==   |    |=    in&    &=  opBool
>>
>> The operator ! too can be defined, but I think it looks too much like the |
>> so it can be omitted (other operators like ^ and ~ are possible).
>>
>
> I like this idea of implementing a flag type and tried to work something out.
> Instead of implementing the overloads, it is also possible to generate an
> enum via CTFE inside a struct and forward with alias this, what do you think?
> I have tried this syntax, seems to work ok:
>
> alias Flags!q{ do_nothing,
>                 walk_dog,
>                 cook_breakfast,
>                 deliver_newspaper,
>                 visit_miss_kerbopple,
>                 wash_covers } Todo;
>
> It does allow this though, but perhaps that can fixed:
>
> Todo todo = Todo.walk_dog;
> todo |= 4;
>
> With such a type, it is easy to add some small convenience features, such as
> an  enumToString, define property .max and implement a range that iterates
> over all flags set or possible values.

I think it will take some time to settle the competition between 
"template parses everything" approach and "language parses most" approach.

For what it's worth, Walter and I were talking three years ago about a 
"new alias" feature:

template Flags(new alias Names...) { ... }

"new alias" means that you may pass to Flags symbols that haven't been 
defined. With that feature in place, Flags could be used like this:

  alias Flags!(do_nothing,
               walk_dog,
               cook_breakfast,
               deliver_newspaper,
               visit_miss_kerbopple,
               wash_covers)
      Todo;

No muss, no fuss, no need to stringize anything. Flags could get to the 
names of the alias parameters by using Names[i].stringof.

Well that's not in the language yet :o).


Andrei



More information about the Digitalmars-d mailing list