如何检查位枚举中是否存在值?

时间:2018-10-09 05:44:28

标签: c++ enums bit-manipulation

我有一个enum

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

现在,如何验证特定的int值属于上述enum?请注意,该想法还允许使用BIT_TWOBIT_THREEBIT_FOUR的任意组合,因此有效值为{0, 1, 2, 4, 6, 8, 10, 12, 14}

如果我勾选BIT_NONE <= val && val <= BIT_FOUR,则将不允许上述组合,但还会包含不需要的{3, 5, 7}

我该如何实现?

2 个答案:

答案 0 :(得分:2)

这需要一些操作技巧:

要将所有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);
}

答案 1 :(得分:0)

由于枚举很小,所以还有另一种方法:使用所有有效值的预定义掩码。 该掩码是1 << {0, 1, 2, 4, 6, 8, 10, 12, 14}的OR,所以0x5557

然后检查是否设置了与该值对应的位:

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

这有一个前提条件,即值不会超出设置范围,但是如果期望值存在,则可以通过比较轻松地检查它们。