template<typename fun, typename arg2, typename obj>
class callback
{
public:
callback(obj& _o, fun _f) : o(_o), f(_f)
{
}
public:
template<typename arg2>
void operator()(arg2 a2)
{
(o->*f)(a2);
}
private:
obj& o;
fun f;
};
class tfun
{
public:
tfun(){}
public:
void printf(int a)
{
cout << "a=" << a << endl;
}
};
template<class ret_type, class arg_type>
class function_base
{
public:
virtual ~function_base(){}
virtual ret_type operator()(arg_type arg) = 0;
};
template<class ret_type, class arg_type>
class function1 : public function_base<ret_type, arg_type>
{
public:
typedef ret_type (*NORM_PROC)(arg_type);
function1(NORM_PROC proc = 0) : fun_(proc)
{
}
ret_type operator()(arg_type arg)
{
fun_->operator()(arg);
}
private:
NORM_PROC fun_;
};
template<class CS, class ret_type, class arg_type>
class function2 : public function_base<ret_type, arg_type>
{
public:
typedef ret_type (CS::*MEM_PROC)(arg_type);
function2(CS* obj, MEM_PROC proc) : obj_(obj), proc_(proc){}
ret_type operator()(arg_type arg)
{
return (obj_->*proc_)(arg);
}
private:
CS* obj_;
MEM_PROC proc_;
};
template<class ret_type, class arg_type>
class function
{
public:
typedef function_base<ret_type, arg_type> function_base_type;
function(function_base_type *pf) : obj_(pf)
{
}
ret_type operator()(arg_type arg)
{
obj_->operator()(arg);
}
private:
function_base_type* obj_;
};
template <class CS, class ret_type, class arg_type>
function<ret_type, arg_type> bind(ret_type (CS::*proc)(arg_type), CS* pc)
{
return new function2<CS, ret_type, arg_type>(pc, proc);
}
typedef void(tfun::*fcb)(int);
int main()
{
tfun *f = new tfun;
callback<fcb, int, tfun*> test(f, &tfun::printf);
test(1);
function<void, int> ff = bind(&tfun::printf, f);
ff(1);
return 0;
}
template<typename R, typename A1, typename A2>
class base
{
public:
virtual ~base()
{
}
virtual R operator()(A1, A2) = 0;
};
template<typename R, typename A1, typename A2>
class func : public base<R, A1, A2>
{
public:
func(R(*ptr)(A1, A2))
: m_pFun(ptr)
{
}
virtual R operator()(A1 a1, A2 a2)
{
return m_pFun(a1, a2);
}
private:
R(*m_pFun)(A1, A2);
};
template<typename R, typename Class, typename A>
class member : public base<R, Class, A>
{
};
template<typename R, typename Class, typename A>
class member<R, Class*, A> : public base<R, Class*, A>
{
public:
member(R (Class::*ptr)(A))
: m_pFun(ptr)
{
}
virtual R operator()(Class *pObj, A a1)
{
return (pObj->*m_pFun)(a1);
}
private:
R (Class::*m_pFun)(A);
};
template<typename F, typename R, typename A1, typename A2>
class functor : public base<R, A1, A2>
{
public:
functor(const F& obj)
: m_fFunc(obj)
{
}
virtual R operator()(A1 a1, A2 a2)
{
return m_fFunc(a1, a2);
}
private:
F m_fFunc;
};
template<typename T>
class function
{
};
template<typename R, typename A1, typename A2>
class function<R(A1, A2)>
{
public:
template<typename Class, typename _R, typename A>
function(_R (Class::*ptr)(A))
: m_pBase(new member<R, A1, A2>(ptr))
{
}
template<typename _R, typename _T1, typename _T2>
function(_R(*ptr)(_T1, _T2))
: m_pBase(new func<R, A1, A2>(ptr))
{
}
template<typename T>
function(const T& obj)
: m_pBase(new functor<T, R, A1, A2>(obj))
{
}
~function()
{
if (m_pBase)
{
delete m_pBase;
m_pBase = NULL;
}
}
virtual R operator()(A1 a1, A2 a2)
{
return m_pBase->operator()(a1, a2);
}
private:
base<R, A1, A2> *m_pBase;
};