diff --git a/CHANGELOG.md b/CHANGELOG.md
index f2b11fe..c7a1d62 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## [Unreleased]
### Added
+ - Added enum extension method for cycling to the next enum value
- Added GetLocalTimeZoneName method to IcdEnvironment
- Added MatchAny method to RegexUtils
- Added OnSystemDeviceAddedRemoved and associated raise methods to IcdEnvironment for NETSTANDARD
diff --git a/ICD.Common.Utils.Tests/Extensions/EnumExtensionsTest.cs b/ICD.Common.Utils.Tests/Extensions/EnumExtensionsTest.cs
index d81f22c..0b94167 100644
--- a/ICD.Common.Utils.Tests/Extensions/EnumExtensionsTest.cs
+++ b/ICD.Common.Utils.Tests/Extensions/EnumExtensionsTest.cs
@@ -32,5 +32,17 @@ namespace ICD.Common.Utils.Tests.Extensions
{
Assert.AreEqual(expected, value.HasFlags(flags));
}
+
+ [TestCase(eTestEnum.A, eTestEnum.B)]
+ [TestCase(eTestEnum.B, eTestEnum.C)]
+ [TestCase(eTestEnum.C, eTestEnum.A)]
+ [TestCase(eTestEnum.A | eTestEnum.B, null)]
+ public void CycleNextTest(eTestEnum value, eTestEnum? expected)
+ {
+ if (EnumUtils.HasMultipleFlags(value))
+ Assert.Catch(typeof(InvalidOperationException), () => value.CycleNext());
+ else
+ Assert.AreEqual(expected, value.CycleNext());
+ }
}
}
diff --git a/ICD.Common.Utils/Extensions/EnumExtensions.cs b/ICD.Common.Utils/Extensions/EnumExtensions.cs
index 559bb7c..fbbb9d0 100644
--- a/ICD.Common.Utils/Extensions/EnumExtensions.cs
+++ b/ICD.Common.Utils/Extensions/EnumExtensions.cs
@@ -1,4 +1,6 @@
using System;
+using System.Collections.Generic;
+using System.Linq;
using ICD.Common.Properties;
namespace ICD.Common.Utils.Extensions
@@ -83,5 +85,25 @@ namespace ICD.Common.Utils.Extensions
{
return EnumUtils.ToStringUndefined(extends);
}
+
+ ///
+ /// Returns the next defined enum value for the enum type.
+ ///
+ ///
+ ///
+ ///
+ public static T CycleNext(this T extends)
+ where T : struct, IConvertible
+ {
+ if (EnumUtils.IsFlagsEnum(typeof(T)) && !EnumUtils.HasSingleFlag(extends))
+ throw new InvalidOperationException(string.Format("Cannot cycle enum with multiple flags - {0}", extends));
+
+ IEnumerable values = EnumUtils.GetValues();
+ IList list = values as IList ?? values.ToArray();
+
+ int index = list.BinarySearch(extends);
+
+ return index == list.Count - 1 ? list[0] : list[index + 1];
+ }
}
}
diff --git a/ICD.Common.Utils/Extensions/ListExtensions.cs b/ICD.Common.Utils/Extensions/ListExtensions.cs
index dd41884..5646e17 100644
--- a/ICD.Common.Utils/Extensions/ListExtensions.cs
+++ b/ICD.Common.Utils/Extensions/ListExtensions.cs
@@ -349,6 +349,22 @@ namespace ICD.Common.Utils.Extensions
#region Binary Search
+ ///
+ /// Returns the index of the item in the list.
+ ///
+ ///
+ ///
+ ///
+ ///
+ [PublicAPI]
+ public static int BinarySearch([NotNull] this IList extends, T item)
+ {
+ if (extends == null)
+ throw new ArgumentNullException("extends");
+
+ return extends.BinarySearch(item, Comparer.Default);
+ }
+
///
/// Returns the index of the item in the list.
///