Boost logo

Boost :

From: Howard Hinnant (hinnant_at_[hidden])
Date: 2007-03-14 15:50:34


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_at_[hidden]> 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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk