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