3#ifdef __cpp_lib_coroutine
9#include "detail/function_result.hpp"
10#include "detail/is_instance_of.hpp"
11#include "detail/task_future.hpp"
17#ifdef __cpp_exceptions
18 #define DISPATCH_QUEUE_THROW_OR(err_msg, body) throw task_error(err_msg)
20 #define DISPATCH_QUEUE_THROW_OR(err_msg, body) body
40 task(std::shared_ptr<detail::task_future<T>> future)
49 return detail::task_future<T>::create_pending();
55 template<typename U = T, typename = typename std::enable_if<std::is_void<U>::value>::type>
57 return detail::task_future<T>::create_ready();
63 template<typename U = T, typename = typename std::enable_if<not std::is_void<U>::value>::type>
65 return detail::task_future<T>::create_ready(std::move(value));
72 return detail::task_future<T>::create_failed(exception);
92 requires (detail::is_instance_of<T, task>::value)
93 auto then(F&& f)
const {
95 task value_this = *
this;
96 auto nested_future = detail::task_future<detail::function_result<F, T>>
::create_pending();
98 value_this.
get().then([=](
const auto& t) {
99 nested_future->do_work(f, t);
102 return to_task(nested_future);
105 using future_t = detail::task_future<detail::function_result<F, T>>;
107 auto work = std::bind(f, T{});
108 auto future = future_t::create(std::move(work));
109 return to_task(future);
126 task value_this = *
this;
127 return to_task(future->then([=] {
128 return f(value_this);
132 using future_t = detail::task_future<detail::function_result<F, task>>;
134 auto work = std::bind(f, *
this);
135 auto future = future_t::create(std::move(work));
136 return to_task(future);
149 return future->get();
161 template<typename U = T, typename = typename std::enable_if<std::is_void<U>::value>::type>
164 if (!future->set_value()) {
178 template<typename U = T, typename = typename std::enable_if<not std::is_void<U>::value>::type>
181 if (!future->set_value(std::move(value))) {
195 return future->get_state();
207 return future->get_exception();
210 return std::make_exception_ptr(
task_error(
"task is invalid"));
221 if (!future->set_exception(exception)) {
257 template<
class Rep,
class Period>
258 bool wait_for(
const std::chrono::duration<Rep, Period>& timeout_duration)
const {
260 return future->wait_for(timeout_duration);
277 template<
class Clock,
class Duration>
278 bool wait_until(
const std::chrono::time_point<Clock, Duration>& timeout_time)
const {
280 return future->wait_until(timeout_time);
293 auto void_future = detail::task_future<void>::create_pending();
296 void_future->set_exception(exception);
299 void_future->set_value();
302 return to_task(void_future);
319 template<typename U, typename = typename std::enable_if<std::is_convertible<T, U>::value>::type>
323 auto u_future = detail::task_future<U>::create_pending();
326 u_future->set_exception(exception);
329 U u_value = (U) t.
get();
330 u_future->set_value(std::move(u_value));
333 return to_task(u_future);
337 U u_value = (U)
get();
349#ifdef __cpp_lib_coroutine
353 task_awaiter(
const task<T>& t) : t(t) {}
354 task_awaiter(
task<T>&& t) : t(std::move(t)) {}
356 bool await_ready() const noexcept {
360 void await_suspend(std::coroutine_handle<> cont)
const {
361 t.then([cont](
auto&&) {
389 task_awaiter
operator co_await()
const {
390 return task_awaiter(*
this);
395 std::shared_ptr<detail::task_future<T>> future;
399 static task<U> to_task(std::shared_ptr<detail::task_future<U>> future) {
Definition task_error.hpp:10
bool wait_for(const std::chrono::duration< Rep, Period > &timeout_duration) const
Definition task.hpp:258
T get() const
Definition task.hpp:147
task_state get_state() const
Definition task.hpp:193
void set_value()
Definition task.hpp:162
static task create_failed(std::exception_ptr exception)
Definition task.hpp:71
static task create_ready()
Definition task.hpp:56
bool valid() const
Definition task.hpp:78
static task create_pending()
Definition task.hpp:48
void set_value(U &&value)
Definition task.hpp:179
task(std::shared_ptr< detail::task_future< T > > future)
Definition task.hpp:40
void wait() const
Definition task.hpp:238
std::exception_ptr get_exception() const
Definition task.hpp:205
void set_exception(std::exception_ptr exception)
Definition task.hpp:219
bool wait_until(const std::chrono::time_point< Clock, Duration > &timeout_time) const
Definition task.hpp:278
auto then(F &&f) const
Definition task.hpp:124
T value_type
Definition task.hpp:34
static task create_ready(U &&value)
Definition task.hpp:64
Definition dispatch_queue.hpp:19
task_state
Definition task_state.hpp:9
@ failed
Task failed with an exception.
Definition task_state.hpp:17
@ pending
Task is either queued for execution or still running.
Definition task_state.hpp:13
@ ready
Task finished successfully and the result value is readily available.
Definition task_state.hpp:15
@ invalid
Task was created without a future and is invalid.
Definition task_state.hpp:11
#define DISPATCH_QUEUE_THROW_OR(err_msg, body)
Definition task.hpp:20