HaxeFoundation / HaxeFoundation/haxe
Better EnumFlags
- Dominant language
- Haxe
- Stars
- 6.9k
- Forks
- 715
- Avg merge
- 2d 2h
- Merged PRs (30d)
- 11
Description
Original `haxe.EnumFlags` come from a before-abstract Haxe, I think it would be time to revamp it.
Ideally one would like to be able to do the following:
```haxe
@:enumFlags abstract Flags(Int) {
var A; // = 1 automatically assigned
var B; // = 2
var Special = 0x800;
var None = 0;
}
static function foo( f : Flags ) {
if( f.has(A|Special) )
f &= A;
else
f.set(B);
...
}
foo(None);
foo(A);
foo(A|Special);
```
Please note that this is currently not working well with current EnumFlags, because A and B are not EnumFlags instance but the enum type parameter, so the top town inference will not be able to correctly deal with `A|B` for example.
This is possible however to do by doing the following:
```haxe
@:enum abstract Flags(Int) {
var A = 1;
var B = 2;
var Special = 0x800;
var None = 0;
@:op(a|b) static function or(a:Flags,b:Flags) : Flags;
@:op(a&b) static function and(a:Flags,b:Flags) : Flags;
public inline function new(i = 0) {
this = i;
}
public inline function has( v : Flags ) : Bool {
return (this & v.toInt()) == v.toInt();
}
public inline function set( v : Flags ) : Void {
this |= v.toInt();
}
public inline function unset( v : Flags ) : Void {
this &= 0xFFFFFFFF - v.toInt();
}
public inline function toInt() {
return this;
}
public inline static function ofInt( i : Int ) : Flags {
return new Flags(i);
}
}
```
It's quite verbose if you have to declare many of the and is not entirely correct either since it's not a proper "enum" in the sense that all flags combination as possible, so it's not something that should be considered complete with a switch.
I propose that we add `@:enumFlags` for that and deprecate haxe.EnumFlags. My only concern here is that if you want to have an "enum" that comes both in terms of different independent values AND that you want to gather as bit flags it doesn't work anymore.
Also being able to iterate on the individual flags and switch on it (this time with switch completeness) would be interesting, this could be done for instance by defining:
function iterator() : haxe.SingleFlag;
Another option is to keep the two types (the enum and the flags separated) but we still want the initial example to work well.
Any suggestion?
Contributor guide
Assessment
This issue has not been assessed yet.