Related
If I have a variable holding a flags enum, can I somehow iterate over the single-bit values in that specific variable? Or do I have to use Enum.GetValues to iterate over the entire enum and check which ones are set?
static IEnumerable<Enum> GetFlags(Enum input)
{
foreach (Enum value in Enum.GetValues(input.GetType()))
if (input.HasFlag(value))
yield return value;
}
Here is a Linq solution to the problem.
public static IEnumerable<Enum> GetFlags(this Enum e)
{
return Enum.GetValues(e.GetType()).Cast<Enum>().Where(e.HasFlag);
}
There aren't any builtin methods to get each component as far as I know. But here's one way you can get them:
[Flags]
enum Items
{
None = 0x0,
Foo = 0x1,
Bar = 0x2,
Baz = 0x4,
Boo = 0x6,
}
var value = Items.Foo | Items.Bar;
var values = value.ToString()
.Split(new[] { ", " }, StringSplitOptions.None)
.Select(v => (Items)Enum.Parse(typeof(Items), v));
// This method will always end up with the most applicable values
value = Items.Bar | Items.Baz;
values = value.ToString()
.Split(new[] { ", " }, StringSplitOptions.None)
.Select(v => (Items)Enum.Parse(typeof(Items), v)); // Boo
I adapted what Enum does internally to generate the string to instead return the flags. You can look at the code in reflector and should be more or less equivalent. Works well for general use cases where there are values which contain multiple bits.
static class EnumExtensions
{
public static IEnumerable<Enum> GetFlags(this Enum value)
{
return GetFlags(value, Enum.GetValues(value.GetType()).Cast<Enum>().ToArray());
}
public static IEnumerable<Enum> GetIndividualFlags(this Enum value)
{
return GetFlags(value, GetFlagValues(value.GetType()).ToArray());
}
private static IEnumerable<Enum> GetFlags(Enum value, Enum[] values)
{
ulong bits = Convert.ToUInt64(value);
List<Enum> results = new List<Enum>();
for (int i = values.Length - 1; i >= 0; i--)
{
ulong mask = Convert.ToUInt64(values[i]);
if (i == 0 && mask == 0L)
break;
if ((bits & mask) == mask)
{
results.Add(values[i]);
bits -= mask;
}
}
if (bits != 0L)
return Enumerable.Empty<Enum>();
if (Convert.ToUInt64(value) != 0L)
return results.Reverse<Enum>();
if (bits == Convert.ToUInt64(value) && values.Length > 0 && Convert.ToUInt64(values[0]) == 0L)
return values.Take(1);
return Enumerable.Empty<Enum>();
}
private static IEnumerable<Enum> GetFlagValues(Type enumType)
{
ulong flag = 0x1;
foreach (var value in Enum.GetValues(enumType).Cast<Enum>())
{
ulong bits = Convert.ToUInt64(value);
if (bits == 0L)
//yield return value;
continue; // skip the zero value
while (flag < bits) flag <<= 1;
if (flag == bits)
yield return value;
}
}
}
The extension method GetIndividualFlags() gets all the individual flags for a type. So values containing multiple bits are left out.
var value = Items.Bar | Items.Baz;
value.GetFlags(); // Boo
value.GetIndividualFlags(); // Bar, Baz
Coming back at this a few years later, with a bit more experience, my ultimate answer for single-bit values only, moving from lowest bit to highest bit, is a slight variant of Jeff Mercado's inner routine:
public static IEnumerable<Enum> GetUniqueFlags(this Enum flags)
{
ulong flag = 1;
foreach (var value in Enum.GetValues(flags.GetType()).Cast<Enum>())
{
ulong bits = Convert.ToUInt64(value);
while (flag < bits)
{
flag <<= 1;
}
if (flag == bits && flags.HasFlag(value))
{
yield return value;
}
}
}
It seems to work, and despite my objections of some years ago, I use HasFlag here, since it's far more legible than using bitwise comparisons and the speed difference is insignificant for anything I'll be doing. (It's entirely possible they've improved the speed of HasFlags since then anyway, for all I know...I haven't tested.)
Going off of #Greg's method, but adding a new feature from C# 7.3, the Enum constraint:
public static IEnumerable<T> GetUniqueFlags<T>(this T flags)
where T : Enum // New constraint for C# 7.3
{
foreach (Enum value in Enum.GetValues(flags.GetType()))
if (flags.HasFlag(value))
yield return (T)value;
}
The new constraint allows this to be an extension method, without having to cast through (int)(object)e, and I can use the HasFlag method and cast directly to T from value.
C# 7.3 also added constraints to for delegates and unmanaged.
+1 for the answer provided by #RobinHood70. I found that a generic version of the method was convenient for me.
public static IEnumerable<T> GetUniqueFlags<T>(this Enum flags)
{
if (!typeof(T).IsEnum)
throw new ArgumentException("The generic type parameter must be an Enum.");
if (flags.GetType() != typeof(T))
throw new ArgumentException("The generic type parameter does not match the target type.");
ulong flag = 1;
foreach (var value in Enum.GetValues(flags.GetType()).Cast<T>())
{
ulong bits = Convert.ToUInt64(value);
while (flag < bits)
{
flag <<= 1;
}
if (flag == bits && flags.HasFlag(value as Enum))
{
yield return value;
}
}
}
EDIT
And +1 for #AustinWBryan for bringing C# 7.3 into the solution space.
public static IEnumerable<T> GetUniqueFlags<T>(this T flags) where T : Enum
{
ulong flag = 1;
foreach (var value in Enum.GetValues(flags.GetType()).Cast<T>())
{
ulong bits = Convert.ToUInt64(value);
while (flag < bits)
{
flag <<= 1;
}
if (flag == bits && flags.HasFlag(value as Enum))
{
yield return value;
}
}
}
Extension method using the new Enum constraint and generics to prevent casting:
public static class EnumExtensions
{
public static T[] GetFlags<T>(this T flagsEnumValue) where T : Enum
{
return Enum
.GetValues(typeof(T))
.Cast<T>()
.Where(e => flagsEnumValue.HasFlag(e))
.ToArray();
}
}
Continuing in my efforts to make the code shorter, this is my latest version of the routine. (I'm the OP...long story.) As discussed previously, this ignores None and multi-bit values.
Note that this uses an Enum constraint and a var pattern, so will require at least C# 7.3.
public static IEnumerable<T> GetUniqueFlags<T>(this T value)
where T : Enum
{
var valueLong = Convert.ToUInt64(value, CultureInfo.InvariantCulture);
foreach (var enumValue in value.GetType().GetEnumValues())
{
if (
enumValue is T flag // cast enumValue to T
&& Convert.ToUInt64(flag, CultureInfo.InvariantCulture) is var bitValue // convert flag to ulong
&& (bitValue & (bitValue - 1)) == 0 // is this a single-bit value?
&& (valueLong & bitValue) != 0 // is the bit set?
)
{
yield return flag;
}
}
}
Wasn't satisfied with the answers above, although they were the start.
After piecing together some different sources here:
Previous poster in this thread's SO QnA
Code Project Enum Flags Check Post
Great Enum<T> Utility
I created this so let me know what you think.
Parameters:
bool checkZero: tells it to allow 0 as a flag value. By default input = 0 returns empty.
bool checkFlags: tells it to check whether the Enum is decorated w/ the [Flags] attribute.
PS. I don't have time right now to figure out the checkCombinators = false alg which will force it to ignore any enum values which are combinations of bits.
public static IEnumerable<TEnum> GetFlags<TEnum>(this TEnum input, bool checkZero = false, bool checkFlags = true, bool checkCombinators = true)
{
Type enumType = typeof(TEnum);
if (!enumType.IsEnum)
yield break;
ulong setBits = Convert.ToUInt64(input);
// if no flags are set, return empty
if (!checkZero && (0 == setBits))
yield break;
// if it's not a flag enum, return empty
if (checkFlags && !input.GetType().IsDefined(typeof(FlagsAttribute), false))
yield break;
if (checkCombinators)
{
// check each enum value mask if it is in input bits
foreach (TEnum value in Enum<TEnum>.GetValues())
{
ulong valMask = Convert.ToUInt64(value);
if ((setBits & valMask) == valMask)
yield return value;
}
}
else
{
// check each enum value mask if it is in input bits
foreach (TEnum value in Enum <TEnum>.GetValues())
{
ulong valMask = Convert.ToUInt64(value);
if ((setBits & valMask) == valMask)
yield return value;
}
}
}
This makes use of the Helper Class Enum<T> found here that I updated to use yield return for GetValues:
public static class Enum<TEnum>
{
public static TEnum Parse(string value)
{
return (TEnum)Enum.Parse(typeof(TEnum), value);
}
public static IEnumerable<TEnum> GetValues()
{
foreach (object value in Enum.GetValues(typeof(TEnum)))
yield return ((TEnum)value);
}
}
Finally, here's a example of using it:
private List<CountType> GetCountTypes(CountType countTypes)
{
List<CountType> cts = new List<CountType>();
foreach (var ct in countTypes.GetFlags())
cts.Add(ct);
return cts;
}
What I did was change my approach, instead of typing the input parameter of the method as the enum type, I typed it as an array of the enum type (MyEnum[] myEnums), this way I just iterate through the array with a switch statement inside the loop.
Here's yet another C# 7.3 solution using Linq
using System;
using System.Collections.Generic;
using System.Linq;
public static class FlagEnumExtensions
{
public static IEnumerable<T> GetFlags<T>(this T en) where T : struct, Enum
{
return Enum.GetValues<T>().Where(member => en.HasFlag(member)).ToArray();
}
}
Edit: added .ToArray() to prevent multiple enumerations.
You dont need to iterate all values. just check your specific flags like so:
if((myVar & FlagsEnum.Flag1) == FlagsEnum.Flag1)
{
//do something...
}
or (as pstrjds said in comments) you can check for use it like:
if(myVar.HasFlag(FlagsEnum.Flag1))
{
//do something...
}
Building upon Greg's answer above, this also takes care of the case where you have a value 0 in your enum, such as None = 0. In which case, it should not iterate over that value.
public static IEnumerable<Enum> ToEnumerable(this Enum input)
{
foreach (Enum value in Enum.GetValues(input.GetType()))
if (input.HasFlag(value) && Convert.ToInt64(value) != 0)
yield return value;
}
Would anyone know how to improve upon this even further so that it can handle the case where all flags in the enum are set in a super smart way that could handle all underlying enum type and the case of All = ~0 and All = EnumValue1 | EnumValue2 | EnumValue3 | ...
You can use an Iterator from the Enum. Starting from the MSDN code:
public class DaysOfTheWeek : System.Collections.IEnumerable
{
int[] dayflag = { 1, 2, 4, 8, 16, 32, 64 };
string[] days = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
public string value { get; set; }
public System.Collections.IEnumerator GetEnumerator()
{
for (int i = 0; i < days.Length; i++)
{
if value >> i & 1 == dayflag[i] {
yield return days[i];
}
}
}
}
It's not tested, so if I made a mistake feel free to call me out. (obviously it's not re-entrant.) You'd have to assign value beforehand, or break it out into another function that uses enum.dayflag and enum.days. You might be able to go somewhere with the outline.
All the answers work well with simple flags, you're probably going to get into issues when flags are combined.
[Flags]
enum Food
{
None=0
Bread=1,
Pasta=2,
Apples=4,
Banana=8,
WithGluten=Bread|Pasta,
Fruits = Apples | Banana,
}
probably need to add a check to test if the enum value it self is a combination.
You'd probably need something like posted here by Henk van Boeijen
to cover your requirement (you need to scroll down a bit)
When it comes to performance, which is important in game development, all solutions given are terrible because of garbage allocation and slow speed. This is a garbage free, over 100 times faster solution than accepted answer.
[Flags]
public enum PersonalTraits : short
{
None = 1 << 0,
Strength = 1 << 1,
Agility = 1 << 2,
Attack = 1 << 3,
Defence = 1 << 4,
Vitality = 1 << 5,
Stamina = 1 << 6,
Accuracy = 1 << 7,
Perception = 1 << 8,
Charisma = 1 << 9,
}
PersonalTraits athlete = PersonalTraits.Stamina | PersonalTraits.Strength;
for (short i = 0, value = 0; value <= (short)PersonalTraits.Charisma; i++, value = (short)(1 << i))
if (((short)athlete & value) != 0)
yield return (PersonalTraits)value;
It could be aswell as the following code:
public static string GetEnumString(MyEnum inEnumValue)
{
StringBuilder sb = new StringBuilder();
foreach (MyEnum e in Enum.GetValues(typeof(MyEnum )))
{
if ((e & inEnumValue) != 0)
{
sb.Append(e.ToString());
sb.Append(", ");
}
}
return sb.ToString().Trim().TrimEnd(',');
}
It goes inside if only when the enum value is contained on the value
You can do it directly by converting to int but you will loose type checking.
I think the best way is use something similar to my proposition. It keep the proper type all the way. No conversion required. It is not perfect due to boxing which will add a little hit in performance.
Not perfect (boxing), but it does the job with no warning...
/// <summary>
/// Return an enumerators of input flag(s)
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public static IEnumerable<T> GetFlags<T>(this T input)
{
foreach (Enum value in Enum.GetValues(input.GetType()))
{
if ((int) (object) value != 0) // Just in case somebody has defined an enum with 0.
{
if (((Enum) (object) input).HasFlag(value))
yield return (T) (object) value;
}
}
}
Usage:
FileAttributes att = FileAttributes.Normal | FileAttributes.Compressed;
foreach (FileAttributes fa in att.GetFlags())
{
...
}
If I have a variable holding a flags enum, can I somehow iterate over the single-bit values in that specific variable? Or do I have to use Enum.GetValues to iterate over the entire enum and check which ones are set?
static IEnumerable<Enum> GetFlags(Enum input)
{
foreach (Enum value in Enum.GetValues(input.GetType()))
if (input.HasFlag(value))
yield return value;
}
Here is a Linq solution to the problem.
public static IEnumerable<Enum> GetFlags(this Enum e)
{
return Enum.GetValues(e.GetType()).Cast<Enum>().Where(e.HasFlag);
}
There aren't any builtin methods to get each component as far as I know. But here's one way you can get them:
[Flags]
enum Items
{
None = 0x0,
Foo = 0x1,
Bar = 0x2,
Baz = 0x4,
Boo = 0x6,
}
var value = Items.Foo | Items.Bar;
var values = value.ToString()
.Split(new[] { ", " }, StringSplitOptions.None)
.Select(v => (Items)Enum.Parse(typeof(Items), v));
// This method will always end up with the most applicable values
value = Items.Bar | Items.Baz;
values = value.ToString()
.Split(new[] { ", " }, StringSplitOptions.None)
.Select(v => (Items)Enum.Parse(typeof(Items), v)); // Boo
I adapted what Enum does internally to generate the string to instead return the flags. You can look at the code in reflector and should be more or less equivalent. Works well for general use cases where there are values which contain multiple bits.
static class EnumExtensions
{
public static IEnumerable<Enum> GetFlags(this Enum value)
{
return GetFlags(value, Enum.GetValues(value.GetType()).Cast<Enum>().ToArray());
}
public static IEnumerable<Enum> GetIndividualFlags(this Enum value)
{
return GetFlags(value, GetFlagValues(value.GetType()).ToArray());
}
private static IEnumerable<Enum> GetFlags(Enum value, Enum[] values)
{
ulong bits = Convert.ToUInt64(value);
List<Enum> results = new List<Enum>();
for (int i = values.Length - 1; i >= 0; i--)
{
ulong mask = Convert.ToUInt64(values[i]);
if (i == 0 && mask == 0L)
break;
if ((bits & mask) == mask)
{
results.Add(values[i]);
bits -= mask;
}
}
if (bits != 0L)
return Enumerable.Empty<Enum>();
if (Convert.ToUInt64(value) != 0L)
return results.Reverse<Enum>();
if (bits == Convert.ToUInt64(value) && values.Length > 0 && Convert.ToUInt64(values[0]) == 0L)
return values.Take(1);
return Enumerable.Empty<Enum>();
}
private static IEnumerable<Enum> GetFlagValues(Type enumType)
{
ulong flag = 0x1;
foreach (var value in Enum.GetValues(enumType).Cast<Enum>())
{
ulong bits = Convert.ToUInt64(value);
if (bits == 0L)
//yield return value;
continue; // skip the zero value
while (flag < bits) flag <<= 1;
if (flag == bits)
yield return value;
}
}
}
The extension method GetIndividualFlags() gets all the individual flags for a type. So values containing multiple bits are left out.
var value = Items.Bar | Items.Baz;
value.GetFlags(); // Boo
value.GetIndividualFlags(); // Bar, Baz
Coming back at this a few years later, with a bit more experience, my ultimate answer for single-bit values only, moving from lowest bit to highest bit, is a slight variant of Jeff Mercado's inner routine:
public static IEnumerable<Enum> GetUniqueFlags(this Enum flags)
{
ulong flag = 1;
foreach (var value in Enum.GetValues(flags.GetType()).Cast<Enum>())
{
ulong bits = Convert.ToUInt64(value);
while (flag < bits)
{
flag <<= 1;
}
if (flag == bits && flags.HasFlag(value))
{
yield return value;
}
}
}
It seems to work, and despite my objections of some years ago, I use HasFlag here, since it's far more legible than using bitwise comparisons and the speed difference is insignificant for anything I'll be doing. (It's entirely possible they've improved the speed of HasFlags since then anyway, for all I know...I haven't tested.)
Going off of #Greg's method, but adding a new feature from C# 7.3, the Enum constraint:
public static IEnumerable<T> GetUniqueFlags<T>(this T flags)
where T : Enum // New constraint for C# 7.3
{
foreach (Enum value in Enum.GetValues(flags.GetType()))
if (flags.HasFlag(value))
yield return (T)value;
}
The new constraint allows this to be an extension method, without having to cast through (int)(object)e, and I can use the HasFlag method and cast directly to T from value.
C# 7.3 also added constraints to for delegates and unmanaged.
+1 for the answer provided by #RobinHood70. I found that a generic version of the method was convenient for me.
public static IEnumerable<T> GetUniqueFlags<T>(this Enum flags)
{
if (!typeof(T).IsEnum)
throw new ArgumentException("The generic type parameter must be an Enum.");
if (flags.GetType() != typeof(T))
throw new ArgumentException("The generic type parameter does not match the target type.");
ulong flag = 1;
foreach (var value in Enum.GetValues(flags.GetType()).Cast<T>())
{
ulong bits = Convert.ToUInt64(value);
while (flag < bits)
{
flag <<= 1;
}
if (flag == bits && flags.HasFlag(value as Enum))
{
yield return value;
}
}
}
EDIT
And +1 for #AustinWBryan for bringing C# 7.3 into the solution space.
public static IEnumerable<T> GetUniqueFlags<T>(this T flags) where T : Enum
{
ulong flag = 1;
foreach (var value in Enum.GetValues(flags.GetType()).Cast<T>())
{
ulong bits = Convert.ToUInt64(value);
while (flag < bits)
{
flag <<= 1;
}
if (flag == bits && flags.HasFlag(value as Enum))
{
yield return value;
}
}
}
Extension method using the new Enum constraint and generics to prevent casting:
public static class EnumExtensions
{
public static T[] GetFlags<T>(this T flagsEnumValue) where T : Enum
{
return Enum
.GetValues(typeof(T))
.Cast<T>()
.Where(e => flagsEnumValue.HasFlag(e))
.ToArray();
}
}
Continuing in my efforts to make the code shorter, this is my latest version of the routine. (I'm the OP...long story.) As discussed previously, this ignores None and multi-bit values.
Note that this uses an Enum constraint and a var pattern, so will require at least C# 7.3.
public static IEnumerable<T> GetUniqueFlags<T>(this T value)
where T : Enum
{
var valueLong = Convert.ToUInt64(value, CultureInfo.InvariantCulture);
foreach (var enumValue in value.GetType().GetEnumValues())
{
if (
enumValue is T flag // cast enumValue to T
&& Convert.ToUInt64(flag, CultureInfo.InvariantCulture) is var bitValue // convert flag to ulong
&& (bitValue & (bitValue - 1)) == 0 // is this a single-bit value?
&& (valueLong & bitValue) != 0 // is the bit set?
)
{
yield return flag;
}
}
}
Wasn't satisfied with the answers above, although they were the start.
After piecing together some different sources here:
Previous poster in this thread's SO QnA
Code Project Enum Flags Check Post
Great Enum<T> Utility
I created this so let me know what you think.
Parameters:
bool checkZero: tells it to allow 0 as a flag value. By default input = 0 returns empty.
bool checkFlags: tells it to check whether the Enum is decorated w/ the [Flags] attribute.
PS. I don't have time right now to figure out the checkCombinators = false alg which will force it to ignore any enum values which are combinations of bits.
public static IEnumerable<TEnum> GetFlags<TEnum>(this TEnum input, bool checkZero = false, bool checkFlags = true, bool checkCombinators = true)
{
Type enumType = typeof(TEnum);
if (!enumType.IsEnum)
yield break;
ulong setBits = Convert.ToUInt64(input);
// if no flags are set, return empty
if (!checkZero && (0 == setBits))
yield break;
// if it's not a flag enum, return empty
if (checkFlags && !input.GetType().IsDefined(typeof(FlagsAttribute), false))
yield break;
if (checkCombinators)
{
// check each enum value mask if it is in input bits
foreach (TEnum value in Enum<TEnum>.GetValues())
{
ulong valMask = Convert.ToUInt64(value);
if ((setBits & valMask) == valMask)
yield return value;
}
}
else
{
// check each enum value mask if it is in input bits
foreach (TEnum value in Enum <TEnum>.GetValues())
{
ulong valMask = Convert.ToUInt64(value);
if ((setBits & valMask) == valMask)
yield return value;
}
}
}
This makes use of the Helper Class Enum<T> found here that I updated to use yield return for GetValues:
public static class Enum<TEnum>
{
public static TEnum Parse(string value)
{
return (TEnum)Enum.Parse(typeof(TEnum), value);
}
public static IEnumerable<TEnum> GetValues()
{
foreach (object value in Enum.GetValues(typeof(TEnum)))
yield return ((TEnum)value);
}
}
Finally, here's a example of using it:
private List<CountType> GetCountTypes(CountType countTypes)
{
List<CountType> cts = new List<CountType>();
foreach (var ct in countTypes.GetFlags())
cts.Add(ct);
return cts;
}
What I did was change my approach, instead of typing the input parameter of the method as the enum type, I typed it as an array of the enum type (MyEnum[] myEnums), this way I just iterate through the array with a switch statement inside the loop.
Here's yet another C# 7.3 solution using Linq
using System;
using System.Collections.Generic;
using System.Linq;
public static class FlagEnumExtensions
{
public static IEnumerable<T> GetFlags<T>(this T en) where T : struct, Enum
{
return Enum.GetValues<T>().Where(member => en.HasFlag(member)).ToArray();
}
}
Edit: added .ToArray() to prevent multiple enumerations.
You dont need to iterate all values. just check your specific flags like so:
if((myVar & FlagsEnum.Flag1) == FlagsEnum.Flag1)
{
//do something...
}
or (as pstrjds said in comments) you can check for use it like:
if(myVar.HasFlag(FlagsEnum.Flag1))
{
//do something...
}
Building upon Greg's answer above, this also takes care of the case where you have a value 0 in your enum, such as None = 0. In which case, it should not iterate over that value.
public static IEnumerable<Enum> ToEnumerable(this Enum input)
{
foreach (Enum value in Enum.GetValues(input.GetType()))
if (input.HasFlag(value) && Convert.ToInt64(value) != 0)
yield return value;
}
Would anyone know how to improve upon this even further so that it can handle the case where all flags in the enum are set in a super smart way that could handle all underlying enum type and the case of All = ~0 and All = EnumValue1 | EnumValue2 | EnumValue3 | ...
You can use an Iterator from the Enum. Starting from the MSDN code:
public class DaysOfTheWeek : System.Collections.IEnumerable
{
int[] dayflag = { 1, 2, 4, 8, 16, 32, 64 };
string[] days = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" };
public string value { get; set; }
public System.Collections.IEnumerator GetEnumerator()
{
for (int i = 0; i < days.Length; i++)
{
if value >> i & 1 == dayflag[i] {
yield return days[i];
}
}
}
}
It's not tested, so if I made a mistake feel free to call me out. (obviously it's not re-entrant.) You'd have to assign value beforehand, or break it out into another function that uses enum.dayflag and enum.days. You might be able to go somewhere with the outline.
All the answers work well with simple flags, you're probably going to get into issues when flags are combined.
[Flags]
enum Food
{
None=0
Bread=1,
Pasta=2,
Apples=4,
Banana=8,
WithGluten=Bread|Pasta,
Fruits = Apples | Banana,
}
probably need to add a check to test if the enum value it self is a combination.
You'd probably need something like posted here by Henk van Boeijen
to cover your requirement (you need to scroll down a bit)
When it comes to performance, which is important in game development, all solutions given are terrible because of garbage allocation and slow speed. This is a garbage free, over 100 times faster solution than accepted answer.
[Flags]
public enum PersonalTraits : short
{
None = 1 << 0,
Strength = 1 << 1,
Agility = 1 << 2,
Attack = 1 << 3,
Defence = 1 << 4,
Vitality = 1 << 5,
Stamina = 1 << 6,
Accuracy = 1 << 7,
Perception = 1 << 8,
Charisma = 1 << 9,
}
PersonalTraits athlete = PersonalTraits.Stamina | PersonalTraits.Strength;
for (short i = 0, value = 0; value <= (short)PersonalTraits.Charisma; i++, value = (short)(1 << i))
if (((short)athlete & value) != 0)
yield return (PersonalTraits)value;
It could be aswell as the following code:
public static string GetEnumString(MyEnum inEnumValue)
{
StringBuilder sb = new StringBuilder();
foreach (MyEnum e in Enum.GetValues(typeof(MyEnum )))
{
if ((e & inEnumValue) != 0)
{
sb.Append(e.ToString());
sb.Append(", ");
}
}
return sb.ToString().Trim().TrimEnd(',');
}
It goes inside if only when the enum value is contained on the value
You can do it directly by converting to int but you will loose type checking.
I think the best way is use something similar to my proposition. It keep the proper type all the way. No conversion required. It is not perfect due to boxing which will add a little hit in performance.
Not perfect (boxing), but it does the job with no warning...
/// <summary>
/// Return an enumerators of input flag(s)
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public static IEnumerable<T> GetFlags<T>(this T input)
{
foreach (Enum value in Enum.GetValues(input.GetType()))
{
if ((int) (object) value != 0) // Just in case somebody has defined an enum with 0.
{
if (((Enum) (object) input).HasFlag(value))
yield return (T) (object) value;
}
}
}
Usage:
FileAttributes att = FileAttributes.Normal | FileAttributes.Compressed;
foreach (FileAttributes fa in att.GetFlags())
{
...
}
I have a value thats 5 bits in length. 4 bits determine the number and the 5th bit determines the sign, there by holding any value between -16 and +15. How can I accomplish sign extending from a constant bit width in C#? I know in C, I can use something like the follow to accomplish this:
int x; // convert this from using 5 bits to a full int
int r; // resulting sign extended number goes here
struct {signed int x:5;} s;
r = s.x = x;
How can I do something similar to this in C#?
It's not really clear what you mean, but it could be as simple as:
int fiveBits = normal & 0x1f;
and for the reverse:
int normal = fiveBits < 16 ? fiveBits : fiveBits | -32;
If you could suggest some original input and desired output, that would help.
Perform a left shift followed by an arithmetic right shift to move the sign bit into the high position and then back. The arithmetic right shift will perform the sign extension for you.
Of course this depends on having a working arithmetic shift operation. The abstract C language does not (it's implementation-defined whether it works or not), but most implementations do. I'm not sure about C# but I would guess it has one.
I know this is an old question, but for future searchers I have more info.
C# does not support custom bit widths, but it does support binary operations and getters/setters, which makes it relatively easy to add a compatibility layer. For instance, if you want to store the raw data in a byte _num, but want to be able to interact with it using a standard C# sbyte, you can use the following:
byte _num;
sbyte num {
get
{
return (sbyte)(((_num & 0x10) << 3) | (_num & 0x0F));
}
set
{
_num = (byte)((value & 0x0F) | ((value & 0x80) >> 3));
}
}
This kind of shell is especially useful when interacting with low level firmware or embedded projects.
I'm just writing a C function (because I don't really know C#) that will do this using operations that I know are available in C#.
int five_bit_to_signed(int five_bit) {
int sh = (sizeof(int)*8)-5;
int x = five_bit << sh; // puts your sign bit in the highest bit.
return x >> sh; // since x is signed this is an arithmatic signed shift
}
From your question, it appears you wish to have a structure that can readily be converted to and from an int type:
struct FiveBit
{
public int bits;
public static implicit operator int(FiveBit f)
{
return (f.bits & 0x10) == 0 ? f.bits : f.bits | -32;
}
public static implicit operator FiveBit(int r)
{
return new FiveBit() { bits = r & 0x1f };
}
}
And here's an example of usage:
class FiveBitTest
{
static void Main(string[] args)
{
FiveBit f = new FiveBit();
int r; // resulting sign extended number goes here
f.bits = 0;
r = f;
Console.WriteLine("r = {0}, f.bits = 0x{1:X}", r, f.bits);
f.bits = 0x1f;
r = f;
Console.WriteLine("r = {0}, f.bits = 0x{1:X}", r, f.bits);
r = -2;
f = r;
Console.WriteLine("r = {0}, f.bits = 0x{1:X}", r, f.bits);
}
The output of the above is:
r = 0, f.bits = 0x0
r = -1, f.bits = 0x1F
r = -2, f.bits = 0x1E
Consider this:
[Flags]
enum Colors
{
Red=1,
Green=2,
Blue=4
}
Colors myColor=Colors.Red|Colors.Blue;
Currently, I'm doing it as follows:
int length=myColors.ToString().Split(new char[]{','}).Length;
But I hope there is a more efficient way of finding the length, maybe based on bitset operations.
Please, if possible, provide explanation why and how your solution works.
Also, if this a duplicate, please point to it and I'll delete this question. The only similar questions on SO I've been able to find were concerned about finding the length of all possible combinations of Colors enum, but not of the myColors variable.
UPDATE: I carefully benchmarked every solution (1 000 000 iterations each) and here is the results:
Stevo3000 - 8ms
MattEvans - 10ms
Silky - 34ms
Luke - 1757ms
Guffa - 4226ms
Tomas Levesque - 32810ms
The Stevo3000 is a clear winner (with Matt Evans holding silver medal).
Thank you very much for your help.
UPDATE 2:
This solution runs even faster: 41 ms for 100 000 000 iterations (roughly 40 times faster (32bit OS) than Stevo3000)
UInt32 v = (UInt32)co;
v = v - ((v >> 1) & 0x55555555);
v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
UInt32 count = ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
The following code will give you the number of bits that are set for a given number of any type varying in size from byte up to long.
public static int GetSetBitCount(long lValue)
{
int iCount = 0;
//Loop the value while there are still bits
while (lValue != 0)
{
//Remove the end bit
lValue = lValue & (lValue - 1);
//Increment the count
iCount++;
}
//Return the count
return iCount;
}
This code is very efficient as it only iterates once for each bit rather than once for every possible bit as in the other examples.
Here are a few extension methods to manipulate Flags enumerations :
public static class EnumExtensions
{
private static void CheckEnumWithFlags<T>()
{
if (!typeof(T).IsEnum)
throw new ArgumentException(string.Format("Type '{0}' is not an enum", typeof(T).FullName));
if (!Attribute.IsDefined(typeof(T), typeof(FlagsAttribute)))
throw new ArgumentException(string.Format("Type '{0}' doesn't have the 'Flags' attribute", typeof(T).FullName));
}
public static bool IsFlagSet<T>(this T value, T flag) where T : struct
{
CheckEnumWithFlags<T>();
long lValue = Convert.ToInt64(value);
long lFlag = Convert.ToInt64(flag);
return (lValue & lFlag) != 0;
}
public static IEnumerable<T> GetFlags<T>(this T value) where T : struct
{
CheckEnumWithFlags<T>();
foreach (T flag in Enum.GetValues(typeof(T)).Cast<T>())
{
if (value.IsFlagSet(flag))
yield return flag;
}
}
public static T SetFlags<T>(this T value, T flags, bool on) where T : struct
{
CheckEnumWithFlags<T>();
long lValue = Convert.ToInt64(value);
long lFlag = Convert.ToInt64(flags);
if (on)
{
lValue |= lFlag;
}
else
{
lValue &= (~lFlag);
}
return (T)Enum.ToObject(typeof(T), lValue);
}
public static T SetFlags<T>(this T value, T flags) where T : struct
{
return value.SetFlags(flags, true);
}
public static T ClearFlags<T>(this T value, T flags) where T : struct
{
return value.SetFlags(flags, false);
}
public static T CombineFlags<T>(this IEnumerable<T> flags) where T : struct
{
CheckEnumWithFlags<T>();
long lValue = 0;
foreach (T flag in flags)
{
long lFlag = Convert.ToInt64(flag);
lValue |= lFlag;
}
return (T)Enum.ToObject(typeof(T), lValue);
}
}
In your case you can use the GetFlags method :
int count = myColors.GetFlags().Count();
It's probably not as efficient as Luke's answer, but it's easier to use...
Here's my take on this... it counts the number of set bits in the value
int val = (int)myColor;
int count = 0;
while (val > 0)
{
if((val & 1) != 0)
{
count++;
}
val = val >> 1;
}
Here's a reasonably easy way of counting the bits. Each bit is shifted in-turn to the LSB of an Int64 which is AND-ed with 1 (to mask out any of the other bits) and then added to the running total.
int length = Enumerable.Range(0, 64).Sum(x => ((long)myColor >> x) & 1);
A rough approximation will be just counting the number of bits set in myColors, but that will only work if every enumeration members' value is power of 2.
Assuming they are flags, you can just use one of the methods here, to count the number of bits set.
It works because, as long as they are flags, when each one is 'OR'd' on, it sets one bit.
-- Edit
Sample code using one of the methods on that link:
[Flags]
enum Test
{
F1 = 1,
F2 = 2,
F3 = 4
}
class Program
{
static void Main(string[] args)
{
int v = (int) (Test.F1 | Test.F2 | Test.F3); // count bits set in this (32-bit value)
int c = 0; // store the total here
int[] S = {1, 2, 4, 8, 16}; // Magic Binary Numbers
int[] B = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF, 0x0000FFFF};
c = v - ((v >> 1) & B[0]);
c = ((c >> S[1]) & B[1]) + (c & B[1]);
c = ((c >> S[2]) + c) & B[2];
c = ((c >> S[3]) + c) & B[3];
c = ((c >> S[4]) + c) & B[4];
Console.WriteLine(c);
Console.Read();
}
}
I've made a helper method for myself. Maybe it'll be useful for others.
public static class EnumHelper
{
public static UInt32 NumFlags(this Enum e)
{
UInt32 v = Convert.ToUInt32(e);
v = v - ((v >> 1) & 0x55555555);
v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
UInt32 count = ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
return count;
}
}
The solution that is most reliable is to test for each value in the enumeration:
int len = 0;
foreach (Colors color in Enum.GetValues(typeof(Colors))) {
if ((myColor & color) == color) {
len++;
}
}
This will work even if the value has bits set where there are no defined value in the enumeration, for example:
Colors myColor = (Colors)65535;
This will also work for enumerations with values that use more than a single bit:
[Flags]
enum Colors {
Red = 0xFF0000,
Green = 0x00FF00,
Blue = 0x0000FF
}
int value = Enum.GetNames(typeof(Colors)).Length;
public static int NumberOfOptions(int value)
{
int result = (int)Math.Pow(2, value-1);
return result;
}
Try this...
Colors.GetValues().Length();
...or is that too obvious?
EDIT:
OK, I just read the question again, and realised that you need the length of 'mycolors', not 'Colors' - let me think about that.
FURTHER EDIT:
Now I'm confused - the OP's posted solution would never work, as myColor.ToString() returns '5' and applying Split(new char[]{','}) to this would result in a array with a length of 1.
Did the OP actually get this to work?
I have a set of five boolean values. If more than one of these are true I want to excecute a particular function. What is the most elegant way you can think of that would allow me to check this condition in a single if() statement? Target language is C# but I'm interested in solutions in other languages as well (as long as we're not talking about specific built-in functions).
One interesting option is to store the booleans in a byte, do a right shift and compare with the original byte. Something like if(myByte && (myByte >> 1)) But this would require converting the separate booleans to a byte (via a bitArray?) and that seems a bit (pun intended) clumsy... [edit]Sorry, that should have been if(myByte & (myByte - 1)) [/edit]
Note: This is of course very close to the classical "population count", "sideways addition" or "Hamming weight" programming problem - but not quite the same. I don't need to know how many of the bits are set, only if it is more than one. My hope is that there is a much simpler way to accomplish this.
I was going to write the Linq version, but five or so people beat me to it. But I really like the params approach to avoid having to manually new up an array. So I think the best hybrid is, based on rp's answer with the body replace with the obvious Linqness:
public static int Truth(params bool[] booleans)
{
return booleans.Count(b => b);
}
Beautifully clear to read, and to use:
if (Truth(m, n, o, p, q) > 2)
How about
if ((bool1? 1:0) + (bool2? 1:0) + (bool3? 1:0) +
(bool4? 1:0) + (bool5? 1:0) > 1)
// do something
or a generalized method would be...
public bool ExceedsThreshold(int threshold, IEnumerable<bool> bools)
{
int trueCnt = 0;
foreach(bool b in bools)
if (b && (++trueCnt > threshold))
return true;
return false;
}
or using LINQ as suggested by other answers:
public bool ExceedsThreshold(int threshold, IEnumerable<bool> bools)
{ return bools.Count(b => b) > threshold; }
EDIT (to add Joel Coehoorn suggestion:
(in .Net 2.x and later)
public void ExceedsThreshold<T>(int threshold,
Action<T> action, T parameter,
IEnumerable<bool> bools)
{ if (ExceedsThreshold(threshold, bools)) action(parameter); }
or in .Net 3.5 and later:
public void ExceedsThreshold(int threshold,
Action action, IEnumerable<bool> bools)
{ if (ExceedsThreshold(threshold, bools)) action(); }
or as an extension to IEnumerable<bool>
public static class IEnumerableExtensions
{
public static bool ExceedsThreshold<T>
(this IEnumerable<bool> bools, int threshold)
{ return bools.Count(b => b) > threshold; }
}
usage would then be:
var bools = new [] {true, true, false, false, false, false, true};
if (bools.ExceedsThreshold(3))
// code to execute ...
It's time for the obligatory LINQ answer, which in this case is actually quite neat.
var bools = new[] { true, true, false, false, false };
return bools.Count(b => b == true) > 1;
I would just cast them to ints and sum.
Unless you're in a super tight inner loop, that has the benefit of being easy to understand.
if you mean more than or equal to one boolean equals to true, you could do it like
if (bool1 || bool2 || bool3 || bool4 || bool5)
If you need more than one (2 and above) booleans equal to true, you can try
int counter = 0;
if (bool1) counter++;
if (bool2) counter++;
if (bool3) counter++;
if (bool4) counter++;
if (bool5) counter++;
if (counter >= 2) //More than 1 boolean is true
I'd write a function to receive any number of boolean values. It would return the number of those values that are true. Check the result for the number of values you need to be positive to do something.
Work harder to make it clear, not clever!
private int CountTrues( params bool[] booleans )
{
int result = 0;
foreach ( bool b in booleans )
{
if ( b ) result++;
}
return result;
}
If there were millions instead of just 5 you could avoid Count()and do this instead ...
public static bool MoreThanOne (IEnumerable<bool> booleans)
{
return booleans.SkipWhile(b => !b).Skip(1).Any(b => b);
}
If your flags are packed into one word then Michael Burr's solution will work. However, the loop is not necessary:
int moreThanOneBitSet( unsigned int v)
{
return (v & (v - 1)) != 0;
}
example
v (binary) | v - 1 | v&(v-1) | result
------------+-------+---------+--------
0000 | 1111 | 0000 | false
0001 | 0000 | 0000 | false
0010 | 0001 | 0000 | false
0011 | 0010 | 0010 | true
.... | .... | .... | ....
1000 | 0111 | 0000 | false
1001 | 1000 | 1000 | true
1010 | 1001 | 1000 | true
1011 | 1010 | 1010 | true
1100 | 1011 | 1000 | true
1101 | 1100 | 1100 | true
1110 | 1101 | 1100 | true
1111 | 1110 | 1110 | true
Shorter and uglier than Vilx-s version:
if (((a||b||c)&&(d||e))||((a||d)&&(b||c||e))||(b&&c)) {}
from the top of my head, a quick approach for this specific example; you could convert the bool to an int (0 or 1). then loop through therm and add them up. if the result >= 2 then you can execute your function.
While I like LINQ, there are some holes in it, like this problem.
Doing a count is fine in general, but can become an issue when the items your counting take a while to calculate/retrieve.
The Any() extension method is fine if you just want to check for any, but if you want to check for at least there's no built in function that will do it and be lazy.
In the end, I wrote a function to return true if there are at least a certain number of items in the list.
public static bool AtLeast<T>(this IEnumerable<T> source, int number)
{
if (source == null)
throw new ArgumentNullException("source");
int count = 0;
using (IEnumerator<T> data = source.GetEnumerator())
while (count < number && data.MoveNext())
{
count++;
}
return count == number;
}
To use:
var query = bools.Where(b => b).AtLeast(2);
This has the benefit of not needing to evaluate all the items before returning a result.
[Plug] My project, NExtension contains AtLeast, AtMost and overrides that allow you to mix in the predicate with the AtLeast/Most check. [/Plug]
Casting to ints and summing should work, but it's a bit ugly and in some languages may not be possible.
How about something like
int count = (bool1? 1:0) + (bool2? 1:0) + (bool3? 1:0) + (bool4? 1:0) + (bool5? 1:0);
Or if you don't care about space, you could just precompute the truth table and use the bools as indices:
if (morethanone[bool1][bool2][bool3][bool4][bool5]) {
... do something ...
}
I would do something like this, using the params argument.
public void YourFunction()
{
if(AtLeast2AreTrue(b1, b2, b3, b4, b5))
{
// do stuff
}
}
private bool AtLeast2AreTrue(params bool[] values)
{
int trueCount = 0;
for(int index = 0; index < values.Length || trueCount >= 2; index++)
{
if(values[index])
trueCount++;
}
return trueCount > 2;
}
if (NumberOfTrue(new List<bool> { bool1, bool2, bool3, bool4 }) >= 2)
{
// do stuff
}
int NumberOfTrue(IEnumerable<bool> bools)
{
return bools.Count(b => b);
}
Not exactly pretty... but here's another way to do it:
if (
(a && (b || c || d || e)) ||
(b && (c || d || e)) ||
(c && (d || e)) ||
(d && e)
)
I have a much much better one now and very short!
bool[] bools = { b1, b2, b3, b4, b5 };
if (bools.Where(x => x).Count() > 1)
{
//do stuff
}
I wanted to give a C++11 variadic template answer.
template< typename T>
T countBool(T v)
{
return v;
}
template< typename T, typename... Args>
int countBool(T first, Args... args)
{
int boolCount = 0;
if ( first )
boolCount++;
boolCount += countBool( args... );
return boolCount;
}
simply calling it as follows creates a rather elegant method of counting the number of bools.
if ( countBool( bool1, bool2, bool3 ) > 1 )
{
....
}
In most languages true is equivalent to a non-zero value while false is zero. I don't have exact syntax for you, but in pseudo code, what about:
if ((bool1 * 1) + (bool2 * 1) + (bool3 * 1) > 2)
{
//statements here
}
If you only have five different values, you can easily do the test by packing the bits in to a short or an int and checking to see if it is any of the zero or one bit answers. The only invalid numbers you could get would be..
0x 0000 0000
0x 0000 0001
0x 0000 0010
0x 0000 0100
0x 0000 1000
0x 0001 0000
This gives you six values to search for, put them in a lookup table and if it's not in there, you have your answer.
This gives you a simple answer.
public static boolean moreThan1BitSet(int b)
{
final short multiBitLookup[] = {
1, 1, 1, 0, 1, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
if(multiBitLookup[b] == 1)
return false;
return true;
}
This doesn't scale well past 8 bits, but you only have five.
if((b1.CompareTo( false ) + b2.CompareTo( false ) + b3.CompareTo( false ) + ...) > 1)
// More than one of them are true
...
else
...
You mentioned
One interesting option is to store the booleans in a byte,
do a right shift and compare with the original byte.
Something like if (myByte && (myByte >> 1))
I don't think that expression will give you the result you want (at least using C semantics, since the expression is not valid C#):
If (myByte == 0x08), then the expression will return true even though there's only one bit set.
If you meant "if (myByte & (myByte >> 1))" then if (myByte == 0x0a) the expression will return false even though there are 2 bits set.
But here are some techniques for counting the number of bits in a word:
Bit Twiddling Hacks - Counting bits
A variation you might consider is to use Kernighan's counting method, but bail out early since you only need to know if there's more than one bit set:
int moreThanOneBitSet( unsigned int v)
{
unsigned int c; // c accumulates the total bits set in v
for (c = 0; v && (c <= 1); c++)
{
v &= v - 1; // clear the least significant bit set
}
return (c > 1);
}
Of course, using a lookup table's not a bad option either.
performance oriented solutions
As the following statements are true in .NET
sizeof(bool) == 1
*(byte*)&someBool == 1 where someBool is true
*(byte*)&someBool == 0 where someBool is false
you could fall back to unsafe code and pointer casting (as C# will not allow simply casting bool to byte or int).
Your code would then look something like this
if (*(byte*)&bool1 + *(byte*)&bool2 + *(byte*)&bool3 > 1)
{
// do stuff
}
The benefit here would be that you don't have any additional branching making this one faster than the obvious myBool ? 1 : 0.
The drawback here would be the usage of unsafe and pointers which often isn't a well received solution in the managed .NET world. Also the assumption that sizeof(bool) == 1 could be questioned as this doesn't apply to all languages but at least in C# .NET it holds true.
If the pointer stuff is too annoying for you, you could always hide it in an extension method:
using System.Runtime.CompilerServices;
// ...
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe int ToInt(this bool b) => *(byte*)&b;
your code would then turn into a more readable
if (bool1.ToInt() + bool2.ToInt() + bool3.ToInt() > 1)
{
// do stuff
}
Obviously you could always combine this with LINQ as you please
if (myBools.Sum(b => b.ToInt()) > 1)
{
// do stuff
}
or if you value performance over anything else this one's probably faster
bool[] myBools = ...
fixed (bool* boolPtr = myBools)
{
byte* bytePtr = (byte*)boolPtr;
int numberOfTrueBools = 0;
// count all true booleans in the array
for (int i = 0; i < myBools.Length; numberOfTrueBools += bytePtr[i], i++);
// do something with your numberOfTrueBools ...
}
Or if you have a huge input array you could even go for a hardware accelerated SIMD solution ...
using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
// ...
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
public static unsafe int CountTrueBytesSIMD(this bool[] myBools)
{
// we need to get a pointer to the bool array to do our magic
fixed (bool* ptr = myBools)
{
// reinterpret all booleans as bytes
byte* bytePtr = (byte*)ptr;
// calculate the number of 32 bit integers that would fit into the array
int dwordLength = myBools.Length >> 2;
// for SIMD, allocate a result vector
Vector128<int> result = Vector128<int>.Zero;
// loop variable
int i = 0;
// it could be that SSSE3 isn't supported...
if (Ssse3.IsSupported)
{
// remember: we're assuming little endian!
// we need this mask to convert the byte vectors to valid int vectors
Vector128<int> cleanupMask = Vector128.Create(0x000000FF);
// iterate over the array processing 16 bytes at once
// TODO: you could even go to 32 byte chunks if AVX-2 is supported...
for (; i < dwordLength - Vector128<int>.Count; i += Vector128<int>.Count)
{
// load 16 bools / bytes from memory
Vector128<byte> v = Sse2.LoadVector128((byte*)((int*)bytePtr + i));
// now count the number of "true" bytes in every 32 bit integers
// 1. shift
Vector128<int> v0 = v.As<byte, int>();
Vector128<int> v1 = Sse2.ShiftRightLogical128BitLane(v, 1).As<byte, int>();
Vector128<int> v2 = Sse2.ShiftRightLogical128BitLane(v, 2).As<byte, int>();
Vector128<int> v3 = Sse2.ShiftRightLogical128BitLane(v, 3).As<byte, int>();
// 2. cleanup invalid bytes
v0 = Sse2.And(v0, cleanupMask);
v1 = Sse2.And(v1, cleanupMask);
v2 = Sse2.And(v2, cleanupMask);
v3 = Sse2.And(v3, cleanupMask);
// 3. add them together. We now have a vector of ints holding the number
// of "true" booleans / 0x01 bytes in their 32 bit memory region
Vector128<int> roundResult = Sse2.Add(Sse2.Add(Sse2.Add(v0, v1), v2), v3);
// 4 now add everything to the result
result = Sse2.Add(result, roundResult);
}
// reduce the result vector to a scalar by horizontally adding log_2(n) times
// where n is the number of words in out vector
result = Ssse3.HorizontalAdd(result, result);
result = Ssse3.HorizontalAdd(result, result);
}
int totalNumberOfTrueBools = result.ToScalar();
// now add all remaining booleans together
// (if the input array wasn't a multiple of 16 bytes or SSSE3 wasn't supported)
i <<= 2;
for (; i < myBools.Length; totalNumberOfTrueBools += bytePtr[i], i++);
return totalNumberOfTrueBools;
}
}
I was recently having this same issue, where I had three boolean values, which I needed to check that only 1 of them was true at a time. For this I used the xor operator as follows:
bool a = true;
bool b = true;
bool c = false;
if (a || b || c)
{
if (a ^ b ^ c){
//Throw Error
}
}
This code will throw an error as a and b are both true.
For reference: http://www.dotnetperls.com/xor
I have only just found the xor operator in C# if anyone knows of any pit falls of this strategy, please let me know.