Philipp Mildenberger
Philipp Mildenberger

Reputation: 550

Compact non-repetitive way for an ALL flag in enums that represent bitflags in C++

I often use enums for bitflags like the following

enum EventType {
    NODE_ADDED = 1 << 0,
    NODE_DELETED = 1 << 1,
    LINK_ADDED = 1 << 2,
    LINK_DELETED = 1 << 3,
    IN_PIN_ADDED = 1 << 4,
    IN_PIN_DELETED = 1 << 5,
    IN_PIN_CHANGE = 1 << 6,
    OUT_PIN_ADDED = 1 << 7,
    OUT_PIN_DELETED = 1 << 8,
    OUT_PIN_CHANGE = 1 << 9,

    ALL = NODE_ADDED | NODE_DELETED | ...,
};

Is there a clean less repetitive way to define an ALL flag that combines all other flags in an enum? For small enums the above works well, but lets say there are 30 flags in an enum, it gets tedious to do it this way. Does something work (in general) like this

ALL = -1

?

Upvotes: 0

Views: 50

Answers (2)

MSalters
MSalters

Reputation: 179789

The root problem here is how may one-bits you need. That depends on the number of enumerators previously. Trying to define ALL inside the enum makes that a case of circular logic

Instead, you have to define it outside the enum:

const auto ALL = (EventType) ~EventType{};

EventType{} has sufficient zeroes, ~ turns it into an integral type with enough ones, so you need another cast back to EventType

Upvotes: 1

Hatted Rooster
Hatted Rooster

Reputation: 36463

Use something that'll always cover every other option, like:

ALL = 0xFFFFFFFF

Or as Swordfish commented, you can flip the bits of an unsigned integer literal:

ALL = ~0u

To answer your comment, you can explicitly tell the compiler what type you want your enum to have:

enum EventType : unsigned int

Upvotes: 3

Related Questions