Home > Enterprise >  Checking whether a scoped enum contains a value
Checking whether a scoped enum contains a value

Time:05-05

I haven't seen a clear answer to this question about enums. Lets say I have an enum:

enum class TileType
{
    WALL= 'W',
    PASSAGE= 'P',
    MONSTER = 'M',
    CRYSTAL= 'C',
};

and I want to typecast and make a new enum with a char Lets say the input char is undefined it the enum:

char id = 'A';

Now when I typecast it there is an undefined behaviour:

TileType type = static_cast<TileType>(id);

Thats why I want to check if the id is a valid value for an enum

//check if enum contains id
bool checkID(char id){...}

Now I have a couple ideas to do it but they seem like over kill to me. I also couldn't find a way to iterate over the enum class to make the check easy but I don't think that's possible.

Is there a way to easily check if the enum contains the id so that I can decide if I can typecast or not? Or am I supposed to do like a switch statement and check for every single case?

CodePudding user response:

Or am I supposed to do like a switch statement and check for every single case?

This is probably a decent solution. Like this:

switch(id) {
    case char(TileType::WALL):
    case char(TileType::PASSAGE):
    case char(TileType::MONSTER):
    case char(TileType::CRYSTAL):
        return true;
    default:
        return false;
}

Another alternative is to store all valid values in a data structure such as an array:

constexpr std::array valid {
    char(TileType::WALL),
    char(TileType::PASSAGE),
    char(TileType::MONSTER),
    char(TileType::CRYSTAL),
};

With such data structure, you can check validity like this:

return std::ranges::find(valid, id) != valid.end();

Compilers tend to be better at optimising the switch.


In either case, it may be useful to use meta-programming to generate the switch / the array.

CodePudding user response:

There is no standard way to do this. One way is to use a third-party library like magic_enum, which may still have limitations on the enum's range.

enum class TileType
{
    WALL= 'W',
    PASSAGE= 'P',
    MONSTER = 'M',
    CRYSTAL= 'C',
};

bool contains = magic_enum::enum_contains<TileType>('A');

Demo

  • Related