Listing 6
template<typename delegate, typename ptr_obj, typename mem_fun>
class delegate_impl : public callable<typename delegate::dret,
typename delegate::dparams>
{
public:
typedef delegate_impl<delegate, ptr_obj, mem_fun> self_type;
typedef typename delegate::dret ret;
typedef typename delegate::dparams params;
typedef typename delegate::p1 p1;
// repeat for parameters 2 and higher...
delegate_impl(ptr_obj o, mem_fun mf)
: _done(false), _fwd(0),
_ptr_obj(o), _mem_fun(mf) {}
void operator()()
{ _fwd = bind(_mem_fun, _ptr_obj); }
void operator()(p1 par1)
{ _fwd = bind(_mem_fun, _ptr_obj, par1); }
// repeat operator() for 2 and more parameters...
virtual ~delegate_impl() {}
bool invoke()
{
_result = _fwd();
mutex::scoped_lock lk(_mx);
_done = true;
_completed.notify_all();
if(0 != _ac)
_ac->accept_result(_result);
return true;
}
bool is_completed() const { return _done; }
void wait_completion()
{
mutex::scoped_lock lk(_mx);
if(_done)
return;
_completed.wait(lk);
}
virtual self_type* make_clone() const
{ return new self_type(_ptr_obj, _mem_fun); }
ret result() const { return _result; }
private:
bool _done;
function0<ret> _fwd;
ret _result;
mutex _mx;
condition _completed;
ptr_obj _ptr_obj;
mem_fun _mem_fun;
};