xtd 1.0.0
Loading...
Searching...
No Matches
task_result.hpp
Go to the documentation of this file.
1
4#pragma once
5#include "basic_task.hpp"
6
8namespace xtd {
10 namespace threading {
12 namespace tasks {
19 template<typename result_t>
20 class task : public xtd::threading::tasks::basic_task<result_t> {
21 public:
22 struct promise_type {
25 std::coroutine_handle<promise_type> this_;
26
27 auto final_suspend() noexcept {
28 struct final_awaiter {
29 promise_type& promise;
30
31 bool await_ready() noexcept {return false;}
32 void await_resume() noexcept {}
33 void await_suspend(std::coroutine_handle<promise_type> handle) noexcept {
34 promise.task_->start();
35 promise.this_.destroy();
36 }
37 };
38 return final_awaiter {*this};
39 }
40 xtd::threading::tasks::task<result_t> get_return_object() {
42 this_ = std::coroutine_handle<promise_type>::from_promise(*this);
43 return *task_;
44 }
45 std::suspend_never initial_suspend() {return {};}
46 void return_value(const result_t& result) {task_->template basic_task<result_t>::data_->result = result;}
47 void unhandled_exception() {exception_ = task_->template basic_task<result_t>::data_->exception;}
48 };
49
50 struct awaiter {
52
53 bool await_ready() const noexcept {return this->task_.is_completed();}
54 void await_suspend(std::coroutine_handle<> handle) {task_.continue_with_([handle] {handle.resume();});}
55 const result_t& await_resume() {
56 task_.on_await_resume();
57 if (task_.is_faulted()) task_.rethrow_exception();
58 return task_.result();
59 }
60 };
61
63 task();
64 task(const std::coroutine_handle<typename task<result_t>::promise_type>& handle) { {*handle_ = handle;}}
65 ~task() {if (handle_.is_unique() && *handle_) handle_->destroy();}
66
68
70
72 task(auto func);
73 task(auto func, const xtd::threading::cancellation_token& cancellation_token);
74 task(auto func, const xtd::any_object& state);
75 task(auto func, const xtd::any_object& state, const xtd::threading::cancellation_token& cancellation_token);
77
79
81 [[nodiscard]] auto result() const -> const result_t& {
82 if (!basic_task<result_t>::is_completed()) static_cast<basic_task<result_t>&>(const_cast<task&>(*this)).wait();
83 return basic_task<result_t>::data_->result;
84 }
86
88
90 [[nodiscard]] static auto from_result(result_t result) -> task {
91 auto t = task {};
92 t.data_->result = result;
93 t.basic_task<result_t>::data_->status = xtd::threading::tasks::task_status::ran_to_completion;
94 t.basic_task<result_t>::data_->end_event.set();
95 return t;
96 }
98
100
102 auto operator co_await() noexcept {return awaiter {*this};}
104
105 private:
107 };
108
110 template<typename result_t>
111 inline task<result_t>::task() {
112 lock_(this->static_data_.sync_root) {
113 this->static_data_.tasks.add(this->data_->unique_id, new_sptr<task<result_t>>(*this));
114 }
115 }
116
117 template<typename result_t>
118 inline task<result_t>::task(auto func) : basic_task<result_t> {func} {
119 lock_(this->static_data_.sync_root) {
120 this->static_data_.tasks.add(this->data_->unique_id, new_sptr<task<result_t>>(*this));
121 }
122 }
123
124 template<typename result_t>
125 inline task<result_t>::task(auto func, const xtd::threading::cancellation_token& cancellation_token) : basic_task<result_t> {func, cancellation_token} {
126 lock_(this->static_data_.sync_root) {
127 this->static_data_.tasks.add(this->data_->unique_id, new_sptr<task<result_t>>(*this));
128 }
129 }
130
131 template<typename result_t>
132 inline task<result_t>::task(auto func, const xtd::any_object& state) : basic_task<result_t> {func, state} {
133 lock_(this->static_data_.sync_root) {
134 this->static_data_.tasks.add(this->data_->unique_id, new_sptr<task<result_t>>(*this));
135 }
136 }
137
138 template<typename result_t>
139 inline task<result_t>::task(auto func, const xtd::any_object& state, const xtd::threading::cancellation_token& cancellation_token) : basic_task<result_t> {func, state, cancellation_token} {
140 lock_(this->static_data_.sync_root) {
141 this->static_data_.tasks.add(this->data_->unique_id, new_sptr<task<result_t>>(*this));
142 }
143 }
145 }
146 }
147}
148
149#include "task_factory.hpp"
150
Contains xtd::threading::tasks::basic_task <> class.
Represent a polymorphic wrapper capable of holding any type.
Definition any_object.hpp:30
Represents an exception whose state is captured at a certain point in code.
Definition exception_dispatch_info.hpp:30
Propagates notification that operations should be canceled.
Definition cancellation_token.hpp:39
Represents an asynchronous operation.
Definition task_result.hpp:20
xtd::delegate< result_t(arguments_t... arguments)> func
Represents a delegate that has variables parameters and returns a value of the type specified by the ...
Definition func.hpp:27
#define lock_(object)
The lock_ keyword marks a statement block as a critical section by obtaining the mutual-exclusion loc...
Definition lock.hpp:68
@ ran_to_completion
The task completed execution successfully.
Definition task_status.hpp:35
xtd::shared_ptr_object< type_t > sptr
The xtd::sptr object is a shared pointer.
Definition sptr.hpp:25
xtd::sptr< type_t > ptr
The xtd::ptr object is a shared pointer.
Definition ptr.hpp:27
auto new_ptr(args_t &&... args) -> xtd::ptr< type_t >
The xtd::new_ptr operator creates a xtd::ptr object.
Definition new_ptr.hpp:24
auto new_sptr(args_t &&... args) -> xtd::sptr< type_t >
xtd::new_sptr operator creates a xtd::sptr object.
Definition new_sptr.hpp:24
@ t
The T key.
Definition console_key.hpp:126
The xtd::threading::tasks namespace provides types that simplify the work of writing concurrent and a...
Definition itask.hpp:14
The xtd::threading namespace provides classes and interfaces that enable multithreaded programming....
Definition abandoned_mutex_exception.hpp:10
The xtd namespace contains all fundamental classes to access Hardware, Os, System,...
Definition abstract_object.hpp:8
Definition task_result.hpp:50
Definition task_result.hpp:22
Contains xtd::threading::tasks::task_factory <result_t> class.