Listing 7
template <typename type_vector, typename n>
struct at_v
: mpl::apply_if<
mpl::greater<mpl::size<type_vector>, n>,
mpl::at<type_vector, n>,
mpl::identity<mpl::void_>
>
{};
class async_result
{
template<typename ret, typename params>
friend class delegate;
public:
bool is_completed() { return _call->is_completed(); }
void wait() { _call->wait_completion(); }
private:
async_result(shared_ptr<simple_call> call) : _call(call) {}
shared_ptr<simple_call> get_call() const
{ return _call; }
shared_ptr<simple_call> _call;
};
// bad_async_result - plain std::exception
template<typename ret, typename params>
class delegate
{
public:
typedef ret dret;
typedef params dparams;
typedef typename at_v<params, mpl::size_t<0> >::type p1;
// repeat for parameters 2 and higher
typedef async_callback<ret>* ac_ptr;
template<typename ptr_obj, typename mem_fun>
delegate(ptr_obj o, mem_fun m)
{
_impl_factory = shared_ptr<impl>(
new delegate_impl<delegate, ptr_obj, mem_fun>
(o, m));
}
async_result begin_invoke(ac_ptr ac = 0)
{
impl* i = new_impl(ac);
(*i)(ac);
return queue_it(i);
}
async_result begin_invoke(p1 par1, ac_ptr ac = 0)
{
impl* i = new_impl(ac);
(*i)(par1, ac);
return queue_it(i);
}
// repeat begin_invoke for 2 and more parameters
ret end_invoke(const async_result& ar)
{
shared_ptr<simple_call> sc = ar.get_call();
calls::iterator it = std::find(_calls.begin(),
_calls.end(), sc);
if(it == _calls.end())
throw bad_async_result();
sc->wait_completion();
impl* i = static_cast<impl*>(sc.get());
return i->result();
}
private:
typedef callable<ret, params> impl;
impl* new_impl(ac_ptr ac = 0)
{
impl* imp = simple_call::clone(_impl_factory.get());
imp->deliver_to(ac);
return imp;
}
shared_ptr<simple_call> queue_it(impl* i)
{
shared_ptr<simple_call> sc(i);
work_queue::instance().queue_item(sc);
_calls.push_back(sc);
return sc;
}
shared_ptr<impl> _impl_factory;
typedef std::list<shared_ptr<simple_call> > calls;
calls _calls;
};