template<uint16_t address_> struct Register { void operator= (uint8_t _r) { *reinterpret_cast<volatile uint8_t*>(address_) = _r; } operator uint8_t () const { return *reinterpret_cast<volatile uint8_t*>(address_); } operator volatile uint8_t& () { return *reinterpret_cast<volatile uint8_t*>(address_); } template<uint8_t bit_> void setBit() { *reinterpret_cast<volatile uint8_t*>(address_) |= (1 << bit_); } template<uint8_t bit_> void clearBit() { *reinterpret_cast<volatile uint8_t*>(address_) &= ~(1 << bit_); } }; Register<0x24> DDRB; Register<0x25> PORTB; constexpr uint8_t DDB5 = 5; constexpr uint8_t PORTB5 = 5;
2017/03/28
C vs C++, Part II, Beautiful & efficient
In the first part of this series, we used C++ features (operator overloading and templates) to eliminate all defines and macros necessary for using a Pin. This way, we achieved the same performance of C code, but slightly increased readability, and hugely increased code safety. The result is a library that looks like this:
Subscribe to:
Posts (Atom)