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())
.