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