Using bitwise or operator in switch case

1k Views Asked by At

I have enum,

enum ENUM_MSG_TEXT_CHANGE {COLOR=0,SIZE,UNDERLINE};

    void Func(int nChange)
    {
bool bColor=false, bSize=false;
    switch(nChange)
    {
    case COLOR:bColor=true;break;
    case SIZE:bSize=true;break;
    case COLOR|SIZE:bSize=true; bColor=true;break;
    }
    }

case SIZE: and case COLOR|SIZE: both gives value 1, so I am getting the error C2196: case value '1' already used. How to differentiate these two cases in switch case?

Thanks

3

There are 3 best solutions below

0
On BEST ANSWER

If you want to make a bitmask, every element of your enum has to correspond to a number that is a power of 2, so it has exactly 1 bit set. If you number them otherwise, it won't work. So, the first element should be 1, then 2, then 4, then 8, then 16, and so on, so you won't get overlaps when orring them. Also, you should just test every bit individually instead of using a switch:

if (nChange & COLOR) {
    bColor = true;
}
if (nChange & SIZE) {
    bSize = true;
}
0
On

These two labels

case SIZE:bSize=true;break;
case COLOR|SIZE:bSize=true; bColor=true;break;

evaluates to 1 because SIZE is defined as having the value 1 and the bit-wise operator | used in the label COLOR|SIZE also yields 1.

Usually such enumerations are declared as bitmask types like

enum ENUM_MSG_TEXT_CHANGE { COLOR = 1 << 0, SIZE = 1 << 1, UNDERLINE = 1 << 2 };

In this case this label

case COLOR|SIZE:bSize=true; bColor=true;break;

will be equal to 3.

0
On

When using the binary OR (operator|) you need to assign values to the individual bits (or combinations of bits). Since COLOR has the value 0 it can't be extracted from a bitfield like you try to do.

Also, for the three enums you have, there are 8 possible combinations. To use a switch, you'd need 8 case labels.

Consider this as an alternative:

#include <iostream>

enum ENUM_MSG_TEXT_CHANGE : unsigned {
    COLOR     = 1U << 0U, // 0b001
    SIZE      = 1U << 1U, // 0b010
    UNDERLINE = 1U << 2U  // 0b100
};

void Func(unsigned nChange) {
    // extract the set bits
    bool bColor     = nChange & COLOR;
    bool bSize      = nChange & SIZE;
    bool bUnderline = nChange & UNDERLINE;

    // print out what was extracted
    std::cout << bUnderline << bSize << bColor << '\n';
}

int main() {
    // test all combinations
    for(unsigned change = 0; change <= (COLOR | SIZE | UNDERLINE); ++change) {
        Func(change);
    }
}

Output:

000
001
010
011
100
101
110
111