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
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 }
105
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 }
112
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 }
190
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 }
252
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 }
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 }
445
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 }
633
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 }
713
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 }
743
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 struct delegate_async_state;
863
864 static bool are_equals(const std::function < result_t(arguments_t...) > & fct1, const std::function < result_t(arguments_t...) > & fct2) noexcept {
865 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...) > ());
866 }
867
868 static bool are_equals(const std::function < result_t() > & fct1, const std::function < result_t() > & fct2) noexcept {
869 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(*)() > ());
870 }
871
872 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 {
873 auto iterator = std::find_if(begin, end, [&](auto item) {return are_equals(item, function);});
874 if (iterator != end) return iterator;
875 return end;
876 }
877
878 static typename function_collection::const_iterator find(typename function_collection::const_iterator begin, typename function_collection::const_iterator end, const function_t& function) noexcept {
879 auto iterator = std::find_if(begin, end, [&](auto item) {return are_equals(item, function);});
880 if (iterator != end) return iterator;
881 return end;
882 }
883
885 };
886}
887
888// Required for begin_invoke and end_invoke methods implementation.
Contains xtd::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
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
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
std::vector< function_t > function_collection
Represents the function collection type.
Definition delegate.hpp:80
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
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() > function_t
Represents function type.
Definition delegate.hpp:78
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...
const no_arguments_function_collection & no_arguments_functions() const
Gets the no arguments delegates array.
Definition delegate.hpp:554
const function_collection & functions() const
Gets the delegates array.
Definition delegate.hpp:558
delegate(const function_t &function) noexcept
Initializes a delegate that invokes the specified instance method.
Definition delegate.hpp:424
result_t operator()(arguments_t... arguments) const
invokes the method represented by the current delegate.
Definition delegate.hpp:721
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::vector< no_arguments_function_t > no_arguments_function_collection
function_t Represents the no arguments function collection type.
Definition delegate.hpp:405
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...
delegate()=default
Initializes an empty delegate.
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
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
size_t size() const noexcept
Return the size of invocation list.
Definition delegate.hpp:566
std::vector< function_t > function_collection
function_t Represents the function collection type.
Definition delegate.hpp:407
std::function< result_t(arguments_t...) > function_t
Represents function type.
Definition delegate.hpp:403
result_t end_invoke(async_result async)
Retrieves the return value of the asynchronous operation represented by the async_result_invoke passe...
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
std::function< result_t() > no_arguments_function_t
Represents no arguments function type.
Definition delegate.hpp:401
result_t invoke(arguments_t &&... arguments) const
invokes the method represented by the current delegate.
Definition delegate.hpp:610
bool is_empty() const noexcept
Return if the delegate is empty.
Definition delegate.hpp:562
static delegate combine(const array< delegate > &delegates) noexcept
Concatenates the invocation lists of an array of delegates.
Definition delegate.hpp:643
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
async_result begin_invoke(arguments_t &&... arguments)
Executes the method represented by the current delegate asynchronously on the thread that the control...
static delegate combine(const delegate &a, const delegate &b) noexcept
Concatenates the invocation lists of two delegates.
Definition delegate.hpp:659
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
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
object()=default
Create a new instance of the ultimate base class object.
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.
Definition exception_case.hpp:33
xtd::shared_ptr_object< 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
sptr< type_t > new_sptr(args_t &&... args)
xtd::new_sptr operator creates a xtd::sptr object.
Definition new_sptr.hpp:24
bool is(xtd::any value)
Checks if the result of an expression is compatible with a given type.
Definition is.hpp:485
@ other
The operating system is other.
Definition platform_id.hpp:58
@ a
The A key.
Definition console_key.hpp:88
@ i
The I key.
Definition console_key.hpp:104
@ b
The B key.
Definition console_key.hpp:90
@ function
The FUNCTION modifier key.
Definition keys.hpp:480
Contains xtd::iequatable interface.
The xtd namespace contains all fundamental classes to access Hardware, Os, System,...
Definition abstract_object.hpp:8
const_iterator begin() const
Returns an iterator to the beginning.
Definition read_only_span.hpp:183
const_iterator end() const
Returns an iterator to the end.
Definition read_only_span.hpp:213
Contains xtd::object class.
Contains xtd::object_ref alias.
Contains xtd::threading::thread_pool class.