#pragma once #include namespace sp { // This class is inspired by https://arobenko.gitbooks.io/comms-protocols-cpp/content/ // TAll is all the message types, that need to be handled, bundled in std::tuple template class MessageHandler; // Big boy to process packets 20 by 20, preventing needlessly copying vtable many times at each inheritance stage template class MessageHandler > : public MessageHandler > { using Base = MessageHandler >; public: using Base::Handle; // Don't hide all Handle() functions from base classes virtual void Handle(const typename T1::DataType& msg) {} virtual void Handle(const typename T2::DataType& msg) {} virtual void Handle(const typename T3::DataType& msg) {} virtual void Handle(const typename T4::DataType& msg) {} virtual void Handle(const typename T5::DataType& msg) {} virtual void Handle(const typename T6::DataType& msg) {} virtual void Handle(const typename T7::DataType& msg) {} virtual void Handle(const typename T8::DataType& msg) {} virtual void Handle(const typename T9::DataType& msg) {} virtual void Handle(const typename T10::DataType& msg) {} virtual void Handle(const typename T11::DataType& msg) {} virtual void Handle(const typename T12::DataType& msg) {} virtual void Handle(const typename T13::DataType& msg) {} virtual void Handle(const typename T14::DataType& msg) {} virtual void Handle(const typename T15::DataType& msg) {} virtual void Handle(const typename T16::DataType& msg) {} virtual void Handle(const typename T17::DataType& msg) {} virtual void Handle(const typename T18::DataType& msg) {} virtual void Handle(const typename T19::DataType& msg) {} virtual void Handle(const typename T20::DataType& msg) {} }; // 10 by 10 template class MessageHandler > : public MessageHandler > { using Base = MessageHandler >; public: using Base::Handle; // Don't hide all Handle() functions from base classes virtual void Handle(const typename T1::DataType& msg) {} virtual void Handle(const typename T2::DataType& msg) {} virtual void Handle(const typename T3::DataType& msg) {} virtual void Handle(const typename T4::DataType& msg) {} virtual void Handle(const typename T5::DataType& msg) {} virtual void Handle(const typename T6::DataType& msg) {} virtual void Handle(const typename T7::DataType& msg) {} virtual void Handle(const typename T8::DataType& msg) {} virtual void Handle(const typename T9::DataType& msg) {} virtual void Handle(const typename T10::DataType& msg) {} }; // 5 by 5 template < typename T1, typename T2, typename T3, typename T4, typename T5, typename... TRest> class MessageHandler > : public MessageHandler > { using Base = MessageHandler >; public: using Base::Handle; // Don't hide all Handle() functions from base classes virtual void Handle(const typename T1::DataType& msg) {} virtual void Handle(const typename T2::DataType& msg) {} virtual void Handle(const typename T3::DataType& msg) {} virtual void Handle(const typename T4::DataType& msg) {} virtual void Handle(const typename T5::DataType& msg) {} }; // Deal with rest with 4 types template class MessageHandler > { public: virtual ~MessageHandler() {} virtual void Handle(const typename T1::DataType& msg) {} virtual void Handle(const typename T2::DataType& msg) {} virtual void Handle(const typename T3::DataType& msg) {} virtual void Handle(const typename T4::DataType& msg) {} }; // Deal with rest with 3 types template < typename T1, typename T2, typename T3> class MessageHandler > { public: virtual ~MessageHandler() {} virtual void Handle(const typename T1::DataType& msg) {} virtual void Handle(const typename T2::DataType& msg) {} virtual void Handle(const typename T3::DataType& msg) {} }; // Deal with rest with 2 types template class MessageHandler > { public: virtual ~MessageHandler() {} virtual void Handle(const typename T1::DataType& msg) {} virtual void Handle(const typename T2::DataType& msg) {} }; // Deal with rest with 1 type template class MessageHandler > { public: virtual ~MessageHandler() {} virtual void Handle(const typename T1::DataType& msg) {} }; // Deal with rest with 0 type template <> class MessageHandler > { public: virtual ~MessageHandler() {} }; } // sp