xtd 0.2.0
__delegate.hpp
Go to the documentation of this file.
1
4#pragma once
6#if !defined(__XTD_CORE_INTERNAL__)
7#error "Do not include this file: Internal use only"
8#endif
10
12#include "../delegate.hpp"
13
15template<class result_t = void>
16inline result_t __xtd_delegate_any_cast(const xtd::any_object& value) {
17 return value.has_value() ? xtd::as<result_t>(value) : result_t {};
18}
19
20template<>
21inline void __xtd_delegate_any_cast<void>(const xtd::any_object& value) {
22 return;
23}
24
25template<class result_t>
26inline xtd::any_object __xtd_delegate_invoker(std::function<result_t()> invoke) {
27 if constexpr (!std::is_void_v<result_t>) return xtd::any_object(invoke());
28 else {
29 invoke();
30 return xtd::any_object {};
31 }
32}
33
34template<typename function_t, typename... arguments_t>
35inline xtd::any_object __xtd_delegate_invoker(function_t&& invoke, arguments_t&&... arguments) {
36 if constexpr (!std::is_void_v<std::invoke_result_t<function_t, arguments_t...>>)
37 return xtd::any_object(std::invoke(std::forward<function_t>(invoke), std::forward<arguments_t>(arguments)...));
38 else {
39 std::invoke(std::forward<function_t>(invoke), std::forward<arguments_t>(arguments)...);
40 return xtd::any_object {};
41 }
42}
43
44template<class result_t>
45struct xtd::delegate<result_t()>::async_result_invoke::data {
47 xtd::threading::manual_reset_event async_event;
48 xtd::any_object async_state;
49 bool is_completed = false;
50 xtd::any_object result;
51};
52
53template<class result_t>
54xtd::delegate<result_t()>::async_result_invoke::async_result_invoke(xtd::async_callback async_callback, const xtd::any_object& async_state) : data_(xtd::new_sptr<data>()) {
55 data_->async_callback = async_callback;
56 data_->async_state = async_state;
57}
58
59template<class result_t>
60xtd::any_object xtd::delegate<result_t()>::async_result_invoke::async_state() const noexcept {
61 return data_->async_state;
62}
63
64template<class result_t>
65xtd::threading::wait_handle& xtd::delegate<result_t()>::async_result_invoke::async_wait_handle() noexcept {
66 return data_->async_event;
67}
68
69template<class result_t>
70bool xtd::delegate<result_t()>::async_result_invoke::completed_synchronously() const noexcept {
71 return false;
72}
73
74template<class result_t>
75bool xtd::delegate<result_t()>::async_result_invoke::is_completed() const noexcept {
76 return data_->is_completed;
77}
78
79template<class result_t>
80inline xtd::async_result xtd::delegate<result_t()>::begin_invoke() {
81 return begin_invoke(xtd::async_callback {}, xtd::any_object(*this));
82}
83
84template<class result_t>
85inline xtd::async_result xtd::delegate<result_t()>::begin_invoke(xtd::async_callback async_callback) {
86 return begin_invoke(async_callback, xtd::any_object(*this));
87}
88
89template<class result_t>
90xtd::async_result xtd::delegate<result_t()>::begin_invoke(xtd::async_callback async_callback, const xtd::any_object& async_state) {
91 auto async = xtd::new_sptr<async_result_invoke>(async_callback, async_state);
92 threading::thread_pool::queue_user_work_item([&, async = async] {
93 async->data_->result = __xtd_delegate_invoker(function_t {std::bind(&xtd::delegate<result_t()>::invoke, this)});
94 async->data_->is_completed = true;
95 async->data_->async_event.set();
96 async->data_->async_callback(async);
97 });
98 return async;
99}
100
101template<class result_t>
102result_t xtd::delegate<result_t()>::end_invoke(async_result async) {
103 auto async_result = as<async_result_invoke>(async);
104 async_result->data_->async_event.wait_one();
105 return __xtd_delegate_any_cast<result_t>(async_result->data_->result);
106}
107
108template<class result_t, class ...arguments_t>
109struct xtd::delegate<result_t(arguments_t...)>::async_result_invoke::data {
111 xtd::threading::manual_reset_event async_event;
112 xtd::any_object async_state;
113 bool is_completed = false;
114 xtd::any_object result;
115};
116
117template<class result_t, class ...arguments_t>
118xtd::delegate<result_t(arguments_t...)>::async_result_invoke::async_result_invoke(xtd::async_callback async_callback, const xtd::any_object& async_state) : data_(xtd::new_sptr<data>()) {
119 data_->async_callback = async_callback;
120 data_->async_state = async_state;
121}
122
123template<class result_t, class ...arguments_t>
124xtd::any_object xtd::delegate<result_t(arguments_t...)>::async_result_invoke::async_state() const noexcept {
125 return data_->async_state;
126}
127
128template<class result_t, class ...arguments_t>
129xtd::threading::wait_handle& xtd::delegate<result_t(arguments_t...)>::async_result_invoke::async_wait_handle() noexcept {
130 return data_->async_event;
131}
132
133template<class result_t, class ...arguments_t>
134bool xtd::delegate<result_t(arguments_t...)>::async_result_invoke::completed_synchronously() const noexcept {
135 return false;
136}
137
138template<class result_t, class ...arguments_t>
139bool xtd::delegate<result_t(arguments_t...)>::async_result_invoke::is_completed() const noexcept {
140 return data_->is_completed;
141}
142
143template<class result_t, class ...arguments_t>
144xtd::async_result xtd::delegate<result_t(arguments_t...)>::begin_invoke(arguments_t&&... arguments) {
145 return begin_invoke(xtd::async_callback {}, xtd::any_object(*this), std::forward<arguments_t>(arguments)...);
146}
147
148template<class result_t, class ...arguments_t>
149xtd::async_result xtd::delegate<result_t(arguments_t...)>::begin_invoke(xtd::async_callback async_callback, arguments_t&&... arguments) {
150 return begin_invoke(async_callback, xtd::any_object(*this), std::forward<arguments_t>(arguments)...);
151}
152
153template<typename result_t, typename... arguments_t>
154struct xtd::delegate<result_t(arguments_t...)>::delegate_async_state {
155 std::shared_ptr<async_result_invoke> async;
156 std::tuple<std::decay_t<arguments_t>...> arguments;
157 std::function<result_t(arguments_t...)> invoker;
158 delegate* self;
159 std::function<xtd::any_object(std::shared_ptr<delegate_async_state>)> start = [](std::shared_ptr<delegate_async_state> state) {
160 return std::apply([state](auto&&... unpacked_args)->xtd::any_object {
161 return __xtd_delegate_invoker(state->invoker, std::forward<decltype(unpacked_args)>(unpacked_args)...);
162 }, state->arguments);
163 };
164};
165
166template<class result_t, class ...arguments_t>
167xtd::async_result xtd::delegate<result_t(arguments_t...)>::begin_invoke(xtd::async_callback async_callback, const xtd::any_object& async_state, arguments_t&&... arguments) {
168 auto state = std::make_shared<delegate_async_state>();
169
170 state->async = xtd::new_sptr<async_result_invoke>(async_callback, async_state);
171 state->arguments = std::make_tuple(std::forward<arguments_t>(arguments)...);
172 state->invoker = [state](arguments_t... args) {return state->self->invoke(std::forward<arguments_t>(args)...);};
173 state->self = this;
174
175 threading::thread_pool::queue_user_work_item([state] {
176 state->async->data_->result = state->start(state);
177 state->async->data_->is_completed = true;
178 state->async->data_->async_event.set();
179 state->async->data_->async_callback(state->async);
180 });
181 return state->async;
182}
183
184template<class result_t, class ...arguments_t>
185result_t xtd::delegate<result_t(arguments_t...)>::end_invoke(async_result async) {
186 auto async_result = as<async_result_invoke>(async);
187 if (!async_result->data_->is_completed) async_result->data_->async_event.wait_one();
188 return __xtd_delegate_any_cast<result_t>(async_result->data_->result);
189}
Represent a polymorphic wrapper capable of holding any type.
Definition any_object.hpp:29
bool has_value() const noexcept
Gets a value indicating whether the current xtd::any_object object has a valid value of its underlyin...
Definition any_object.hpp:62
Encapsulates operating system specific objects that wait for exclusive access to shared resources.
Definition wait_handle.hpp:52
Contains xtd::delegate <result_t(arguments_t...)> delegate.
xtd::delegate< void(async_result ar)> async_callback
References a method to be called when a corresponding asynchronous operation completes.
Definition delegate.hpp:39
xtd::sptr< xtd::iasync_result > async_result
Represents the status of an asynchronous operation.
Definition async_result.hpp:19
type_t as(any_object &o)
Casts a type into another type.
Definition __as_any_object.hpp:59
sptr< type_t > new_sptr(args_t &&... args)
xtd::new_sptr operator creates a xtd::sptr object.
Definition new_sptr.hpp:24
@ start
Starting of a logical operation.
Definition trace_event_type.hpp:37
Contains xtd::threading::manual_reset_event exception.
The xtd namespace contains all fundamental classes to access Hardware, Os, System,...
Definition abstract_object.hpp:8
constexpr const_pointer data() const noexcept
Gets direct access to the underlying contiguous storage.
Definition read_only_span.hpp:201