// Example program #include #include #include /** * @brief Template class for portable Bitfields * * @tparam T type of variable in which the bitfield resides * @tparam START bit index starting from LSB where the bitfield starts * @tparam SIZE number of bits */ template struct BitField { /** * @brief Construct a new Bit Field object * */ BitField() { static_assert(SIZE != 0, "Bitfield SIZE must be > 0!"); static_assert(START < sizeof(T) * 8, "START exceeds number of bits of the chosen typename T!"); } /** * @brief assignment operator * * @param v value to be written in the bitfield * @return BitField& */ BitField& operator =(T v) { #if 0 _raw = ((v & ((1ULL << SIZE)-1)) << START); return *this; #else //_raw & ~(((1ULL << SIZE)-1) << START); // use bit band alias if system permits _raw = ((v & ((1ULL << SIZE)-1)) << START) | (_raw & ~(((1ULL << SIZE)-1) << START)); return *this; //#endif #endif } /** * @brief return the value inside the bitfield * * @return T */ operator T() const { return _raw >> START; } /** * @brief return the raw value * * @return T */ T operator ()() const { return _raw; } private: T _raw; }; union Reg_Control { // bit 4 struct POWER_DEV{ typedef BitField Bits; enum{TURN_OFF = 0, TURN_ON = 1}; }; // bits 2-3 struct SPEED{ typedef BitField Bits; enum{STAND_STILL = 0, SLOW = 1, NORMAL = 2, FAST = 3}; }; union Bits{ Reg_Control::POWER_DEV::Bits POWER_DEV; Reg_Control::SPEED::Bits SPEED; } bits; // raw value. all bitfields will be "unified" here ;) uint8_t raw; // union Ctor with default value set to 0x00 Reg_Control(uint8_t v = 0x00) : raw(v) {} }; int main() { Reg_Control reg; //reg.bits.SPEED = Reg_Control::SPEED::FAST; reg.bits.POWER_DEV = Reg_Control::POWER_DEV::TURN_ON; std::cout << +reg.raw << std::endl; reg.bits.POWER_DEV = Reg_Control::POWER_DEV::TURN_OFF; std::cout << +reg.raw << std::endl; reg.bits.POWER_DEV = Reg_Control::POWER_DEV::TURN_ON; reg.bits.SPEED = Reg_Control::SPEED::SLOW; std::cout << +reg.raw << std::endl; reg.bits.POWER_DEV = Reg_Control::POWER_DEV::TURN_OFF; reg.bits.SPEED = Reg_Control::SPEED::FAST; std::cout << +reg.raw << std::endl; return 0; }