Given a value, I want to check if some of its bits are set and some of them unset at the same time, while I don't care about the value of others.
I can do this with two bit masks, one for set bits one for unset bits like so:
#include <iostream> bool checkMask(uint8_t value, uint8_t setmask, uint8_t unsetmask) { return (value & setmask) == setmask && (~value & ~unsetmask) == ~unsetmask; } int main() { uint8_t setmask = 0b0100'0001; uint8_t unsetmask = 0b1111'1011; uint8_t valueMatches = 0b01101'1011; uint8_t valueFails1 = 0b00101'1010; uint8_t valueFails2 = 0b01101'1111; std::cout << "matches " << checkMask(valueMatches, setmask, unsetmask) << std::endl; std::cout << "fails1 " << checkMask(valueFails1, setmask, unsetmask) << std::endl; std::cout << "fails2 " << checkMask(valueFails2, setmask, unsetmask) << std::endl; } (May be buggy, it's an example)
Of course, this can also be done with a string, where I can represent more than 0 and 1 with a wildcard value like:
string bitmask = ".1...001"; and then check bit by bit from the string, ignoring '.' and checking 0s and 1s match.
In my solutions there's a tradeoff, either using 2 values, which makes it less intuitive (specially the unset mask), or ussing a string which is more inefficient, but really clear.
Are there other options?
string bitmaskintoclass TwoMasksin compile-time, letting the user represent mask as a string and compiler speed up runtime with two masks. You could also write a custom constructor with 8 arguments, one argument for one bit (ex. -1 represents any bit), to create such "two masks". Or a constructor with a list of pairs, representing bit position and value.You could also write a custom literal. As such, I believe the questionIs there a better way?is opinion based - "better" based on?checkMaskcan be more simply expressed as(value & unsetmask) == (value | setmask).