#pragma once #include #include #include #include // https://stackoverflow.com/a/263738 /* a=target variable, b=bit number to act upon 0-n */ #define BIT_SET(a,b) ((a) |= (1ULL<<(b))) #define BIT_CLEAR(a,b) ((a) &= ~(1ULL<<(b))) #define BIT_FLIP(a,b) ((a) ^= (1ULL<<(b))) #define BIT_CHECK(a,b) (!!((a) & (1ULL<<(b)))) // '!!' to make sure this returns 0 or 1 /* x=target variable, y=mask */ #define BITMASK_SET(x,y) ((x) |= (y)) #define BITMASK_CLEAR(x,y) ((x) &= (~(y))) #define BITMASK_FLIP(x,y) ((x) ^= (y)) #define BITMASK_CHECK_ALL(x,y) (!(~(x) & (y))) #define BITMASK_CHECK_ANY(x,y) ((x) & (y)) namespace itsy_bitsy { template struct bit_type { typedef uint64_t type; }; template struct bit_type> { typedef bool type; }; template struct bit_type 2 && sz <= 16)>> { typedef uint16_t type; }; template struct bit_type 16 && sz <= 32)>> { typedef uint32_t type; }; template struct bit_type 32 && sz <= 64)>> { typedef uint64_t type; }; template using bit_type_t = typename bit_type::type; template bool vcxx_warning_crap(std::true_type, V val) { return val != 0; } template T vcxx_warning_crap(std::false_type, V val) { return static_cast(val); } template auto vcxx_warning_crap(V val) { return vcxx_warning_crap(std::is_same(), val); } template void write(Base& b, bit_type_t bits) { uintptr_t baseAddr = reinterpret_cast(&b); uintptr_t offs = baseOffset; unsigned char* byt = reinterpret_cast(baseAddr + offs); char testb = *byt & (1 << bit_target); if (bits) BIT_SET(*byt, bit_target); else BIT_CLEAR(*byt, bit_target); } template bit_type_t read(Base& b) { uintptr_t baseAddr = reinterpret_cast(&b); uintptr_t offs = baseOffset; unsigned char* byt = reinterpret_cast(baseAddr + offs); char test = *byt & (1 << bit_target); if (test) return true; return false; } }