Created
December 6, 2024 14:23
-
-
Save lucasteles/499045cb41d99e2b5aa213c1a1577849 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Runtime.CompilerServices; | |
Check(Foo.A | Foo.B | Foo.C, Foo.B); | |
Check(Foo.A | Foo.B, Foo.C); | |
Check(Foo.A | Foo.C, Foo.None); | |
Check(Foo.A | Foo.B | Foo.C, Foo.B | Foo.C); | |
Check(Foo.A | Foo.B | Foo.D, Foo.B | Foo.C); | |
var setA = (Foo.B | Foo.C).Set(Foo.A).Set(Foo.C, false); | |
Console.WriteLine(setA); | |
Check(setA, Foo.A); | |
var multiFlags = Foo.A | Foo.B | Foo.C | Foo.E; | |
Console.WriteLine("\nList unique values :"); | |
foreach(var enumValue in multiFlags.GetUniqueFlags()) | |
Console.WriteLine($"- {enumValue}"); | |
Console.WriteLine("\nList all values :"); | |
foreach(var enumValue in multiFlags.GetFlags()) | |
Console.WriteLine($"- {enumValue}"); | |
Console.WriteLine("🌄"); | |
static void Check(Foo e, Foo flag) { | |
Console.WriteLine($"HasFlag ({flag}) in ({e}) = {e.HasFlag(flag)}"); | |
Console.WriteLine($"HasAllFlag ({flag}) in ({e}) = {e.HasAll(flag)}"); | |
Console.WriteLine($"HasAnyFlag ({flag}) in ({e}) = {e.HasAny(flag)}"); | |
Console.WriteLine(); | |
} | |
[Flags] | |
public enum Foo { | |
None = 0, | |
A = 1 << 0, | |
B = 1 << 1, | |
C = 1 << 2, | |
D = 1 << 3, | |
E = 1 << 4, | |
AB = A | B, | |
} | |
static class EnumExt | |
{ | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public static bool HasAll<T>(this T value, in T flags) where T : struct, Enum, IConvertible | |
{ | |
var bits = value.ToUInt64(null); | |
var flagBits = flags.ToUInt64(null); | |
return flagBits != 0 && (bits & flagBits) == flagBits; | |
} | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public static bool HasAny<T>(this T value, in T flags) where T : struct, Enum, IConvertible | |
{ | |
var bits = value.ToUInt64(null); | |
var flagBits = flags.ToUInt64(null); | |
return (bits & flagBits) is not 0; | |
} | |
[MethodImpl(MethodImplOptions.AggressiveInlining)] | |
public static T Set<T>(this T value, in T flags, bool enabled = true) where T : struct, Enum, IConvertible | |
{ | |
var bits = value.ToUInt64(null); | |
var flagBits = flags.ToUInt64(null); | |
var result = enabled ? bits | flagBits : bits & ~flagBits; | |
return Unsafe.As<ulong, T>(ref result); | |
} | |
public static IEnumerable<T> GetUniqueFlags<T>(this T flags) where T : struct, Enum, IConvertible | |
{ | |
var flag = 1UL; | |
var flagBits = flags.ToUInt64(null); | |
foreach (var value in Enum.GetValues<T>()) | |
{ | |
var bits = value.ToUInt64(null); | |
while (flag < bits) | |
flag <<= 1; | |
if (flag == bits && (bits & flagBits) == bits) | |
yield return value; | |
} | |
} | |
public static IEnumerable<T> GetFlags<T>(this T flags) where T : struct, Enum, IConvertible | |
{ | |
var flagBits = flags.ToUInt64(null); | |
foreach (var value in Enum.GetValues<T>()) | |
{ | |
var bits = value.ToUInt64(null); | |
if ((bits & flagBits) == bits) | |
yield return value; | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
HasFlag (B) in (AB, C) = True | |
HasAllFlag (B) in (AB, C) = True | |
HasAnyFlag (B) in (AB, C) = True | |
HasFlag (C) in (AB) = False | |
HasAllFlag (C) in (AB) = False | |
HasAnyFlag (C) in (AB) = False | |
HasFlag (None) in (A, C) = True | |
HasAllFlag (None) in (A, C) = False | |
HasAnyFlag (None) in (A, C) = False | |
HasFlag (B, C) in (AB, C) = True | |
HasAllFlag (B, C) in (AB, C) = True | |
HasAnyFlag (B, C) in (AB, C) = True | |
HasFlag (B, C) in (AB, D) = False | |
HasAllFlag (B, C) in (AB, D) = False | |
HasAnyFlag (B, C) in (AB, D) = True | |
AB | |
HasFlag (A) in (AB) = True | |
HasAllFlag (A) in (AB) = True | |
HasAnyFlag (A) in (AB) = True | |
List unique values : | |
- A | |
- B | |
- C | |
- E | |
List all values : | |
- None | |
- A | |
- B | |
- AB | |
- C | |
- E | |
🌄 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"version": 1, | |
"target": "Run", | |
"mode": "Debug" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment