Combining Enum Value using Bitmask

Thomas Joulin picture Thomas Joulin · Feb 7, 2011 · Viewed 44.5k times · Source

I understand it's possible to use bitmasks in enum values, but I don't know how to create it.

I have a simple enum :

enum State
{
    minimizing = 0,
    maximizing,

    minimized,
    maximized
};

A state is always State.minimized or State.maximized, and can have additional state on resize. So something can be Maximized and minimizing

Answer

Gauthier picture Gauthier · Feb 7, 2011

I am going to assume that myState has the type of your enum State.

The traditional use of enum is to create the constant values that a variable of this type can take. You wish to set you variable myState to a combination of the values defined in the enum.

The enum defines 1, 2, 4, and 8 as valid values, yet you want to be able to set the variable to 4 | 2 = 6. While C uses your implementation-defined int type for all enum, it is not the case in C++. myState = 6 is not valid in C++. Actually, myState = 4 is not either valid in C++, you need to cast explicitly or use one of the constant names of the enum.

Although possible in C, it is not good practice to set myState to a value that is not defined by its type (for example to 6).

In your case, a solution that seems consequent would be:

typedef enum {
    OTHER,
    MINIMIZED,
    MAXIMIZED
} win_size_t;

typedef struct {
    win_size_t current;
    win_size_t next;
} state_t;

state_t myState;

That way, you can write to the fields current and next undependently.

If you still want to have bit fields, you can set the size of the elements of your struct in bits. It is kind of dangerous though, the implementation of bit fields depend on your compiler. I am not even sure if compilers would accept to have an enum type in a bit field (should be ok in C, since enums are int).

typedef struct {
    win_size_t current : 2;  // not tested
    win_size_t next : 2;
} state_t;

The previous given solutions are valid of course. My point is that if your variable myState has your enum State as type, it should only use the members of the enum for its values, not a combination.

Maybe myState has another type, what do I know.


If myState is not of the enum State type, then you may use the constants defined in your enum in combination.

enum State {
    MINIMIZING = (1u << 0),
    MAXIMIZING = (1u << 1),
    MINIMIZED  = (1u << 2),
    MAXIMIZED  = (1u << 3),
};

unsigned int myState = 0;

myState |= MAXIMIZED;  // sets that bit
myState &= ~MAXIMIZED; // resets that bit

This allows you to do two things in one assignment:

myState = MAXIMIZED | MINIMIZING;

But also things you are not likely to want:

myState = MAXIMIZED | MINIMIZED;  // does that make sense?