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; };