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

Reply via email to