+ /** Attach a continuation to this future
+ *
+ * This is like .then() but avoid the creation of a new future.
+ */
+ template<class F>
+ void then_(F continuation)
+ {
+ if (state_ == nullptr)
+ throw std::future_error(std::future_errc::no_state);
+ // Give shared-ownership to the continuation:
+ auto state = std::move(state_);
+ state->set_continuation(simgrid::xbt::make_task(std::move(continuation), state));
+ }
+
+ /** Attach a continuation to this future
+ *
+ * This version never does future unwrapping.
+ */
+ template <class F> auto then_no_unwrap(F continuation) -> Future<decltype(continuation(std::move(*this)))>
+ {
+ typedef decltype(continuation(std::move(*this))) R;
+ if (state_ == nullptr)
+ throw std::future_error(std::future_errc::no_state);
+ auto state = std::move(state_);
+ // Create a new future...
+ Promise<R> promise;
+ Future<R> future = promise.get_future();
+ // ...and when the current future is ready...
+ state->set_continuation(simgrid::xbt::make_task(
+ [](Promise<R> promise, std::shared_ptr<FutureState<T>> state, F continuation) {
+ // ...set the new future value by running the continuation.
+ Future<T> future(std::move(state));
+ simgrid::xbt::fulfill_promise(promise, [&continuation, &future] { return continuation(std::move(future)); });
+ },
+ std::move(promise), state, std::move(continuation)));
+ return future;
+ }
+