
On Mar 12, 2007, at 9:30 AM, Christopher Kohlhoff wrote:
Hi Braddock,
On Fri, 09 Mar 2007 09:05:42 -0500, "Braddock Gaskill" <braddock@braddock.com> said:
The ability to use a future with the asio::io_service in particular would be quite powerful.
I've attached a quick and dirty futures implementation that I wrote last year to demonstrate how futures and asio might fit together. Unlike the various futures proposals that are around, I prefer to keep the producer and consumer interfaces separate. Hence I have promise<T> (producer interface) and future<T> (consumer interface) -- these names are borrowed from the Alice programming language.
I've been looking at this: ... future<std::string> resolve(std::string host_name) { promise<std::string> result; boost::asio::ip::tcp::resolver::query query(host_name, "0"); resolver_.async_resolve(query, boost::bind(&Resolver::handle_resolve, this, _1, _2, result)); return result; } private: void handle_resolve(boost::system::error_code ec, boost::asio::ip::tcp::resolver::iterator iterator, promise<std::string> result) { if (ec) result.fail(boost::system::system_error(ec)); else result(iterator->endpoint().address().to_string()); } And am somewhat disappointed that the low-level worker function needs to be aware of promise. What if there existed a: template <class R> template <class F> promise_functor<R, F> promise<R>::operator()(F f); This would be in addition to the current setter functionality in promise. You could call this on a promise: result(f) and a promise_functor<R, F> would be returned as the result (I'm not at all very attached to the name promise_functor). Executing that functor would be roughly equivalent to setting the promise: future<std::string> resolve(std::string host_name) { promise<std::string> result; boost::asio::ip::tcp::resolver::query query(host_name, "0"); resolver_.async_resolve(query, result(boost::bind(&Resolver::handle_resolve, this, _1, _2))); return result; } private: std::string handle_resolve(boost::system::error_code ec, boost::asio::ip::tcp::resolver::iterator iterator) { if (ec) throw boost::system::system_error(ec); return iterator->endpoint().address().to_string(); } The promise_functor adaptor would execute f under a try/catch, setting the promise's value on successful termination, else catching the exception and setting the promise's failure mode. Variadic templates and perfect forwarding would make the implementation nearly painless (today it would be a pain). Having a ready-to-run functor that can be produced from a promise might ease setting the promise's value with code that is (by design or by accident) promise-ignorant. Just a thought, and not a fully fleshed out one. -Howard