Как проверить, существует ли значение в битовом перечислении? - PullRequest
0 голосов
/ 09 октября 2018

У меня есть enum:

enum Rule
{
    BIT_NONE,
    BIT_ONE,
    BIT_TWO = 1 << 1,
    BIT_THREE = 1 << 2,
    BIT_FOUR = 1 << 3
};

Теперь, как мне проверить, что конкретное значение int принадлежит вышеуказанному enum?Обратите внимание, что идея также состоит в том, чтобы разрешить любую комбинацию BIT_TWO, BIT_THREE и BIT_FOUR, поэтому допустимыми значениями являются {0, 1, 2, 4, 6, 8, 10, 12, 14}.

Если я проверю BIT_NONE <= val && val <= BIT_FOUR, это не будетразрешить комбинации, как упомянуто выше, но также будет включать нежелательные {3, 5, 7}.

Как я могу этого достичь?

Ответы [ 2 ]

0 голосов
/ 09 октября 2018

Поскольку перечисление невелико, существует другой способ: использование предварительно определенной маски всех допустимых значений.Эта маска является ИЛИ 1 << {0, 1, 2, 4, 6, 8, 10, 12, 14}, поэтому 0x5557.

Затем проверьте, установлен ли бит, соответствующий значению:

bool is_allowed(unsigned val) {
    return (0x5557 & (1 << val)) != 0;
}

Это имеет предварительное условие, что значенияне являются дикими за пределами набора, но их можно легко проверить с помощью сравнения, если ожидается, что они существуют.

0 голосов
/ 09 октября 2018

Для этого нужны некоторые хитрые операции:

Чтобы разрешить все enum как один бит, вам нужно быть уверенным, что оно меньше BIT_FOUR, и это всего один бит.Последний может быть обнаружен с помощью !((val-1)&val):

bool is_allowed_single(unsigned val) {
    return BIT_NONE <= val && val <= BIT_FOUR && !((val-1)&val);
}

Тогда также допустима комбинация определенных битов:

bool is_allowed_combination(unsigned val) {
    return !(val & ~(BIT_TWO|BIT_THREE|BIT_FOUR));
}

Наконец, мы получаем:

bool is_allowed(unsigned val) {
    return is_allowed_single(val) || is_allowed_combination(val);
}
...