typename boost::enable_if< traits::is_future<typename util::result_of<Func(Future)>::type> >::type invoke_continuation(Func& func, Future& future, Continuation& cont) { try { typedef typename util::result_of<Func(Future)>::type inner_future; typedef typename shared_state_ptr_for<inner_future>::type inner_shared_state_ptr; // take by value, as the future may go away immediately inner_shared_state_ptr inner_state = future_access::get_shared_state(func(std::move(future))); if (inner_state.get() == 0) { HPX_THROW_EXCEPTION(no_state, "invoke_continuation", "the inner future has no valid shared state"); } // Bind an on_completed handler to this future which will transfer // its result to the new future. boost::intrusive_ptr<Continuation> cont_(&cont); inner_state->set_on_completed(util::bind( transfer_result<inner_future>(), inner_state, cont_)); } catch (...) { cont.set_exception(boost::current_exception()); } }
typename std::enable_if< traits::detail::is_unique_future< typename util::invoke_result<Func, Future>::type >::value >::type invoke_continuation(Func& func, Future && future, Continuation& cont) { try { typedef typename util::invoke_result<Func, Future>::type inner_future; typedef typename traits::detail::shared_state_ptr_for<inner_future>::type inner_shared_state_ptr; // take by value, as the future may go away immediately inner_shared_state_ptr inner_state = traits::detail::get_shared_state(func(std::forward<Future>(future))); typename inner_shared_state_ptr::element_type* ptr = inner_state.get(); if (ptr == nullptr) { HPX_THROW_EXCEPTION(no_state, "invoke_continuation", "the inner future has no valid shared state"); } // Bind an on_completed handler to this future which will transfer // its result to the new future. boost::intrusive_ptr<Continuation> cont_(&cont); ptr->execute_deferred(); ptr->set_on_completed( util::deferred_call(transfer_result<inner_future>(), std::move(inner_state), std::move(cont_))); } catch (...) { cont.set_exception(std::current_exception()); } }