From 7f14e347b428800d6e44abcc6d0b6bc3e6f8a00d Mon Sep 17 00:00:00 2001 From: Theodore Tsirpanis Date: Sat, 6 Aug 2022 21:08:16 +0300 Subject: [PATCH] Refactor `EnumUtils` and make it AOT-friendly. The `EnumUtils.Parse` method used to use the non-generic `Enum.GetValues` method to do its job, which is unsafe and produces AOT warnings. This PR refactors it to use `Enum.IsDefined` instead, which does not allocate. I also added asserts to methods in `EnumUtils` that ensure we use them with int-sized enums. --- src/ImageSharp/Common/Helpers/EnumUtils.cs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/ImageSharp/Common/Helpers/EnumUtils.cs b/src/ImageSharp/Common/Helpers/EnumUtils.cs index d6bead6408..a598411629 100644 --- a/src/ImageSharp/Common/Helpers/EnumUtils.cs +++ b/src/ImageSharp/Common/Helpers/EnumUtils.cs @@ -19,15 +19,14 @@ internal static class EnumUtils /// The default value to return. /// The . public static TEnum Parse(int value, TEnum defaultValue) - where TEnum : Enum + where TEnum : struct, Enum { - foreach (TEnum enumValue in Enum.GetValues(typeof(TEnum))) + DebugGuard.IsTrue(Unsafe.SizeOf() == sizeof(int), "Only int-sized enums are supported."); + + TEnum valueEnum = Unsafe.As(ref value); + if (Enum.IsDefined(valueEnum)) { - TEnum current = enumValue; - if (value == Unsafe.As(ref current)) - { - return enumValue; - } + return valueEnum; } return defaultValue; @@ -41,8 +40,10 @@ public static TEnum Parse(int value, TEnum defaultValue) /// The flag. /// The . public static bool HasFlag(TEnum value, TEnum flag) - where TEnum : Enum + where TEnum : struct, Enum { + DebugGuard.IsTrue(Unsafe.SizeOf() == sizeof(int), "Only int-sized enums are supported."); + uint flagValue = Unsafe.As(ref flag); return (Unsafe.As(ref value) & flagValue) == flagValue; }