#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(const T1& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const T2& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const T3& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const T4& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const T5& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const T6& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const T7& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const T8& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const T9& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const T10& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const T11& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const T12& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const T13& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const T14& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const T15& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const T16& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const T17& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const T18& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const T19& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const 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(const T1& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const T2& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const T3& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const T4& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const T5& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const T6& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const T7& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const T8& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const T9& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const 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(const T1& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const T2& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const T3& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const T4& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const T5& msg) { this->Handle(static_cast(msg)); } }; // Deal with rest with 4 types template class GenericHandler > { public: virtual ~GenericHandler() {} virtual void Handle(const T1& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const T2& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const T3& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const T4& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const TCommon&) { } //Nothing to do }; // Deal with rest with 3 types template class GenericHandler > { public: virtual ~GenericHandler() {} virtual void Handle(const T1& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const T2& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const T3& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const TCommon&) { } //Nothing to do }; // Deal with rest with 2 types template class GenericHandler > { public: virtual ~GenericHandler() {} virtual void Handle(const T1& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const T2& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const TCommon&) { } //Nothing to do }; // Deal with rest with 1 type template class GenericHandler > { public: virtual ~GenericHandler() {} virtual void Handle(const T1& msg) { this->Handle(static_cast(msg)); } virtual void Handle(const TCommon&) { } //Nothing to do }; // Deal with rest with 0 type template class GenericHandler > { public: virtual ~GenericHandler() {} virtual void Handle(const TCommon&) { } //Nothing to do }; } // sp