diff --git a/Core/Extensions/EnumExtensions.cs b/Core/Extensions/EnumExtensions.cs
index f1d0dd6c..2c4b34ad 100644
--- a/Core/Extensions/EnumExtensions.cs
+++ b/Core/Extensions/EnumExtensions.cs
@@ -9,14 +9,29 @@ namespace Vanara.Extensions
/// Extensions for enumerated types.
public static class EnumExtensions
{
+ /// Gets the bit position of a flag that has a single bit, starting at 0.
+ /// The enumerated type.
+ /// The enumerated value.
+ /// The bit position, starting at 0, of the single bit flag specified in .
+ /// The flag value is zero and has no bit position.
+ /// The flag value has more than a single bit set.
+ public static byte BitPosition(this T flags) where T : struct, System.Enum
+ {
+ CheckHasFlags();
+ var flagValue = Convert.ToInt64(flags);
+ if (flagValue == 0) throw new ArgumentException("The flag value is zero and has no bit position.");
+ var r = Math.Log(flagValue, 2);
+ if (!Math.Abs(r).Equals(r)) throw new ArithmeticException("The flag value has more than a single bit set.");
+ return Convert.ToByte(r);
+ }
+
/// Throws an exception if a flag value does not exist in a specified enumeration.
/// The enumerated type.
/// The value to check.
/// Name of the argument to display in the exception. "value" is used if no value or null is supplied.
///
- public static void CheckHasValue(T value, string argName = null)
+ public static void CheckHasValue(T value, string argName = null) where T : struct, System.Enum
{
- CheckIsEnum();
if (IsFlags())
{
var allFlags = 0L;
@@ -35,15 +50,15 @@ namespace Vanara.Extensions
/// The enumerated value.
/// The flags to clear or unset.
/// The resulting enumerated value after the has been unset.
- public static T ClearFlags(this T flags, T flag) where T : struct, IConvertible => flags.SetFlags(flag, false);
+ public static T ClearFlags(this T flags, T flag) where T : struct, System.Enum => flags.SetFlags(flag, false);
/// Combines enumerated list of values into a single enumerated value.
/// The enumerated type.
/// The flags to combine.
/// A single enumerated value.
- public static T CombineFlags(this IEnumerable flags) where T : struct, IConvertible
+ public static T CombineFlags(this IEnumerable flags) where T : struct, System.Enum
{
- CheckIsEnum(true);
+ CheckHasFlags();
long lValue = 0;
foreach (var flag in flags)
{
@@ -57,9 +72,8 @@ namespace Vanara.Extensions
/// The enumerated type.
/// The enumerated value.
/// The description, or null if one is not set.
- public static string GetDescription(this T value) where T : struct, IConvertible
+ public static string GetDescription(this T value) where T : struct, System.Enum
{
- CheckIsEnum();
// If this is flag, return flags if there are more than one.
if (IsFlags() && value.GetFlags().Count() > 1)
return value.ToString(CultureInfo.InvariantCulture);
@@ -78,9 +92,9 @@ namespace Vanara.Extensions
/// The enumerated type.
/// The enumerated value.
/// An enumeration of individual flags that compose the .
- public static IEnumerable GetFlags(this T value) where T : struct, IConvertible
+ public static IEnumerable GetFlags(this T value) where T : struct, System.Enum
{
- CheckIsEnum(true);
+ CheckHasFlags();
foreach (T flag in Enum.GetValues(typeof(T)))
{
if (value.IsFlagSet(flag))
@@ -93,9 +107,9 @@ namespace Vanara.Extensions
/// The enumerated flag value.
/// The flag value to check.
/// true if is flag set; otherwise, false.
- public static bool IsFlagSet(this T flags, T flag) where T : struct, IConvertible
+ public static bool IsFlagSet(this T flags, T flag) where T : struct, System.Enum
{
- CheckIsEnum(true);
+ CheckHasFlags();
var flagValue = Convert.ToInt64(flag);
return (Convert.ToInt64(flags) & flagValue) == flagValue;
}
@@ -104,9 +118,8 @@ namespace Vanara.Extensions
/// The enumerated type.
/// The enumerated value.
/// true if the specified value is valid; otherwise, false.
- public static bool IsValid(this T value) where T : struct, IConvertible
+ public static bool IsValid(this T value) where T : struct, System.Enum
{
- CheckIsEnum();
if (IsFlags())
{
long mask = 0, lValue = Convert.ToInt64(value);
@@ -122,9 +135,9 @@ namespace Vanara.Extensions
/// A reference to an enumerated value.
/// The flag to set or unset.
/// if set to true sets the flag; otherwise the flag is unset.
- public static void SetFlags(ref T flags, T flag, bool set = true) where T : struct, IConvertible
+ public static void SetFlags(ref T flags, T flag, bool set = true) where T : struct, System.Enum
{
- CheckIsEnum(true);
+ CheckHasFlags();
var flagsValue = Convert.ToInt64(flags);
var flagValue = Convert.ToInt64(flag);
if (set)
@@ -140,7 +153,7 @@ namespace Vanara.Extensions
/// The flag to set or unset.
/// if set to true sets the flag; otherwise the flag is unset.
/// The resulting enumerated value after the has been set or unset.
- public static T SetFlags(this T flags, T flag, bool set = true) where T : struct, IConvertible
+ public static T SetFlags(this T flags, T flag, bool set = true) where T : struct, System.Enum
{
var ret = flags;
SetFlags(ref ret, flag, set);
@@ -153,18 +166,16 @@ namespace Vanara.Extensions
/// if set to true the check with also assert that the enumeration has the set and will throw an exception if not.
///
///
- private static void CheckIsEnum(bool checkHasFlags = false)
+ private static void CheckHasFlags() where T : struct, System.Enum
{
- if (!typeof(T).IsEnum)
- throw new ArgumentException($"Type '{typeof(T).FullName}' is not an enum");
- if (checkHasFlags && !IsFlags())
+ if (!IsFlags())
throw new ArgumentException($"Type '{typeof(T).FullName}' doesn't have the 'Flags' attribute");
}
/// Determines whether this enumerations has the set.
/// The enumerated type.
/// true if this instance has the set; otherwise, false.
- private static bool IsFlags() => Attribute.IsDefined(typeof(T), typeof(FlagsAttribute));
+ private static bool IsFlags() where T : struct, System.Enum => Attribute.IsDefined(typeof(T), typeof(FlagsAttribute));
/*/// Returns an indication if the enumerated value is either defined or can be defined by a set of known flags.
/// The enumerated type.