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, const xtd::any_object& async_state);
65 xtd::any_object 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 using function_collection = std::vector<function_t>;
82
84
87 delegate() = default;
89 delegate(delegate&&) = default;
90 delegate(const delegate&) = default;
91 delegate& operator =(const delegate& delegate) = default;
93
96 delegate(const function_t& function) noexcept {data_->functions.push_back(function);} // Can't be explicit by design.
97
101 template<class object1_t, class object2_t>
102 delegate(const object1_t& object, result_t(object2_t::*method)() const) noexcept {
103 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object))));
104 }
108 template<class object1_t, class object2_t>
109 delegate(const object1_t& object, result_t(object2_t::*method)()) noexcept {
110 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object))));
111 }
113
115
119 const function_collection& functions() const {return data_->functions;}
120
123 bool is_empty() const noexcept {return data_->functions.size() == 0;}
124
127 size_t size() const noexcept {return data_->functions.size();}
129
131
134 void clear() {data_->functions.clear();}
135
157
163 result_t end_invoke(async_result async);
164
171 result_t invoke() const {return operator()();}
172
176 bool equals(const object& obj) const noexcept override {return is<delegate>(obj) && equals(static_cast<const delegate&>(obj));}
180 bool equals(const delegate& other) const noexcept override {
181 if (data_->functions.size() != other.data_->functions.size())
182 return false;
183
184 for (size_t i = 0; i < data_->functions.size(); i++)
185 if (!are_equals(data_->functions[i], other.data_->functions[i]))
186 return false;
187
188 return true;
189 }
191
193
200 static delegate combine(const array<delegate>& delegates) noexcept {
201 delegate result;
202 for (const delegate& delegate : delegates) {
203 for (const function_t& function : delegate.data_->functions)
204 result.data_->functions.push_back(function);
205 }
206 return result;
207 }
208
214 static delegate combine(const delegate& a, const delegate& b) noexcept {
215 delegate result = a;
216 for (const function_t& function : b.data_->functions)
217 result.data_->functions.push_back(function);
218 return result;
219 }
220
226 static delegate remove(const delegate& source, const delegate& value) noexcept {
227 delegate result = source;
228 std::for_each(value.data_->functions.begin(), value.data_->functions.end(), [&](auto function) {
229 auto iterator = std::find_if(result.data_->functions.rbegin(), result.data_->functions.rend(), [&](auto item) {return are_equals(item, function);});
230 if (iterator != result.data_->functions.rend()) result.data_->functions.erase((iterator + 1).base());
231 });
232 return result;
233 }
234
240 static delegate remove_all(const delegate& source, const delegate& value) noexcept {
241 delegate result = source;
242 for (const function_t& function : value.data_->functions) {
243 if (find(result.data_->functions.begin(), result.data_->functions.end(), function) != result.data_->functions.end()) {
244 for (typename function_collection::reverse_iterator iterator = result.data_->functions.rbegin(); iterator != result.data_->functions.rend(); ++iterator) {
245 if (are_equals(*iterator, function))
246 result.data_->functions.erase((iterator + 1).base());
247 }
248 }
249 }
250 return result;
251 }
253
255
260 result_t operator()() const {
261 if (data_->functions.size() == 0) return result_t();
262
263 for (size_t i = 0; i < data_->functions.size() - 1; i++) {
265 data_->functions[i]();
266 }
268 return data_->functions.back()();
269 }
270
271 delegate& operator =(const function_t& function) noexcept {
272 data_->functions.clear();
273 data_->functions.push_back(function);
274 return *this;
275 }
277
279 delegate operator +(const delegate& other) noexcept {
280 delegate result = *this;
281 result += other;
282 return result;
283 }
284
285 delegate operator +(const function_t& function) noexcept {
286 delegate result = *this;
287 result += function;
288 return result;
289 }
290
291 template<class fn_t>
292 delegate operator +(fn_t function) noexcept {
293 delegate result = *this;
294 result += function;
295 return result;
296 }
297
298 delegate& operator +=(const delegate& delegate) noexcept {
299 *this = delegate::combine(*this, delegate);
300 return *this;
301 }
302
303 delegate& operator +=(const function_t& function) noexcept {
304 *this = delegate::combine(*this, delegate(function));
305 return *this;
306 }
307
308 template<class fn_t>
309 delegate& operator +=(fn_t function) noexcept {
310 *this = delegate::combine(*this, delegate(function));
311 return *this;
312 }
313
314 delegate operator -(const delegate& other) noexcept {
315 delegate result = *this;
316 result -= other;
317 return result;
318 }
319
320 delegate operator -(const function_t& function) noexcept {
321 delegate result = *this;
322 result -= function;
323 return result;
324 }
325
326 template<class fn_t>
327 delegate operator -(fn_t function) noexcept {
328 delegate result = *this;
329 result -= function;
330 return result;
331 }
332
333 delegate& operator -=(const delegate& delegate) noexcept {
334 *this = delegate::remove(*this, delegate);
335 return *this;
336 }
337
338 delegate& operator -=(const function_t& function) noexcept {
339 *this = delegate::remove(*this, delegate(function));
340 return *this;
341 }
342
343 template<class fn_t>
344 delegate& operator -=(fn_t function) noexcept {
345 *this = delegate::remove(*this, delegate(function));
346 return *this;
347 }
349
350 private:
351 static bool are_equals(const std::function<result_t()>& fct1, const std::function<result_t()>& fct2) noexcept {
352 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(*)()>());
353 }
354
355 static typename function_collection::const_iterator find(typename function_collection::const_iterator begin, typename function_collection::const_iterator end, const function_t& function) noexcept {
356 auto iterator = std::find_if(begin, end, [&](auto item) {return are_equals(item, function);});
357 if (iterator != end) return iterator;
358 return end;
359 }
360 xtd::sptr<data> data_ = xtd::new_sptr<data>();
361 };
362
377 template<class result_t, class ...arguments_t>
378 class delegate<result_t(arguments_t...)> : public object, public xtd::iequatable<delegate<result_t(arguments_t...)>> {
379 struct data {
380 std::vector<std::function <result_t()>> no_arguments_functions;
381 std::vector<std::function <result_t(arguments_t...)>> functions;
382 };
383
384 class async_result_invoke : public xtd::iasync_result {
385 struct data;
386 public:
387 async_result_invoke(xtd::async_callback async_callback, const xtd::any_object& async_state);
388 xtd::any_object async_state() const noexcept override;
389 xtd::threading::wait_handle& async_wait_handle() noexcept override;
390 bool completed_synchronously() const noexcept override;
391 bool is_completed() const noexcept override;
392
393 xtd::sptr<data> data_;
394 };
395
396 public:
398
401 using no_arguments_function_t = std::function <result_t()>;
403 using function_t = std::function <result_t(arguments_t...)>;
405 using no_arguments_function_collection = std::vector<no_arguments_function_t>;
407 using function_collection = std::vector<function_t>;
409
411
414 delegate() = default;
416 delegate(delegate&&) = default;
417 delegate(const delegate&) = default;
418 delegate& operator =(const delegate& delegate) = default;
419 delegate(const delegate<result_t()>& delegate) noexcept {data_->no_arguments_functions = delegate.functions();}
421
424 delegate(const function_t& function) noexcept {data_->functions.push_back(function);} // Can't be explicit by design.
425
427 delegate(const no_arguments_function_t& function) noexcept {data_->no_arguments_functions.push_back(function);} // Can't be explicit by design.
429
433 template<class object1_t, class object2_t>
434 delegate(const object1_t& object, result_t(object2_t::*method)() const) noexcept {
435 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object))));
436 }
437
441 template<class object1_t, class object2_t>
442 delegate(const object1_t& object, result_t(object2_t::*method)()) noexcept {
443 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object))));
444 }
446
448 template<class object1_t, class object2_t, class a1_t>
449 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t) const) noexcept {
450 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1)));
451 }
452
453 template<class object1_t, class object2_t, class a1_t>
454 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t)) noexcept {
455 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1)));
456 }
457
458 template<class object1_t, class object2_t, class a1_t, class a2_t>
459 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t) const) noexcept {
460 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2)));
461 }
462
463 template<class object1_t, class object2_t, class a1_t, class a2_t>
464 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t)) noexcept {
465 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2)));
466 }
467
468 template<class object1_t, class object2_t, class a1_t, class a2_t, class a3_t>
469 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t) const) noexcept {
470 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)));
471 }
472
473 template<class object1_t, class object2_t, class a1_t, class a2_t, class a3_t>
474 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t)) noexcept {
475 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)));
476 }
477
478 template<class object1_t, class object2_t, class a1_t, class a2_t, class a3_t, class a4_t>
479 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t) const) {
480 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)));
481 }
482
483 template<class object1_t, class object2_t, class a1_t, class a2_t, class a3_t, class a4_t>
484 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t)) noexcept {
485 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)));
486 }
487
488 template<class object1_t, class object2_t, class a1_t, class a2_t, class a3_t, class a4_t, class A5>
489 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5) const) noexcept {
490 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)));
491 }
492
493 template<class object1_t, class object2_t, class a1_t, class a2_t, class a3_t, class a4_t, class A5>
494 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5)) {
495 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)));
496 }
497
498 template<class object1_t, class object2_t, class a1_t, class a2_t, class a3_t, class a4_t, class A5, class a6_t>
499 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t) const) noexcept {
500 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)));
501 }
502
503 template<class object1_t, class object2_t, class a1_t, class a2_t, class a3_t, class a4_t, class A5, class a6_t>
504 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t)) noexcept {
505 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)));
506 }
507
508 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>
509 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 {
510 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)));
511 }
512
513 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>
514 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t, a7_t)) noexcept {
515 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)));
516 }
517
518 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>
519 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 {
520 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)));
521 }
522
523 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>
524 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 {
525 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)));
526 }
527
528 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>
529 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 {
530 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)));
531 }
532
533 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>
534 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 {
535 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)));
536 }
537
538 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>
539 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 {
540 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)));
541 }
542
543 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>
544 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 {
545 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)));
546 }
548
550
554 const no_arguments_function_collection& no_arguments_functions() const {return data_->no_arguments_functions;}
555
558 const function_collection& functions() const {return data_->functions;}
559
562 bool is_empty() const noexcept {return data_->functions.size() == 0 && data_->no_arguments_functions.size() == 0;}
563
566 size_t size() const noexcept {return data_->functions.size() + data_->no_arguments_functions.size();}
568
570
580 async_result begin_invoke(arguments_t&&... arguments);
595 async_result begin_invoke(xtd::async_callback async_callback, const xtd::any_object& async_state, arguments_t&&... arguments);
596
602 result_t end_invoke(async_result async);
603
610 result_t invoke(arguments_t&&... arguments) const {return operator()(arguments...);}
611
615 bool equals(const object& obj) const noexcept override {return is<delegate>(obj) && equals(static_cast<const delegate&>(obj));}
619 bool equals(const delegate& other) const noexcept override {
620 if (data_->functions.size() != other.data_->functions.size() || data_->no_arguments_functions.size() != other.data_->no_arguments_functions.size())
621 return false;
622
623 for (size_t i = 0; i < data_->no_arguments_functions.size(); i++)
624 if (!are_equals(data_->no_arguments_functions[i], other.data_->no_arguments_functions[i]))
625 return false;
626
627 for (size_t i = 0; i < data_->functions.size(); i++)
628 if (!are_equals(data_->functions[i], other.data_->functions[i]))
629 return false;
630
631 return true;
632 }
634
636
643 static delegate combine(const array<delegate>& delegates) noexcept {
644 delegate result;
645 for (const delegate& delegate : delegates) {
646 for (const no_arguments_function_t& function : delegate.data_->no_arguments_functions)
647 result.data_->no_arguments_functions.push_back(function);
648 for (const function_t& function : delegate.data_->functions)
649 result.data_->functions.push_back(function);
650 }
651 return result;
652 }
653
659 static delegate combine(const delegate& a, const delegate& b) noexcept {
660 delegate result = a;
661 for (const no_arguments_function_t& function : b.data_->no_arguments_functions)
662 result.data_->no_arguments_functions.push_back(function);
663 for (const function_t& function : b.data_->functions)
664 result.data_->functions.push_back(function);
665 return result;
666 }
667
673 static delegate remove(const delegate& source, const delegate& value) noexcept {
674 delegate result = source;
675 std::for_each(value.data_->no_arguments_functions.begin(), value.data_->no_arguments_functions.end(), [&](auto no_arguments_function) {
676 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);});
677 if (iterator != result.data_->no_arguments_functions.rend()) result.data_->no_arguments_functions.erase((iterator + 1).base());
678 });
679
680 std::for_each(value.data_->functions.begin(), value.data_->functions.end(), [&](auto function) {
681 auto iterator = std::find_if(result.data_->functions.rbegin(), result.data_->functions.rend(), [&](auto item) {return are_equals(item, function);});
682 if (iterator != result.data_->functions.rend()) result.data_->functions.erase((iterator + 1).base());
683 });
684 return result;
685 }
686
692 static delegate remove_all(const delegate& source, const delegate& value) noexcept {
693 delegate result = source;
694 for (const no_arguments_function_t& function : value.data_->no_arguments_functions) {
695 if (find(result.data_->no_arguments_functions.begin(), result.data_->no_arguments_functions.end(), function) != result.data_->no_arguments_functions.end()) {
696 for (typename function_collection::reverse_iterator iterator = result.data_->no_arguments_functions.rbegin(); iterator != result.data_->no_arguments_functions.rend(); ++iterator) {
697 if (are_equals(*iterator, function))
698 result.data_->no_arguments_functions.erase((iterator + 1).base());
699 }
700 }
701 }
702
703 for (const function_t& function : value.data_->functions) {
704 if (find(result.data_->functions.begin(), result.data_->functions.end(), function) != result.data_->functions.end()) {
705 for (typename function_collection::reverse_iterator iterator = result.data_->functions.rbegin(); iterator != result.data_->functions.rend(); ++iterator) {
706 if (are_equals(*iterator, function))
707 result.data_->functions.erase((iterator + 1).base());
708 }
709 }
710 }
711 return result;
712 }
714
716
721 result_t operator()(arguments_t... arguments) const {
722 if (data_->no_arguments_functions.size() == 0 && data_->functions.size() == 0) return result_t();
723
724 if (data_->no_arguments_functions.size()) {
725 for (size_t i = 0; i < data_->no_arguments_functions.size() - (data_->functions.size() == 0 ? 1 : 0); i++) {
726 if (data_->no_arguments_functions[i] == nullptr) xtd::helpers::throw_helper::throws(xtd::helpers::exception_case::argument_null);
727 data_->no_arguments_functions[i]();
728 }
729
730 if (data_->functions.size() == 0) {
731 if (data_->no_arguments_functions.back() == nullptr) xtd::helpers::throw_helper::throws(xtd::helpers::exception_case::argument_null);
732 return data_->no_arguments_functions.back()();
733 }
734 }
735
736 for (size_t i = 0; i < data_->functions.size() - 1; i++) {
738 data_->functions[i](arguments...);
739 }
741 return data_->functions.back()(arguments...);
742 }
744
746 template<class type_t>
747 delegate& operator =(const type_t& function) noexcept {
748 data_->no_arguments_functions.clear();
749 data_->functions.clear();
750 data_->functions.push_back(function_t(function));
751 return *this;
752 }
753
754 delegate& operator =(const function_t& function) noexcept {
755 data_->no_arguments_functions.clear();
756 data_->functions.clear();
757 data_->functions.push_back(function);
758 return *this;
759 }
760
761 delegate& operator =(const no_arguments_function_t& function) noexcept {
762 data_->no_arguments_functions.clear();
763 data_->functions.clear();
764 data_->no_arguments_functions.push_back(function);
765 return *this;
766 }
767
768 delegate operator +(const delegate& other) noexcept {
769 delegate result = *this;
770 result += other;
771 return result;
772 }
773
774 delegate operator +(const no_arguments_function_t& function) noexcept {
775 delegate result = *this;
776 result += function;
777 return result;
778 }
779
780 delegate operator +(const function_t& function) noexcept {
781 delegate result = *this;
782 result += function;
783 return result;
784 }
785
786 template<class fn_t>
787 delegate operator +(fn_t function) noexcept {
788 delegate result = *this;
789 result += function;
790 return result;
791 }
792
793 delegate& operator +=(const delegate& delegate) noexcept {
794 *this = delegate::combine(*this, delegate);
795 return *this;
796 }
797
798 delegate& operator +=(const no_arguments_function_t& function) noexcept {
799 *this = delegate::combine(*this, delegate(function));
800 return *this;
801 }
802
803 delegate& operator +=(const function_t& function) noexcept {
804 *this = delegate::combine(*this, delegate(function));
805 return *this;
806 }
807
808 template<class fn_t>
809 delegate& operator +=(fn_t function) noexcept {
810 *this = delegate::combine(*this, delegate(function));
811 return *this;
812 }
813
814 delegate operator -(const delegate& other) noexcept {
815 delegate result = *this;
816 result -= other;
817 return result;
818 }
819
820 delegate operator -(const no_arguments_function_t& function) noexcept {
821 delegate result = *this;
822 result -= function;
823 return result;
824 }
825
826 delegate operator -(const function_t& function) noexcept {
827 delegate result = *this;
828 result -= function;
829 return result;
830 }
831
832 template<class fn_t>
833 delegate operator -(fn_t function) noexcept {
834 delegate result = *this;
835 result -= function;
836 return result;
837 }
838
839 delegate& operator -=(const delegate& delegate) noexcept {
840 *this = delegate::remove(*this, delegate);
841 return *this;
842 }
843
844 delegate& operator -=(const no_arguments_function_t& function) noexcept {
845 *this = delegate::remove(*this, delegate(function));
846 return *this;
847 }
848
849 delegate& operator -=(const function_t& function) noexcept {
850 *this = delegate::remove(*this, delegate(function));
851 return *this;
852 }
853
854 template<class fn_t>
855 delegate& operator -=(fn_t function) noexcept {
856 *this = delegate::remove(*this, delegate(function));
857 return *this;
858 }
860
861 private:
862 static bool are_equals(const std::function<result_t(arguments_t...)>& fct1, const std::function<result_t(arguments_t...)>& fct2) noexcept {
863 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...)>());
864 }
865
866 static bool are_equals(const std::function<result_t()>& fct1, const std::function<result_t()>& fct2) noexcept {
867 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(*)()>());
868 }
869
870 static typename no_arguments_function_collection::const_iterator find(typename no_arguments_function_collection::const_iterator begin, typename no_arguments_function_collection::const_iterator end, const no_arguments_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 static typename function_collection::const_iterator find(typename function_collection::const_iterator begin, typename function_collection::const_iterator end, const function_t& function) noexcept {
877 auto iterator = std::find_if(begin, end, [&](auto item) {return are_equals(item, function);});
878 if (iterator != end) return iterator;
879 return end;
880 }
881
882 xtd::sptr<data> data_ = xtd::new_sptr<data>();
883 };
884}
885
886// 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.
Represent a polymorphic wrapper capable of holding any type.
Definition any_object.hpp:29
Provides methods for creating, manipulating, searching, and sorting arrays, thereby serving as the ba...
Definition array.hpp:61
const function_collection & functions() const
Gets the delegates array.
Definition delegate.hpp:119
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:109
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:240
std::vector< function_t > function_collection
Represents the function collection type.
Definition delegate.hpp:80
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:102
void clear()
Clear delegates array.
Definition delegate.hpp:134
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:180
bool is_empty() const noexcept
Return if the delegate is empty.
Definition delegate.hpp:123
size_t size() const noexcept
Return the size of invocation list.
Definition delegate.hpp:127
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:96
std::function< result_t()> function_t
Represents function type.
Definition delegate.hpp:78
async_result begin_invoke(xtd::async_callback async_callback, const xtd::any_object &async_state)
Executes the method represented by the current delegate asynchronously on the thread that the control...
static delegate combine(const array< delegate > &delegates) noexcept
Concatenates the invocation lists of an array of delegates.
Definition delegate.hpp:200
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:176
static delegate combine(const delegate &a, const delegate &b) noexcept
Concatenates the invocation lists of two delegates.
Definition delegate.hpp:214
result_t invoke() const
invokes the method represented by the current delegate.
Definition delegate.hpp:171
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:226
result_t operator()() const
invokes the method represented by the current delegate.
Definition delegate.hpp:260
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
Represents no arguments function type.
Definition delegate.hpp:401
std::vector< function_t > function_collection
function_t Represents the function collection type.
Definition delegate.hpp:407
async_result begin_invoke(xtd::async_callback async_callback, const xtd::any_object &async_state, arguments_t &&... arguments)
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...
delegate()=default
Initializes an empty delegate.
async_result begin_invoke(arguments_t &&... arguments)
Executes the method represented by the current delegate asynchronously on the thread that the control...
bool equals(const delegate &other) const noexcept override
Determines whether this instance and another specified delegateType object have the same value.
Definition delegate.hpp:619
std::function< result_t(arguments_t...)> function_t
Represents function type.
Definition delegate.hpp:403
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:442
size_t size() const noexcept
Return the size of invocation list.
Definition delegate.hpp:566
std::vector< no_arguments_function_t > no_arguments_function_collection
function_t Represents the no arguments function collection type.
Definition delegate.hpp:405
result_t operator()(arguments_t... arguments) const
invokes the method represented by the current delegate.
Definition delegate.hpp:721
bool is_empty() const noexcept
Return if the delegate is empty.
Definition delegate.hpp:562
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...
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:673
const function_collection & functions() const
Gets the delegates array.
Definition delegate.hpp:558
result_t invoke(arguments_t &&... arguments) const
invokes the method represented by the current delegate.
Definition delegate.hpp:610
static delegate combine(const array< delegate > &delegates) noexcept
Concatenates the invocation lists of an array of delegates.
Definition delegate.hpp:643
static delegate combine(const delegate &a, const delegate &b) noexcept
Concatenates the invocation lists of two delegates.
Definition delegate.hpp:659
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:692
delegate(const function_t &function) noexcept
Initializes a delegate that invokes the specified instance method.
Definition delegate.hpp:424
bool equals(const object &obj) const noexcept override
Determines whether this instance and another specified delegateType object have the same value.
Definition delegate.hpp:615
const no_arguments_function_collection & no_arguments_functions() const
Gets the no arguments delegates array.
Definition delegate.hpp:554
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:434
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:43
The xtd::shared_ptr_object is a shared pointer as std::shared_ptr.
Definition shared_ptr_object.hpp:30
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.
@ 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.