Combinable Enums

keepcalmI am sure in many cases you have seen enumerations that can be combined using the bitwise OR operator.

It is being used by many libraries that you might have used. It is also useful when you want to set some flags on or off on a specific item in a non OO language or if you wish to pass a specific set of flags in a method.

Combining enumerations looks something like the following

MyEnum value = MyEnum.Value1 | MyEnum.Value2;

So how can we create our own Enumerations that can be combined like this?
First let’s see what bitwise Or when performed on two values.
We all know that when performing an or operation if either of the two sides is true or 1 then the outcome is true (or 1 depending on how we see the values).
So when we perform a bitwise OR operation to two numeral types the OR operation is performed on each bit of the binary representation of each of the two numbers.
Let’s see it in action

int a = 5;  // which is 101 in binary
int b = 4; // which is 100 in binary
int c = a | b;

So what would be the outcome?
Well the value that will be stored in the variable c would be 5, or the binary 101 to be exact.
What goes on behind the scenes looks something like this:

bitwise OR

An OR operation is performed on the first bit of the first number and on the first bit of the second number. So 1 OR 0 = 1. The same goes for the rest of the bits.

So how could we create our Enumeration that can be used with the above technique?
Well it’s actually pretty simple if you think about it. When we want one value to be set then we turn on one bit. When we want two values, the we turn on two bits, when we want three values we turn 3 bits on etc etc.
So our enumeration would be something like the following

public enum combinable

   value0 = 0,  // 0000 in binary
   value1 = 1,  // 0001 in binary
   value2 = 2,  // 0010 in binary
   value3 = 4,  // 0100 in binary
   value4 = 8   // 1000 in binary

So what do we have here? Well basically we have an enumeration whose values are powers of 2. Why you may ask? Because each value can be represented by a single turned on bit. So when we see that specific bit turned on then we know that value/attribute is set as true. for example if we have (in binary) the numer 11 we know that value1 and value2 have been combined using a bitwise OR operation.
But how can we know from code if one value is set then? What coding method do we have in finding out? Well some languages have methods do the check for us. For example C# has the static method Enum.HasFlag() that takes as input the value we get and the enum value that we wish to check. But we want to be language agnostic and language independent here so how can we do that? Well by using another bitwise operation of course. This time we will use bitwise AND.
What is that? Well the bitwise AND operation is exactly like the bitwise or operation but performing AND. What is AND? You really don’t remember?
Well simply put the output of an AND operation is set to 1 if and only if both input values are 1. So in our method if we want to know if one value is set in one enumeration that was past in then we simply do the following check

bool isItSet = (temp & combinable.value3) != 0; 

As we explained before, if a specific bit is turned on, then the respective value is set as true in our enumeration. So if we perform a bitwise AND operation with the value we wish to check and the result is not zero then that value is set.

One might ask “Yeah that’s cool and all devsanon, but what if you enumeration has many flags that can be set? Do I have to actually calculate the powers of 2 for all those flags? I mean 2 to the power of 10 is 1024. What if I have like 30 clients and a specific method is only available to some of them and I want to use this method? Do I really have to calculate all the powers of 2 up to power 30? I mean isn’t there an easier way?”
Well of course there is guys. We just need to use more bitwise operations.
Have you ever heard of shift left logical? It shifts all the turned on bits as many places as we please.

So how can we use the operator << to simplify our enum declarations?

Well as we said before we want only one bit turned on, on a specific position so using the shift left operator we can simply shift the bit left as many positions we want. Our enum declaration would something like the following

public enum combinable

   value2=1 << 1, 
   value3=1 << 2, 
   value4=1 << 3,
   value5=1 << 4 

and each next value representing another power of 2. You don't have to calculate anything. Simply just shift the number one as many positions to the left as you please and you will have your enum.

Please follow and like us:

Leave a Reply