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