From 6ef93d02e4c4c18ef2c4c90c2f0adacee3835d3a Mon Sep 17 00:00:00 2001 From: Tyler Brinkley Date: Wed, 17 Jan 2024 08:55:00 -0600 Subject: [PATCH] Fix issue 47 with enumerating certain high value flag values (#48) * Fix issue 47 with enumerating certain high value flag values * Target .NET 7 for test --- .github/workflows/build.yml | 4 +-- Src/Enums.NET.Test/Enums.NET.Test.csproj | 6 ++--- Src/Enums.NET.Test/Issues/Issue47.cs | 34 ++++++++++++++++++++++++ Src/Enums.NET/EnumCache.cs | 12 +++++---- Src/Enums.NET/Enums.NET.csproj | 6 ++--- 5 files changed, 49 insertions(+), 13 deletions(-) create mode 100644 Src/Enums.NET.Test/Issues/Issue47.cs diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c8a5eb2..e9d87c8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -20,6 +20,6 @@ jobs: - name: Test .NET 4.5 run: dotnet test -f net45 --no-restore --verbosity normal working-directory: ./Src - - name: Test .NET Core 3.0 - run: dotnet test -f netcoreapp3.0 --no-restore --verbosity normal + - name: Test .NET 7 + run: dotnet test -f net7 --no-restore --verbosity normal working-directory: ./Src diff --git a/Src/Enums.NET.Test/Enums.NET.Test.csproj b/Src/Enums.NET.Test/Enums.NET.Test.csproj index 3015f7a..5b0a6dd 100644 --- a/Src/Enums.NET.Test/Enums.NET.Test.csproj +++ b/Src/Enums.NET.Test/Enums.NET.Test.csproj @@ -1,6 +1,6 @@  - netcoreapp3.0;netcoreapp2.0;netcoreapp1.1;netcoreapp1.0;net46;net45 + net7;netcoreapp2.0;netcoreapp1.1;netcoreapp1.0;net46;net45 EnumsNET.Tests latest @@ -26,7 +26,7 @@ - + @@ -38,7 +38,7 @@ Enums.NET Test .NET 4.5 DISPLAY_ATTRIBUTE;ICONVERTIBLE;GET_TYPE_CODE;TYPE_REFLECTION - + Enums.NET Test .NET Core App 3.0 NETSTANDARD;DISPLAY_ATTRIBUTE;ICONVERTIBLE;GET_TYPE_CODE;TYPE_REFLECTION;BENCHMARKS;SPAN diff --git a/Src/Enums.NET.Test/Issues/Issue47.cs b/Src/Enums.NET.Test/Issues/Issue47.cs new file mode 100644 index 0000000..f9be5f2 --- /dev/null +++ b/Src/Enums.NET.Test/Issues/Issue47.cs @@ -0,0 +1,34 @@ +using System; +using NUnit.Framework; + +namespace EnumsNET.Tests.Issues +{ + [TestFixture] + public class Issue47 + { + [Test] + public void AsString_SuccessfullyReturnsValue_WhenUsingLargeFlagEnumValue() + { + Assert.AreEqual("Val1, Val30", (MyEnum.Val1 | MyEnum.Val30).AsString()); + } + +#if SPAN + [Test] + public void TryFormat_SuccessfullyReturnsValue_WhenUsingLargeFlagEnumValue() + { + var destination = new char[20]; + Assert.True((MyEnum.Val1 | MyEnum.Val30).TryFormat(destination, out var charsWritten)); + Assert.AreEqual(11, charsWritten); + Assert.AreEqual("Val1, Val30", new string(destination[..charsWritten])); + } +#endif + + [Flags] + public enum MyEnum + { + Unknown = 0, + Val1 = 1 << 0, + Val30 = 1 << 30, + } + } +} diff --git a/Src/Enums.NET/EnumCache.cs b/Src/Enums.NET/EnumCache.cs index bf6a437..9ec009a 100644 --- a/Src/Enums.NET/EnumCache.cs +++ b/Src/Enums.NET/EnumCache.cs @@ -1203,10 +1203,11 @@ public sealed override void GetAllFlags(ref byte result) var sb = new StringBuilder(); TUnderlyingOperations operations = default; - var isLessThanZero = operations.LessThan(value, default); - for (var currentValue = operations.One; isLessThanZero ? !currentValue.Equals(default) : !operations.LessThan(value, currentValue); currentValue = operations.LeftShift(currentValue, 1)) + var validValue = operations.And(value, _allFlags); + var checkForZero = operations.LessThan(validValue, default) || operations.LessThan(operations.LeftShift(validValue, 1), validValue); + for (var currentValue = operations.One; checkForZero ? !currentValue.Equals(default) : !operations.LessThan(validValue, currentValue); currentValue = operations.LeftShift(currentValue, 1)) { - if (HasAnyFlags(value, currentValue)) + if (HasAnyFlags(validValue, currentValue)) { if (sb.Length > 0) { @@ -1264,8 +1265,9 @@ int Iterate(ReadOnlySpan delimiter, Span dest, int maxLength) var original = dest; var length = 0; TUnderlyingOperations operations = default; - var isLessThanZero = operations.LessThan(value, default); - for (var currentValue = operations.One; isLessThanZero ? !currentValue.Equals(default) : !operations.LessThan(value, currentValue); currentValue = operations.LeftShift(currentValue, 1)) + var validValue = operations.And(value, _allFlags); + var checkForZero = operations.LessThan(validValue, default) || operations.LessThan(operations.LeftShift(validValue, 1), validValue); + for (var currentValue = operations.One; checkForZero ? !currentValue.Equals(default) : !operations.LessThan(validValue, currentValue); currentValue = operations.LeftShift(currentValue, 1)) { if (HasAnyFlags(value, currentValue)) { diff --git a/Src/Enums.NET/Enums.NET.csproj b/Src/Enums.NET/Enums.NET.csproj index 0b8b0d6..0779ed5 100644 --- a/Src/Enums.NET/Enums.NET.csproj +++ b/Src/Enums.NET/Enums.NET.csproj @@ -2,10 +2,10 @@ net45;netcoreapp3.0;netstandard2.1;netstandard2.0;netstandard1.3;netstandard1.1;netstandard1.0 4.0.0.0 - 4.0.1 - 4.0.1 + 4.0.2 + 4.0.2 - 4.0.1 + 4.0.2 False Tyler Brinkley Enums.NET is a high-performance type-safe .NET enum utility library