|
Portable concurrency
0.11.0
|
If some function returning type R is going to be executed asyncronyously (via async, packaged_task or as continuation for some future or shared_future object) then future<R> object is created in order to provide access to the result of the function invocation. If function itself returns object of type future<R> or shared_future<R> then running it asyncronyously in a naive implementation will create future to future to result. Such future<future<R>> type is quite inconvenient to use and actually forbidden by the portable_concurrency future and shared_future implementation (same is true for any combination of future templates future<shared_future<R>>, shared_future<future<R>> and shared_future<shared_future<R>>). future<R> is always created instead of future<future<R>> and shared_future<R> instead of future<shared_future<R>> by applying rules specified in "The C++ Extensions for Concurrency" TS as implicit unwrapping.
The future unwrapping works as if there are two function template overloads:
template<typename R> future<R> UNWRAP(future<future<R>>&& rhs) template<typename R> shared_future<R> UNWRAP(future<shared_future<R>>&& rhs)which constructs future/shahred_future object from the shared state referred to by rhs. The object becomes ready when one of the following occurs:
rhs and rhs.get() are ready. The value or the exception from rhs.get() is stored in the returned object shared state. rhs is ready but rhs.get() is invalid. The returned object stores an exception of type std::future_error, with an error condition of std::future_errc::broken_promise.promise<future<T>> and promise<shared_future<T>>. promise::get member function works as UNWRAP(promise_to_future.NAIVE_GET()).
1.8.17