// 文件名称: entrust.h
// 文件描述: 定义C++委托类型,使C++可以支持委托.
// 文件作者: kenny
// 创建时间: 2006-8-8 16:36
// 修改记录:
// * 2006-10-12 11:46 修改不恰当的注释
// * 2006-10-12 11:49 去除对委托调用的异常捕获, 使用户可以自定义.
// * 2008-3-31 10:46:20 修改名字空间命名,为empty添加const及添加clear方法
#if !defined(__ENTRUST_H_2006_8_8_KENNY__)
#define __ENTRUST_H_2006_8_8_KENNY__
//#if !defined(_MSC_VER)
#if defined(__BORLANDC__)
#pragma warn -8027
#endif
namespace nsKLIB
{
#if defined(__WINVER__)
#define CALL_ENTRUST __stdcall
#else
#define CALL_ENTRUST
#endif
template<typename _type_in, typename _type_out = void*, typename _type_result = bool>
class tentrust
{
public:
//输入参数类型:
typedef _type_in tin;
//输出参数类型:
typedef _type_out tout;
//返回值类型:
typedef _type_result tresult;
//实例化原形:
typedef tentrust<tin, tout, tresult> tentrust_type, *tpentrust_type;
//全局委托入口:
typedef tresult (CALL_ENTRUST *tfunc_g)(tin, tout);
//成员委托入口:
typedef tresult (CALL_ENTRUST tentrust_type::*tfunc_m)(tin, tout);
typedef union _func_type { tfunc_g g; tfunc_m m; } tfunc;
public:
tentrust() { ::memset(this, 0, sizeof(tentrust_type)); }
tentrust(tfunc_g f) : __object(0) { __func.g = f; }
template<typename _type_object>
tentrust(_type_object* o, tresult (CALL_ENTRUST _type_object::*f)(tin, tout)) { plug(o, f); }
~tentrust() {}
template<typename _type_object>
tentrust_type& plug(_type_object* o, tresult (CALL_ENTRUST _type_object::*f)(tin, tout)) {
union { _type_object* in; tpentrust_type out; } oc;
union { tresult (CALL_ENTRUST _type_object::*in)(tin, tout); tfunc_m out; } fc;
oc.in = o;
fc.in = f;
__object = oc.out;
__func.m = fc.out;
return *this;
}
tentrust_type& plug(tfunc_g f) { return __func.g = f, *this; }
tresult operator()(tin in, tout out = tout()) {
if( !__func.g ) return tresult();
else if( __object ) return (__object->*__func.m)(in, out);
else return (*__func.g)(in, out);
}
template<typename _object, typename _func>
tentrust_type& plug_cast(_object o, _func f) {
union { _object in; tpentrust_type out; } oc;
union { _func in; tfunc_m out; } fc;
oc.in = o;
fc.in = f;
__object = oc.out;
__func.m = fc.out;
return *this;
}
tentrust_type& operator=(const tentrust_type& e) {
if( &e == this ) return *this;
__object = e.object();
__func = e.func();
return *this;
}
tpentrust_type object() const { return __object; }
tfunc func() const { return __func; }
bool empty() const { return __func.g == 0; }
void clear() { __object = 0, __func.g = 0; }
private:
tpentrust_type __object;
tfunc __func;
};
} //namespace nsKLIB
#if defined(__BORLANDC__)
#pragma warn .8027
#endif
#endif //__ENTRUST_H_2006_8_8_KENNY__