xtd 0.2.0
delegate.hpp
Go to the documentation of this file.
1
4#pragma once
5#include "any.hpp"
7#include "async_result.hpp"
8#include "iequatable.hpp"
9#include "object.hpp"
10#include "object_ref.hpp"
11#include <functional>
12#include <stdexcept>
13#include <vector>
14
16namespace xtd {
18 template<class result_t>
19 class delegate;
20
21 template<class result_t, class ...arguments_t>
22 class delegate<result_t(arguments_t...)>;
24
39 using async_callback = xtd::delegate<void(async_result ar)>;
40
55 template<class result_t>
56 class delegate<result_t()> : public xtd::object, public xtd::iequatable<delegate<result_t()>> {
57 struct data {
58 std::vector<std::function <result_t()>> functions;
59 };
60
61 class async_result_invoke : public xtd::iasync_result {
62 struct data;
63 public:
64 async_result_invoke(xtd::async_callback async_callback, std::any async_state);
65 std::any async_state() const noexcept override;
66 xtd::threading::wait_handle& async_wait_handle() noexcept override;
67 bool completed_synchronously() const noexcept override;
68 bool is_completed() const noexcept override;
69
70 xtd::sptr<data> data_;
71 };
72
73 public:
75
78 using function_t = std::function <result_t()>;
80
82
85 delegate() = default;
87 delegate(delegate&&) = default;
88 delegate(const delegate&) = default;
89 delegate& operator =(const delegate& delegate) = default;
91
94 delegate(const function_t& function) noexcept {data_->functions.push_back(function);} // Can't be explicit by design.
95
99 template<class object1_t, class object2_t>
100 delegate(const object1_t& object, result_t(object2_t::*method)() const) noexcept {
101 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object))));
102 }
106 template<class object1_t, class object2_t>
107 delegate(const object1_t& object, result_t(object2_t::*method)()) noexcept {
108 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object))));
109 }
111
113
117 const std::vector<function_t>& functions() const {return data_->functions;}
118
121 bool is_empty() const noexcept {return data_->functions.size() == 0;}
122
125 size_t size() const noexcept {return data_->functions.size();}
127
129
132 void clear() {data_->functions.clear();}
133
155
161 result_t end_invoke(async_result async);
162
169 result_t invoke() const {return operator()();}
170
174 bool equals(const object& obj) const noexcept override {return is<delegate>(obj) && equals(static_cast<const delegate&>(obj));}
178 bool equals(const delegate& other) const noexcept override {
179 if (data_->functions.size() != other.data_->functions.size())
180 return false;
181
182 for (size_t i = 0; i < data_->functions.size(); i++)
183 if (!are_equals(data_->functions[i], other.data_->functions[i]))
184 return false;
185
186 return true;
187 }
189
191
198 static delegate combine(const std::vector<delegate>& delegates) noexcept {
199 delegate result;
200 for (const delegate& delegate : delegates) {
201 for (const function_t& function : delegate.data_->functions)
202 result.data_->functions.push_back(function);
203 }
204 return result;
205 }
206
212 static delegate combine(const delegate& a, const delegate& b) noexcept {
213 delegate result = a;
214 for (const function_t& function : b.data_->functions)
215 result.data_->functions.push_back(function);
216 return result;
217 }
218
224 static delegate remove(const delegate& source, const delegate& value) noexcept {
225 delegate result = source;
226 std::for_each(value.data_->functions.begin(), value.data_->functions.end(), [&](auto function) {
227 auto iterator = std::find_if(result.data_->functions.rbegin(), result.data_->functions.rend(), [&](auto item) {return are_equals(item, function);});
228 if (iterator != result.data_->functions.rend()) result.data_->functions.erase((iterator + 1).base());
229 });
230 return result;
231 }
232
238 static delegate remove_all(const delegate& source, const delegate& value) noexcept {
239 delegate result = source;
240 for (const function_t& function : value.data_->functions) {
241 if (find(result.data_->functions.begin(), result.data_->functions.end(), function) != result.data_->functions.end()) {
242 for (typename std::vector<function_t>::reverse_iterator iterator = result.data_->functions.rbegin(); iterator != result.data_->functions.rend(); ++iterator) {
243 if (are_equals(*iterator, function))
244 result.data_->functions.erase((iterator + 1).base());
245 }
246 }
247 }
248 return result;
249 }
251
253
258 result_t operator()() const {
259 if (data_->functions.size() == 0) return result_t();
260
261 for (size_t i = 0; i < data_->functions.size() - 1; i++) {
263 data_->functions[i]();
264 }
266 return data_->functions.back()();
267 }
268
269 delegate& operator =(const function_t& function) noexcept {
270 data_->functions.clear();
271 data_->functions.push_back(function);
272 return *this;
273 }
275
277 delegate operator +(const delegate& other) noexcept {
278 delegate result = *this;
279 result += other;
280 return result;
281 }
282
283 delegate operator +(const function_t& function) noexcept {
284 delegate result = *this;
285 result += function;
286 return result;
287 }
288
289 template<class fn_t>
290 delegate operator +(fn_t function) noexcept {
291 delegate result = *this;
292 result += function;
293 return result;
294 }
295
296 delegate& operator +=(const delegate& delegate) noexcept {
297 *this = delegate::combine(*this, delegate);
298 return *this;
299 }
300
301 delegate& operator +=(const function_t& function) noexcept {
302 *this = delegate::combine(*this, delegate(function));
303 return *this;
304 }
305
306 template<class fn_t>
307 delegate& operator +=(fn_t function) noexcept {
308 *this = delegate::combine(*this, delegate(function));
309 return *this;
310 }
311
312 delegate operator -(const delegate& other) noexcept {
313 delegate result = *this;
314 result -= other;
315 return result;
316 }
317
318 delegate operator -(const function_t& function) noexcept {
319 delegate result = *this;
320 result -= function;
321 return result;
322 }
323
324 template<class fn_t>
325 delegate operator -(fn_t function) noexcept {
326 delegate result = *this;
327 result -= function;
328 return result;
329 }
330
331 delegate& operator -=(const delegate& delegate) noexcept {
332 *this = delegate::remove(*this, delegate);
333 return *this;
334 }
335
336 delegate& operator -=(const function_t& function) noexcept {
337 *this = delegate::remove(*this, delegate(function));
338 return *this;
339 }
340
341 template<class fn_t>
342 delegate& operator -=(fn_t function) noexcept {
343 *this = delegate::remove(*this, delegate(function));
344 return *this;
345 }
347
348 private:
349 static bool are_equals(const std::function<result_t()>& fct1, const std::function<result_t()>& fct2) noexcept {
350 return fct1.target_type() == fct2.target_type() && (fct1.template target<result_t(*)()>() == fct2.template target<result_t(*)()>() || *fct1.template target<result_t(*)()>() == *fct2.template target<result_t(*)()>());
351 }
352
353 static typename std::vector<function_t>::const_iterator find(typename std::vector<function_t>::const_iterator begin, typename std::vector<function_t>::const_iterator end, const function_t& function) noexcept {
354 auto iterator = std::find_if(begin, end, [&](auto item) {return are_equals(item, function);});
355 if (iterator != end) return iterator;
356 return end;
357 }
358 xtd::sptr<data> data_ = xtd::new_sptr<data>();
359 };
360
375 template<class result_t, class ...arguments_t>
376 class delegate<result_t(arguments_t...)> : public object, public xtd::iequatable<delegate<result_t(arguments_t...)>> {
377 struct data {
378 std::vector<std::function <result_t()>> no_arguments_functions;
379 std::vector<std::function <result_t(arguments_t...)>> functions;
380 };
381
382 class async_result_invoke : public xtd::iasync_result {
383 struct data;
384 public:
385 async_result_invoke(xtd::async_callback async_callback, std::any async_state);
386 std::any async_state() const noexcept override;
387 xtd::threading::wait_handle& async_wait_handle() noexcept override;
388 bool completed_synchronously() const noexcept override;
389 bool is_completed() const noexcept override;
390
391 xtd::sptr<data> data_;
392 };
393
394 public:
396
399 using no_arguments_function_t = std::function <result_t()>;
401 using function_t = std::function <result_t(arguments_t...)>;
403
405
408 delegate() = default;
410 delegate(delegate&&) = default;
411 delegate(const delegate&) = default;
412 delegate& operator =(const delegate& delegate) = default;
413 delegate(const delegate<result_t()>& delegate) noexcept {data_->no_arguments_functions = delegate.functions();}
415
418 delegate(const function_t& function) noexcept {data_->functions.push_back(function);} // Can't be explicit by design.
419
421 delegate(const no_arguments_function_t& function) noexcept {data_->no_arguments_functions.push_back(function);} // Can't be explicit by design.
423
427 template<class object1_t, class object2_t>
428 delegate(const object1_t& object, result_t(object2_t::*method)() const) noexcept {
429 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object))));
430 }
431
435 template<class object1_t, class object2_t>
436 delegate(const object1_t& object, result_t(object2_t::*method)()) noexcept {
437 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object))));
438 }
440
442 template<class object1_t, class object2_t, class a1_t>
443 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t) const) noexcept {
444 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1)));
445 }
446
447 template<class object1_t, class object2_t, class a1_t>
448 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t)) noexcept {
449 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1)));
450 }
451
452 template<class object1_t, class object2_t, class a1_t, class a2_t>
453 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t) const) noexcept {
454 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2)));
455 }
456
457 template<class object1_t, class object2_t, class a1_t, class a2_t>
458 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t)) noexcept {
459 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2)));
460 }
461
462 template<class object1_t, class object2_t, class a1_t, class a2_t, class a3_t>
463 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t) const) noexcept {
464 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)));
465 }
466
467 template<class object1_t, class object2_t, class a1_t, class a2_t, class a3_t>
468 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t)) noexcept {
469 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)));
470 }
471
472 template<class object1_t, class object2_t, class a1_t, class a2_t, class a3_t, class a4_t>
473 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t) const) {
474 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)));
475 }
476
477 template<class object1_t, class object2_t, class a1_t, class a2_t, class a3_t, class a4_t>
478 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t)) noexcept {
479 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4)));
480 }
481
482 template<class object1_t, class object2_t, class a1_t, class a2_t, class a3_t, class a4_t, class A5>
483 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5) const) noexcept {
484 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5)));
485 }
486
487 template<class object1_t, class object2_t, class a1_t, class a2_t, class a3_t, class a4_t, class A5>
488 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5)) {
489 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5)));
490 }
491
492 template<class object1_t, class object2_t, class a1_t, class a2_t, class a3_t, class a4_t, class A5, class a6_t>
493 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t) const) noexcept {
494 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6)));
495 }
496
497 template<class object1_t, class object2_t, class a1_t, class a2_t, class a3_t, class a4_t, class A5, class a6_t>
498 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t)) noexcept {
499 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6)));
500 }
501
502 template<class object1_t, class object2_t, class a1_t, class a2_t, class a3_t, class a4_t, class A5, class a6_t, class a7_t>
503 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t, a7_t) const) noexcept {
504 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7)));
505 }
506
507 template<class object1_t, class object2_t, class a1_t, class a2_t, class a3_t, class a4_t, class A5, class a6_t, class a7_t>
508 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t, a7_t)) noexcept {
509 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7)));
510 }
511
512 template<class object1_t, class object2_t, class a1_t, class a2_t, class a3_t, class a4_t, class A5, class a6_t, class a7_t, class a8_t>
513 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t, a7_t, a8_t) const) noexcept {
514 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7, std::placeholders::_8)));
515 }
516
517 template<class object1_t, class object2_t, class a1_t, class a2_t, class a3_t, class a4_t, class A5, class a6_t, class a7_t, class a8_t>
518 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t, a7_t, a8_t)) noexcept {
519 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7, std::placeholders::_8)));
520 }
521
522 template<class object1_t, class object2_t, class a1_t, class a2_t, class a3_t, class a4_t, class A5, class a6_t, class a7_t, class a8_t, class a9_t>
523 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t, a7_t, a8_t, a9_t) const) noexcept {
524 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7, std::placeholders::_8, std::placeholders::_9)));
525 }
526
527 template<class object1_t, class object2_t, class a1_t, class a2_t, class a3_t, class a4_t, class A5, class a6_t, class a7_t, class a8_t, class a9_t>
528 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t, a7_t, a8_t, a9_t)) noexcept {
529 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7, std::placeholders::_8, std::placeholders::_9)));
530 }
531
532 template<class object1_t, class object2_t, class a1_t, class a2_t, class a3_t, class a4_t, class A5, class a6_t, class a7_t, class a8_t, class a9_t, class a10_t>
533 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t, a7_t, a8_t, a9_t, a10_t) const) noexcept {
534 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7, std::placeholders::_8, std::placeholders::_9, std::placeholders::_10)));
535 }
536
537 template<class object1_t, class object2_t, class a1_t, class a2_t, class a3_t, class a4_t, class A5, class a6_t, class a7_t, class a8_t, class a9_t, class a10_t>
538 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t, a7_t, a8_t, a9_t, a10_t)) noexcept {
539 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7, std::placeholders::_8, std::placeholders::_9, std::placeholders::_10)));
540 }
542
544
548 const std::vector<no_arguments_function_t>& no_arguments_functions() const {return data_->no_arguments_functions;}
549
552 const std::vector<function_t>& functions() const {return data_->functions;}
553
556 bool is_empty() const noexcept {return data_->functions.size() == 0 && data_->no_arguments_functions.size() == 0;}
557
560 size_t size() const noexcept {return data_->functions.size() + data_->no_arguments_functions.size();}
562
564
574 async_result begin_invoke(arguments_t... arguments);
589 async_result begin_invoke(xtd::async_callback async_callback, std::any async_state, arguments_t... arguments);
590
596 result_t end_invoke(async_result async);
597
604 result_t invoke(arguments_t... arguments) const {return operator()(arguments...);}
605
609 bool equals(const object& obj) const noexcept override {return is<delegate>(obj) && equals(static_cast<const delegate&>(obj));}
613 bool equals(const delegate& other) const noexcept override {
614 if (data_->functions.size() != other.data_->functions.size() || data_->no_arguments_functions.size() != other.data_->no_arguments_functions.size())
615 return false;
616
617 for (size_t i = 0; i < data_->no_arguments_functions.size(); i++)
618 if (!are_equals(data_->no_arguments_functions[i], other.data_->no_arguments_functions[i]))
619 return false;
620
621 for (size_t i = 0; i < data_->functions.size(); i++)
622 if (!are_equals(data_->functions[i], other.data_->functions[i]))
623 return false;
624
625 return true;
626 }
628
630
637 static delegate combine(const std::vector<delegate>& delegates) noexcept {
638 delegate result;
639 for (const delegate& delegate : delegates) {
640 for (const no_arguments_function_t& function : delegate.data_->no_arguments_functions)
641 result.data_->no_arguments_functions.push_back(function);
642 for (const function_t& function : delegate.data_->functions)
643 result.data_->functions.push_back(function);
644 }
645 return result;
646 }
647
653 static delegate combine(const delegate& a, const delegate& b) noexcept {
654 delegate result = a;
655 for (const no_arguments_function_t& function : b.data_->no_arguments_functions)
656 result.data_->no_arguments_functions.push_back(function);
657 for (const function_t& function : b.data_->functions)
658 result.data_->functions.push_back(function);
659 return result;
660 }
661
667 static delegate remove(const delegate& source, const delegate& value) noexcept {
668 delegate result = source;
669 std::for_each(value.data_->no_arguments_functions.begin(), value.data_->no_arguments_functions.end(), [&](auto no_arguments_function) {
670 auto iterator = std::find_if(result.data_->no_arguments_functions.rbegin(), result.data_->no_arguments_functions.rend(), [&](auto item) {return are_equals(item, no_arguments_function);});
671 if (iterator != result.data_->no_arguments_functions.rend()) result.data_->no_arguments_functions.erase((iterator + 1).base());
672 });
673
674 std::for_each(value.data_->functions.begin(), value.data_->functions.end(), [&](auto function) {
675 auto iterator = std::find_if(result.data_->functions.rbegin(), result.data_->functions.rend(), [&](auto item) {return are_equals(item, function);});
676 if (iterator != result.data_->functions.rend()) result.data_->functions.erase((iterator + 1).base());
677 });
678 return result;
679 }
680
686 static delegate remove_all(const delegate& source, const delegate& value) noexcept {
687 delegate result = source;
688 for (const no_arguments_function_t& function : value.data_->no_arguments_functions) {
689 if (find(result.data_->no_arguments_functions.begin(), result.data_->no_arguments_functions.end(), function) != result.data_->no_arguments_functions.end()) {
690 for (typename std::vector<function_t>::reverse_iterator iterator = result.data_->no_arguments_functions.rbegin(); iterator != result.data_->no_arguments_functions.rend(); ++iterator) {
691 if (are_equals(*iterator, function))
692 result.data_->no_arguments_functions.erase((iterator + 1).base());
693 }
694 }
695 }
696
697 for (const function_t& function : value.data_->functions) {
698 if (find(result.data_->functions.begin(), result.data_->functions.end(), function) != result.data_->functions.end()) {
699 for (typename std::vector<function_t>::reverse_iterator iterator = result.data_->functions.rbegin(); iterator != result.data_->functions.rend(); ++iterator) {
700 if (are_equals(*iterator, function))
701 result.data_->functions.erase((iterator + 1).base());
702 }
703 }
704 }
705 return result;
706 }
708
710
715 result_t operator()(arguments_t... arguments) const {
716 if (data_->no_arguments_functions.size() == 0 && data_->functions.size() == 0) return result_t();
717
718 if (data_->no_arguments_functions.size()) {
719 for (size_t i = 0; i < data_->no_arguments_functions.size() - (data_->functions.size() == 0 ? 1 : 0); i++) {
720 if (data_->no_arguments_functions[i] == nullptr) xtd::helpers::throw_helper::throws(xtd::helpers::exception_case::argument_null);
721 data_->no_arguments_functions[i]();
722 }
723
724 if (data_->functions.size() == 0) {
725 if (data_->no_arguments_functions.back() == nullptr) xtd::helpers::throw_helper::throws(xtd::helpers::exception_case::argument_null);
726 return data_->no_arguments_functions.back()();
727 }
728 }
729
730 for (size_t i = 0; i < data_->functions.size() - 1; i++) {
732 data_->functions[i](arguments...);
733 }
735 return data_->functions.back()(arguments...);
736 }
738
740 template<class type_t>
741 delegate& operator =(const type_t& function) noexcept {
742 data_->no_arguments_functions.clear();
743 data_->functions.clear();
744 data_->functions.push_back(function_t(function));
745 return *this;
746 }
747
748 delegate& operator =(const function_t& function) noexcept {
749 data_->no_arguments_functions.clear();
750 data_->functions.clear();
751 data_->functions.push_back(function);
752 return *this;
753 }
754
755 delegate& operator =(const no_arguments_function_t& function) noexcept {
756 data_->no_arguments_functions.clear();
757 data_->functions.clear();
758 data_->no_arguments_functions.push_back(function);
759 return *this;
760 }
761
762 delegate operator +(const delegate& other) noexcept {
763 delegate result = *this;
764 result += other;
765 return result;
766 }
767
768 delegate operator +(const no_arguments_function_t& function) noexcept {
769 delegate result = *this;
770 result += function;
771 return result;
772 }
773
774 delegate operator +(const function_t& function) noexcept {
775 delegate result = *this;
776 result += function;
777 return result;
778 }
779
780 template<class fn_t>
781 delegate operator +(fn_t function) noexcept {
782 delegate result = *this;
783 result += function;
784 return result;
785 }
786
787 delegate& operator +=(const delegate& delegate) noexcept {
788 *this = delegate::combine(*this, delegate);
789 return *this;
790 }
791
792 delegate& operator +=(const no_arguments_function_t& function) noexcept {
793 *this = delegate::combine(*this, delegate(function));
794 return *this;
795 }
796
797 delegate& operator +=(const function_t& function) noexcept {
798 *this = delegate::combine(*this, delegate(function));
799 return *this;
800 }
801
802 template<class fn_t>
803 delegate& operator +=(fn_t function) noexcept {
804 *this = delegate::combine(*this, delegate(function));
805 return *this;
806 }
807
808 delegate operator -(const delegate& other) noexcept {
809 delegate result = *this;
810 result -= other;
811 return result;
812 }
813
814 delegate operator -(const no_arguments_function_t& function) noexcept {
815 delegate result = *this;
816 result -= function;
817 return result;
818 }
819
820 delegate operator -(const function_t& function) noexcept {
821 delegate result = *this;
822 result -= function;
823 return result;
824 }
825
826 template<class fn_t>
827 delegate operator -(fn_t function) noexcept {
828 delegate result = *this;
829 result -= function;
830 return result;
831 }
832
833 delegate& operator -=(const delegate& delegate) noexcept {
834 *this = delegate::remove(*this, delegate);
835 return *this;
836 }
837
838 delegate& operator -=(const no_arguments_function_t& function) noexcept {
839 *this = delegate::remove(*this, delegate(function));
840 return *this;
841 }
842
843 delegate& operator -=(const function_t& function) noexcept {
844 *this = delegate::remove(*this, delegate(function));
845 return *this;
846 }
847
848 template<class fn_t>
849 delegate& operator -=(fn_t function) noexcept {
850 *this = delegate::remove(*this, delegate(function));
851 return *this;
852 }
854
855 private:
856 static bool are_equals(const std::function<result_t(arguments_t...)>& fct1, const std::function<result_t(arguments_t...)>& fct2) noexcept {
857 return fct1.target_type() == fct2.target_type() && (fct1.template target<result_t(*)(arguments_t...)>() == fct2.template target<result_t(*)(arguments_t...)>() || *fct1.template target<result_t(*)(arguments_t...)>() == *fct2.template target<result_t(*)(arguments_t...)>());
858 }
859
860 static bool are_equals(const std::function<result_t()>& fct1, const std::function<result_t()>& fct2) noexcept {
861 return fct1.target_type() == fct2.target_type() && (fct1.template target<result_t(*)()>() == fct2.template target<result_t(*)()>() || *fct1.template target<result_t(*)()>() == *fct2.template target<result_t(*)()>());
862 }
863
864 static typename std::vector<no_arguments_function_t>::const_iterator find(typename std::vector<no_arguments_function_t>::const_iterator begin, typename std::vector<no_arguments_function_t>::const_iterator end, const no_arguments_function_t& function) noexcept {
865 auto iterator = std::find_if(begin, end, [&](auto item) {return are_equals(item, function);});
866 if (iterator != end) return iterator;
867 return end;
868 }
869
870 static typename std::vector<function_t>::const_iterator find(typename std::vector<function_t>::const_iterator begin, typename std::vector<function_t>::const_iterator end, const function_t& function) noexcept {
871 auto iterator = std::find_if(begin, end, [&](auto item) {return are_equals(item, function);});
872 if (iterator != end) return iterator;
873 return end;
874 }
875
876 xtd::sptr<data> data_ = xtd::new_sptr<data>();
877 };
878}
879
880// Required for begin_invoke and end_invoke methods implementation.
Contains std::any type and std::bad_any_cast exception.
Contains xtd::argument_null_exception exception.
Contains xtd::async_result alias.
delegate(const object1_t &object, result_t(object2_t::*method)()) noexcept
Initializes a delegate that invokes the specified instance method on the specified class instance.
Definition delegate.hpp:107
static delegate remove_all(const delegate &source, const delegate &value) noexcept
removes all occurrences of the invocation list of a delegate from the invocation list of another dele...
Definition delegate.hpp:238
delegate(const object1_t &object, result_t(object2_t::*method)() const) noexcept
Initializes a delegate that invokes the specified instance method on the specified class instance.
Definition delegate.hpp:100
void clear()
Clear delegates array.
Definition delegate.hpp:132
delegate()=default
Initializes an empty delegate.
static delegate combine(const std::vector< delegate > &delegates) noexcept
Concatenates the invocation lists of an array of delegates.
Definition delegate.hpp:198
bool equals(const delegate &other) const noexcept override
Determines whether this instance and another specified delegateType object have the same value.
Definition delegate.hpp:178
bool is_empty() const noexcept
Return if the delegate is empty.
Definition delegate.hpp:121
size_t size() const noexcept
Return the size of invocation list.
Definition delegate.hpp:125
async_result begin_invoke(xtd::async_callback async_callback)
Executes the method represented by the current delegate asynchronously on the thread that the control...
delegate(const function_t &function) noexcept
Initializes a delegate that invokes the specified instance method.
Definition delegate.hpp:94
const std::vector< function_t > & functions() const
Gets the delegates array.
Definition delegate.hpp:117
std::function< result_t()> function_t
function_t pointer type
Definition delegate.hpp:78
async_result begin_invoke(xtd::async_callback async_callback, std::any async_state)
Executes the method represented by the current delegate asynchronously on the thread that the control...
result_t end_invoke(async_result async)
Retrieves the return value of the asynchronous operation represented by the async_result_invoke passe...
bool equals(const object &obj) const noexcept override
Determines whether this instance and another specified delegateType object have the same value.
Definition delegate.hpp:174
static delegate combine(const delegate &a, const delegate &b) noexcept
Concatenates the invocation lists of two delegates.
Definition delegate.hpp:212
result_t invoke() const
invokes the method represented by the current delegate.
Definition delegate.hpp:169
static delegate remove(const delegate &source, const delegate &value) noexcept
removes the last occurrence of the invocation list of a delegate from the invocation list of another ...
Definition delegate.hpp:224
result_t operator()() const
invokes the method represented by the current delegate.
Definition delegate.hpp:258
async_result begin_invoke()
Executes the method represented by the current delegate asynchronously on the thread that the control...
std::function< result_t()> no_arguments_function_t
no_arguments_function_t pointer type
Definition delegate.hpp:399
const std::vector< function_t > & functions() const
Gets the delegates array.
Definition delegate.hpp:552
async_result begin_invoke(xtd::async_callback async_callback, std::any async_state, arguments_t... arguments)
Executes the method represented by the current delegate asynchronously on the thread that the control...
async_result begin_invoke(arguments_t... arguments)
Executes the method represented by the current delegate asynchronously on the thread that the control...
result_t invoke(arguments_t... arguments) const
invokes the method represented by the current delegate.
Definition delegate.hpp:604
result_t end_invoke(async_result async)
Retrieves the return value of the asynchronous operation represented by the async_result_invoke passe...
static delegate combine(const std::vector< delegate > &delegates) noexcept
Concatenates the invocation lists of an array of delegates.
Definition delegate.hpp:637
delegate()=default
Initializes an empty delegate.
bool equals(const delegate &other) const noexcept override
Determines whether this instance and another specified delegateType object have the same value.
Definition delegate.hpp:613
const std::vector< no_arguments_function_t > & no_arguments_functions() const
Gets the no arguments delegates array.
Definition delegate.hpp:548
std::function< result_t(arguments_t...)> function_t
function_t pointer type
Definition delegate.hpp:401
delegate(const object1_t &object, result_t(object2_t::*method)()) noexcept
Initializes a delegate that invokes the specified instance method on the specified class instance.
Definition delegate.hpp:436
size_t size() const noexcept
Return the size of invocation list.
Definition delegate.hpp:560
result_t operator()(arguments_t... arguments) const
invokes the method represented by the current delegate.
Definition delegate.hpp:715
bool is_empty() const noexcept
Return if the delegate is empty.
Definition delegate.hpp:556
static delegate remove(const delegate &source, const delegate &value) noexcept
removes the last occurrence of the invocation list of a delegate from the invocation list of another ...
Definition delegate.hpp:667
static delegate combine(const delegate &a, const delegate &b) noexcept
Concatenates the invocation lists of two delegates.
Definition delegate.hpp:653
static delegate remove_all(const delegate &source, const delegate &value) noexcept
removes all occurrences of the invocation list of a delegate from the invocation list of another dele...
Definition delegate.hpp:686
delegate(const function_t &function) noexcept
Initializes a delegate that invokes the specified instance method.
Definition delegate.hpp:418
async_result begin_invoke(xtd::async_callback async_callback, arguments_t... arguments)
Executes the method represented by the current delegate asynchronously on the thread that the control...
bool equals(const object &obj) const noexcept override
Determines whether this instance and another specified delegateType object have the same value.
Definition delegate.hpp:609
delegate(const object1_t &object, result_t(object2_t::*method)() const) noexcept
Initializes a delegate that invokes the specified instance method on the specified class instance.
Definition delegate.hpp:428
static void throws(xtd::helpers::exception_case exception_case, const source_location &location=source_location::current())
Throws an exption with specified exception case.
Represents the status of an asynchronous operation.
Definition iasync_result.hpp:25
Defines a generalized method that a value type or class implements to create a type-specific method f...
Definition iequatable.hpp:22
Supports all classes in the xtd class hierarchy and provides low-level services to derived classes....
Definition object.hpp:44
Encapsulates operating system specific objects that wait for exclusive access to shared resources.
Definition wait_handle.hpp:52
xtd::delegate< void(async_result ar)> async_callback
References a method to be called when a corresponding asynchronous operation completes.
Definition delegate.hpp:39
@ argument_null
The argument is null.
std::shared_ptr< type_t > sptr
The xtd::sptr object is a shared pointer.
Definition sptr.hpp:25
xtd::sptr< xtd::iasync_result > async_result
Represents the status of an asynchronous operation.
Definition async_result.hpp:19
@ other
The operating system is other.
@ a
The A key.
@ end
The END key.
@ i
The I key.
@ b
The B key.
@ function
The FUNCTION modifier key.
Contains xtd::iequatable interface.
The xtd namespace contains all fundamental classes to access Hardware, Os, System,...
Definition xtd_about_box.hpp:10
Contains xtd::object class.
Contains xtd::object_ref alias.
Contains xtd::threading::thread_pool class.