Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if exclusively only these flags set in enumeration

I have created an extension method as such..

public static bool AllFlagsSet<T>(this T input, params T[] values) where T : struct, IConvertible
{
    bool allSet = true;
    int enumVal = input.ToInt32(null);

    foreach (T itm in values)
    {
        int val = itm.ToInt32(null);
        if (!((enumVal & val) == val)) 
        {
            allSet = false;
            break;
        }
    }

    return allSet;
}

Which works great for the purposes I needed, however I now have a requirement to create a method with the same signature which checks if only exclusively those values have been set.

Basically something like this.

public static bool OnlyTheseFlagsSet<T>(this T input, params T[] values) where T : struct, IConvertible
{
}

The only way I can think of doing this is by getting all available enumeration values checking which are set and confirming that only the two provided have been.

Is there another way to solve this problem using some sort of bitwise operation?

like image 266
Maxim Gershkovich Avatar asked Nov 19 '12 02:11

Maxim Gershkovich


3 Answers

Do "or" on all required flags and compare with input - should be equal. Similar to following, with correct loop to compute value on the left:

var onlyTheseFlagsSet = (value[0] | value[1]) == input;
like image 147
Alexei Levenkov Avatar answered Sep 30 '22 07:09

Alexei Levenkov


Exclusivity requirement means that

input = values[0] | values[1] | ... | values[values.Length - 1]

So, here is your implementation:

return input.ToInt32(null) == values.Aggregate(0, 
       (total, next) => total | next.ToInt32(null));
like image 40
Dmitry Frenkel Avatar answered Sep 30 '22 07:09

Dmitry Frenkel


This flips the bit of each input value. If only those are set, the resulting value will be zero. Otherwise, it will flip bits to 1 if the value is not set in input which will leave the value non-zero.

public static bool OnlyTheseFlagsSet<T>(this T input, params T[] values) where T : struct, IConvertible
{
    int enumVal = input.ToInt32(null);

    foreach (T itm in values)
    {
        int val = itm.ToInt32(null);
        enumVal = enumVal ^ val;                
    }

    return (enumVal == 0);
}
like image 22
Patrick Quirk Avatar answered Sep 30 '22 05:09

Patrick Quirk