#pragma once #include #include "MacroExt.hh" namespace logging { struct NULL_SPACE {}; struct IArguments { virtual ~IArguments() {} }; template class Arguments : public IArguments { public: Arguments(T1 _arg1) : arg1(_arg1) {} public: T1 arg1; }; class IContainer { public: virtual void call( IArguments * ) = 0; virtual ~IContainer() {} }; template< class T, class M > class Container : public IContainer {}; template< class T, class A1 > class Container< T, void (T::*)(A1) > : public IContainer { typedef void (T::* M)(A1); typedef Arguments A; public: Container(T* c, M m) : m_class(c), m_method(m) {} private: T * m_class; M m_method; public: void call( IArguments * _args ) { A * a = dynamic_cast(_args); if( a ) (m_class->*m_method)( a->arg1 ); } }; class Delegate { public: Delegate() : container(nullptr) {} ~Delegate() { if( ext_memory and container ) ext_memory->deallocate( container, sizeof(*container) ); else if ( container ) delete container; } template< class T, class U > Delegate( T * _class, U _method ) { container = new Container< T, U >(_class, _method); } template< class T, class U > Delegate( T * _class, U _method, std::pmr::memory_resource* _memory) : ext_memory(_memory) { typedef Container ContainerType; container = std::pmr::polymorphic_allocator(ext_memory).allocate( 1 ); new( container ) ContainerType(_class, _method); } template< class T1 > void operator()( T1 _arg1 ) { Arguments< T1 > temp(_arg1); container->call( &temp ); } private: std::pmr::memory_resource * ext_memory; IContainer * container; }; }