#include #include // https://www.modernescpp.com/index.php/c-is-still-lazy // // CRTP base class of pin // /* avoiding virtual call (static polymorphism) */ struct IPin { void set(bool logic); void toggle(); bool get(); }; template struct PinBase : public IPin { void set(bool logic) { static_cast(this)->setImp(logic); } void toggle() { static_cast(this)->toggleImp(); } bool get(void) { return static_cast(this)->getImp(); } private: // // base implementations // void setImp() { std::cout << "base implementation of set()!" << std::endl; } void toggleImp() { std::cout << "base implementation of toggle()!" << std::endl; } bool getImp(void) { std::cout << "base implementation of get()!" << std::endl; return true; } }; // // implementations // struct STM32_Pin : PinBase { STM32_Pin() { //std::cout << "created STM32_Pin" << std::endl; } void setImp(bool logic) { //std::cout << "stm32 pin set to " << logic << std::endl; } void toggleImp() { //std::cout << "toggled stm32 pin" << std::endl; } bool getImp() { return true; } void STM32_stuff() { //std::cout << "STM_32 specific stuff" << std::endl; } }; struct AVR_Pin : PinBase { AVR_Pin() { a = 3; //std::cout << "created AVR_Pin" << std::endl; } void setImp(bool logic) { //std::cout << "AVR pin set to " << logic << std::endl; } void toggleImp() { a = 5; //std::cout << "toggled AVR pin" << std::endl; } bool getImp() { return true; } void avr_stuff() { a = 10; //std::cout << "AVR specific stuff" << std::endl; } private: int a; }; template void foo(T& base) { base.set(true); base.set(false); base.toggle(); } template void baa(PinBase& pin) { pin.toggle(); //foo(pin); } #if 0 template struct Driver { Driver(PinBase& pin) : pin(pin) { } void doSomething() { pin.toggle(); } private: PinBase pin; }; #endif struct Driver { Driver(IPin& pin) : pin(pin) { } void doSomething() { pin.toggle(); } private: IPin& pin; }; int main(void) { //STM32_Pin pin1; AVR_Pin pin2; //pin1.STM32_stuff(); pin2.avr_stuff(); #if 0 foo(pin1); foo(pin2); baa(pin1); #endif Driver drv(pin2); drv.doSomething(); return 0; }