#ifndef DUMMYCLASS_H
#define DUMMYCLASS_H
namespace delegate
{
class DummyClass{};
}
#endif
#ifndef METHODSTORAGE_H
#define METHODSTORAGE_H
#include "DummyClass.h"
namespace delegate
{
class MethodStorage
{
public:
typedef DummyClass GenericClass;
typedef void (GenericClass::*GenericMemberFunctionPtr)();
typedef void (*GenericFunctionPtr)();
MethodStorage()
:m_obj(0),
m_member_fnptr(0),
m_fnptr(0)
{
}
inline bool operator == (MethodStorage const& other) const{return this->equals(other);}
inline bool operator != (MethodStorage const& other) const{return !this->equals(other);}
inline bool equals(MethodStorage const& other) const
{
return m_obj == other.m_obj
&& m_member_fnptr == other.m_member_fnptr
&& m_fnptr == other.m_fnptr;
}
//protected:
GenericClass *m_obj;
GenericMemberFunctionPtr m_member_fnptr;
GenericFunctionPtr m_fnptr;
};
};
#endif
#ifndef METHODWRAPPER_H
#define METHODWRAPPER_H
#include "MethodStorage.h"
namespace delegate
{
///This "Signature" is not a complete function pointer
///corresponding signature to void (*)(int) is void(int)
///and void (SomeClassType::*)(int) is void(int) as well
template<typename Signature>
class MethodWrapper;
template<>
class MethodWrapper< void () >
{
public:
template<typename ClassType,typename MemberFunctionClass>
MethodWrapper(ClassType const& obj,void (MemberFunctionClass::*ptr)(void) const)
{
m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj);
m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)() >;
}
template<typename ClassType,typename MemberFunctionClass>
MethodWrapper(ClassType & obj,void (MemberFunctionClass::*ptr)(void)const )
{
m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj);
m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)() >;
}
template<typename ClassType,typename MemberFunctionClass>
MethodWrapper(ClassType & obj,void (MemberFunctionClass::*ptr)(void))
{
m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj);
m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)() >;
}
MethodWrapper(void (*ptr)(void))
{
m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(this);
m_method.m_fnptr = reinterpret_cast<MethodStorage::GenericFunctionPtr>(ptr);
internal_call = &MethodWrapper::executeFunction< MethodWrapper , void (*)() >;
}
void operator()()
{
(this->*internal_call)(m_method.m_obj);
}
private:
typedef void (MethodWrapper::*internal_call_type)(void*);
MethodStorage m_method;
internal_call_type internal_call;
template<typename ClassType,typename FunctionPtrType>
void executeMemberFunction(void* obj)
{
(reinterpret_cast<ClassType*>(obj)->*reinterpret_cast<FunctionPtrType>(m_method.m_member_fnptr))();
}
template<typename ClassType,typename FunctionPtrType>
void executeFunction(void* obj)
{
(*reinterpret_cast<FunctionPtrType>(m_method.m_fnptr))();
}
};
template<typename ReturnType>
class MethodWrapper< ReturnType () >
{
public:
template<typename ClassType,typename MemberFunctionClass>
MethodWrapper(ClassType const& obj,ReturnType (MemberFunctionClass::*ptr)(void) const)
{
m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj);
m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
internal_call = &MethodWrapper::executeMemberFunction< ClassType , ReturnType (MemberFunctionClass::*)() >;
}
template<typename ClassType,typename MemberFunctionClass>
MethodWrapper(ClassType & obj,ReturnType (MemberFunctionClass::*ptr)(void)const )
{
m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj);
m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
internal_call = &MethodWrapper::executeMemberFunction< ClassType , ReturnType (MemberFunctionClass::*)() >;
}
template<typename ClassType,typename MemberFunctionClass>
MethodWrapper(ClassType & obj,ReturnType (MemberFunctionClass::*ptr)(void))
{
m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj);
m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
internal_call = &MethodWrapper::executeMemberFunction< ClassType , ReturnType (MemberFunctionClass::*)() >;
}
MethodWrapper(ReturnType (*ptr)(void))
{
m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(this);
m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
internal_call = &MethodWrapper::executeFunction< MethodWrapper , ReturnType (*)() >;
}
ReturnType operator()()
{
return (this->*internal_call)(m_method.m_obj);
}
private:
typedef void (MethodWrapper::*internal_call_type)(void);
MethodStorage m_method;
internal_call_type internal_call;
template<typename ClassType,typename FunctionPtrType>
ReturnType executeMemberFunction(void* obj)
{
return (reinterpret_cast<ClassType*>(obj)->*reinterpret_cast<FunctionPtrType>(m_method.m_member_fnptr))();
}
template<typename ClassType,typename FunctionPtrType>
ReturnType executeFunction(void* obj)
{
return (*reinterpret_cast<FunctionPtrType>(m_method.m_fnptr))();
}
};
template<typename ArgType0>
class MethodWrapper< void ( ArgType0 ) >
{
public:
template<typename ClassType,typename MemberFunctionClass>
MethodWrapper(ClassType const& obj,void (MemberFunctionClass::*ptr)(ArgType0) const)
{
m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(const_cast<ClassType*>(&obj));
m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)(ArgType0) >;
}
template<typename ClassType,typename MemberFunctionClass>
MethodWrapper(ClassType & obj,void (MemberFunctionClass::*ptr)(ArgType0)const )
{
m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj);
m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)(ArgType0) >;
}
template<typename ClassType,typename MemberFunctionClass>
MethodWrapper(ClassType const& obj,void (MemberFunctionClass::*ptr)(ArgType0))
{
m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(const_cast<ClassType*>(&obj));
m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)(ArgType0) >;
}
template<typename ClassType,typename MemberFunctionClass>
MethodWrapper(ClassType & obj,void (MemberFunctionClass::*ptr)(ArgType0))
{
m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj);
m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)(ArgType0) >;
}
MethodWrapper(void (*ptr)(ArgType0))
{
m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(this);
m_method.m_fnptr = reinterpret_cast<MethodStorage::GenericFunctionPtr>(ptr);
internal_call = &MethodWrapper::executeFunction< MethodWrapper , void (*)(ArgType0) >;
}
void operator()(ArgType0 arg0)
{
(this->*internal_call)(m_method.m_obj, arg0);
}
private:
typedef void (MethodWrapper::*internal_call_type)(void*,ArgType0);
MethodStorage m_method;
internal_call_type internal_call;
template<typename ClassType,typename FunctionPtrType>
void executeMemberFunction(void* obj,ArgType0 arg0)
{
(reinterpret_cast<ClassType*>(obj)->*reinterpret_cast<FunctionPtrType>(m_method.m_member_fnptr))(arg0);
}
template<typename ClassType,typename FunctionPtrType>
void executeFunction(void* obj,ArgType0 arg0)
{
(*reinterpret_cast<FunctionPtrType>(m_method.m_fnptr))(arg0);
}
};
template<typename ReturnType,typename ArgType0>
class MethodWrapper< ReturnType ( ArgType0 ) >
{
public:
template<typename ClassType,typename MemberFunctionClass>
MethodWrapper(ClassType const& obj,ReturnType (MemberFunctionClass::*ptr)(ArgType0) const)
{
m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj);
m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)(ArgType0) >;
}
template<typename ClassType,typename MemberFunctionClass>
MethodWrapper(ClassType & obj,ReturnType (MemberFunctionClass::*ptr)(ArgType0)const )
{
m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj);
m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)(ArgType0) >;
}
template<typename ClassType,typename MemberFunctionClass>
MethodWrapper(ClassType & obj,ReturnType (MemberFunctionClass::*ptr)(ArgType0))
{
m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(&obj);
m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
internal_call = &MethodWrapper::executeMemberFunction< ClassType , void (MemberFunctionClass::*)(ArgType0) >;
}
MethodWrapper(ReturnType (*ptr)(ArgType0))
{
m_method.m_obj = reinterpret_cast<MethodStorage::GenericClass*>(this);
m_method.m_member_fnptr = reinterpret_cast<MethodStorage::GenericMemberFunctionPtr>(ptr);
internal_call = &MethodWrapper::executeFunction< MethodWrapper , void (*)(ArgType0) >;
}
ReturnType operator()(ArgType0 arg0)
{
return (this->*internal_call)(m_method.m_obj,arg0);
}
private:
typedef ReturnType (MethodWrapper::*internal_call_type)(void*,ArgType0);
MethodStorage m_method;
internal_call_type internal_call;
template<typename ClassType,typename FunctionPtrType>
ReturnType executeMemberFunction(void* obj,ArgType0 arg0)
{
return (reinterpret_cast<ClassType*>(obj)->*reinterpret_cast<FunctionPtrType>(m_method.m_member_fnptr))(arg0);
}
template<typename ClassType,typename FunctionPtrType>
ReturnType executeFunction(void* obj,ArgType0 arg0)
{
return (*reinterpret_cast<FunctionPtrType>(m_method.m_fnptr))(arg0);
}
};
}
#endif
compiler:MinGW 4.5.2 / VC++2010
C#式的delegate的重点之一是省略掉类型信息.
http://www.codeproject.com/KB/cpp/ImpossiblyFastCppDelegate.aspx 写道
class delegate
{
public:
delegate()
: object_ptr(0)
, stub_ptr(0)
{}
template <class T, void (T::*TMethod)(int)>
static delegate from_method(T* object_ptr)
{
delegate d;
d.object_ptr = object_ptr;
d.stub_ptr = &method_stub<T, TMethod>; // #1
return d;
}
void operator()(int a1) const
{
return (*stub_ptr)(object_ptr, a1);
}
private:
typedef void (*stub_type)(void* object_ptr, int);
void* object_ptr;
stub_type stub_ptr;
template <class T, void (T::*TMethod)(int)>
static void method_stub(void* object_ptr, int a1)
{
T* p = static_cast<T*>(object_ptr);
return (p->*TMethod)(a1); // #2
}
};
非常巧妙地隐藏掉了类型信息。但是本人对虚继承的委托还没有好的解决方法,也理解不了虚继承的成员函数的hack:http://www.codeproject.com/KB/cpp/FastDelegate.aspx