HaxeFoundation / HaxeFoundation/haxe

Better EnumFlags

Open
#6,330 10 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.