Browse Source

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.
pull/2200/head
Theodore Tsirpanis 4 years ago
parent
commit
7f14e347b4
  1. 17
      src/ImageSharp/Common/Helpers/EnumUtils.cs

17
src/ImageSharp/Common/Helpers/EnumUtils.cs

@ -19,15 +19,14 @@ namespace SixLabors.ImageSharp
/// <param name="defaultValue">The default value to return.</param>
/// <returns>The <typeparamref name="TEnum"/>.</returns>
public static TEnum Parse<TEnum>(int value, TEnum defaultValue)
where TEnum : Enum
where TEnum : struct, Enum
{
foreach (TEnum enumValue in Enum.GetValues(typeof(TEnum)))
DebugGuard.IsTrue(Unsafe.SizeOf<TEnum>() == sizeof(int), "Only int-sized enums are supported.");
TEnum valueEnum = Unsafe.As<int, TEnum>(ref value);
if (Enum.IsDefined(valueEnum))
{
TEnum current = enumValue;
if (value == Unsafe.As<TEnum, int>(ref current))
{
return enumValue;
}
return valueEnum;
}
return defaultValue;
@ -41,8 +40,10 @@ namespace SixLabors.ImageSharp
/// <param name="flag">The flag.</param>
/// <returns>The <see cref="bool"/>.</returns>
public static bool HasFlag<TEnum>(TEnum value, TEnum flag)
where TEnum : Enum
where TEnum : struct, Enum
{
DebugGuard.IsTrue(Unsafe.SizeOf<TEnum>() == sizeof(int), "Only int-sized enums are supported.");
uint flagValue = Unsafe.As<TEnum, uint>(ref flag);
return (Unsafe.As<TEnum, uint>(ref value) & flagValue) == flagValue;
}

Loading…
Cancel
Save