1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
|
package cs;
/**
Use this type to have access to the bitwise operators of C# enums that have a `cs.system.FlagsAttribute` attribute.
Usage example:
```haxe
import cs.system.reflection.BindingFlags;
var binding = new Flags(BindingFlags.Public) | BindingFlags.Static | BindingFlags.NonPublic;
```
**/
abstract Flags<T : EnumValue>(T) from T to T
{
/**
Creates a new `Flags` type with an optional initial value. If no initial value was specified,
the default enum value for an empty flags attribute is specified
**/
@:extern inline public function new(?initial:T)
this = initial;
/**
Accessible through the bitwise OR operator (`|`). Returns a new `Flags` type with the flags
passed at `flags` added to it.
**/
@:op(A|B) @:extern inline public function add(flags:Flags<T>):Flags<T>
{
return new Flags(underlying() | flags.underlying());
}
/**
Accessible through the bitwise AND operator (`&`). Returns a new `Flags` type with
the flags that are set on both `this` and `flags`
**/
@:op(A&B) @:extern inline public function bitAnd(flags:Flags<T>):Flags<T>
{
return new Flags(underlying() & flags.underlying());
}
/**
Accessible through the bitwise XOR operator (`^`).
**/
@:op(A^B) @:extern inline public function bitXor(flags:Flags<T>):Flags<T>
{
return new Flags(underlying() & flags.underlying());
}
/**
Accesible through the bitwise negation operator (`~`). Returns a new `Flags` type
with all unset flags as set - but the ones that are set already.
**/
@:op(~A) @:extern inline public function bitNeg():Flags<T>
{
return new Flags(~underlying());
}
/**
Returns a new `Flags` type with all flags set by `flags` unset
**/
@:extern inline public function remove(flags:Flags<T>):Flags<T>
{
return new Flags(underlying() & ~flags.underlying());
}
/**
Returns whether `flag` is present on `this` type
**/
@:extern inline public function has(flag:T):Bool
{
return underlying() & new Flags(flag).underlying() != null;
}
/**
Returns whether `this` type has any flag set by `flags` also set
**/
@:extern inline public function hasAny(flags:Flags<T>):Bool
{
return underlying() & flags.underlying() != null;
}
/**
Returns whether `this` type has all flags set by `flags` also set
**/
@:extern inline public function hasAll(flags:Flags<T>):Bool
{
return underlying() & flags.underlying() == flags.underlying();
}
@:extern inline private function underlying():EnumUnderlying<T>
return this;
}
@:coreType private abstract EnumUnderlying<T> from T to T
{
@:op(A|B) public static function or<T>(lhs:EnumUnderlying<T>, rhs:EnumUnderlying<T>):T;
@:op(A^B) public static function xor<T>(lhs:EnumUnderlying<T>, rhs:EnumUnderlying<T>):T;
@:op(A&B) public static function and<T>(lhs:EnumUnderlying<T>, rhs:EnumUnderlying<T>):T;
@:op(~A) public static function bneg<T>(t:EnumUnderlying<T>):T;
}
|