xtd 0.2.0
Loading...
Searching...
No Matches
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) {
262 if constexpr (std::is_void_v < result_t >) return;
263 else if constexpr (std::is_reference_v < result_t >) {
264 using underlying_t = std::remove_reference_t < result_t >;
265 if constexpr (std::is_const_v < underlying_t >) {
266 static const underlying_t empty_value{};
267 return empty_value;
268 } else {
269 static underlying_t empty_value{};
270 return empty_value;
271 }
272 } else return result_t{};
273 }
274
275 for (size_t i = 0; i < data_->functions.size() - 1; i++) {
277 data_->functions[i]();
278 }
280 return data_->functions.back()();
281 }
282
283 delegate& operator =(const function_t& function) noexcept {
284 data_->functions.clear();
285 data_->functions.push_back(function);
286 return *this;
287 }
289
291 delegate operator +(const delegate& other) noexcept {
292 delegate result = *this;
293 result += other;
294 return result;
295 }
296
297 delegate operator +(const function_t& function) noexcept {
298 delegate result = *this;
299 result += function;
300 return result;
301 }
302
303 template < class fn_t >
304 delegate operator +(fn_t function) noexcept {
305 delegate result = *this;
306 result += function;
307 return result;
308 }
309
310 delegate & operator +=(const delegate& delegate) noexcept {
311 *this = delegate::combine(*this, delegate);
312 return *this;
313 }
314
315 delegate & operator +=(const function_t& function) noexcept {
316 *this = delegate::combine(*this, delegate(function));
317 return *this;
318 }
319
320 template < class fn_t >
321 delegate & operator +=(fn_t function) noexcept {
322 *this = delegate::combine(*this, delegate(function));
323 return *this;
324 }
325
326 delegate operator -(const delegate& other) noexcept {
327 delegate result = *this;
328 result -= other;
329 return result;
330 }
331
332 delegate operator -(const function_t& function) noexcept {
333 delegate result = *this;
334 result -= function;
335 return result;
336 }
337
338 template < class fn_t >
339 delegate operator -(fn_t function) noexcept {
340 delegate result = *this;
341 result -= function;
342 return result;
343 }
344
345 delegate & operator -=(const delegate& delegate) noexcept {
346 *this = delegate::remove(*this, delegate);
347 return *this;
348 }
349
350 delegate & operator -=(const function_t& function) noexcept {
351 *this = delegate::remove(*this, delegate(function));
352 return *this;
353 }
354
355 template < class fn_t >
356 delegate & operator -=(fn_t function) noexcept {
357 *this = delegate::remove(*this, delegate(function));
358 return *this;
359 }
361
362 private:
363 static bool are_equals(const std::function < result_t() > & fct1, const std::function < result_t() > & fct2) noexcept {
364 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(*)() > ());
365 }
366
367 static typename function_collection::const_iterator find(typename function_collection::const_iterator begin, typename function_collection::const_iterator end, const function_t& function) noexcept {
368 auto iterator = std::find_if(begin, end, [&](auto item) {return are_equals(item, function);});
369 if (iterator != end) return iterator;
370 return end;
371 }
373 };
374
389 template < class result_t, class ...arguments_t >
390 class delegate < result_t(arguments_t...) > : public object, public xtd::iequatable < delegate<result_t(arguments_t...) >> {
391 struct data {
392 std::vector < std::function < result_t()>> no_arguments_functions;
393 std::vector < std::function < result_t(arguments_t...)>> functions;
394 };
395
396 class async_result_invoke : public xtd::iasync_result {
397 struct data;
398 public:
399 async_result_invoke(xtd::async_callback async_callback, const xtd::any_object & async_state);
400 xtd::any_object async_state() const noexcept override;
401 xtd::threading::wait_handle & async_wait_handle() noexcept override;
402 bool completed_synchronously() const noexcept override;
403 bool is_completed() const noexcept override;
404
405 xtd::sptr < data > data_;
406 };
407
408 public:
410
413 using no_arguments_function_t = std::function < result_t() >;
415 using function_t = std::function < result_t(arguments_t...) >;
417 using no_arguments_function_collection = std::vector < no_arguments_function_t >;
419 using function_collection = std::vector < function_t >;
421
423
426 delegate() = default;
428 delegate(delegate&&) = default;
429 delegate(const delegate&) = default;
430 delegate& operator =(const delegate & delegate) = default;
431 delegate(const delegate < result_t() > & delegate) noexcept {data_->no_arguments_functions = delegate.functions();}
433
436 delegate(const function_t& function) noexcept {data_->functions.push_back(function);} // Can't be explicit by design.
437
439 delegate(const no_arguments_function_t& function) noexcept {data_->no_arguments_functions.push_back(function);} // Can't be explicit by design.
441
445 template < class object1_t, class object2_t >
446 delegate(const object1_t& object, result_t(object2_t::*method)() const) noexcept {
447 data_->functions.push_back(function_t(std::bind(method, const_cast < object1_t* > (&object))));
448 }
449
453 template < class object1_t, class object2_t >
454 delegate(const object1_t& object, result_t(object2_t::*method)()) noexcept {
455 data_->functions.push_back(function_t(std::bind(method, const_cast < object1_t* > (&object))));
456 }
457
458
460 template < class object1_t, class object2_t, class a1_t >
461 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t) const) noexcept {
462 data_->functions.push_back(function_t(std::bind(method, const_cast < object1_t* > (&object), std::placeholders::_1)));
463 }
464
465 template < class object1_t, class object2_t, class a1_t >
466 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t)) noexcept {
467 data_->functions.push_back(function_t(std::bind(method, const_cast < object1_t* > (&object), std::placeholders::_1)));
468 }
469
470 template < class object1_t, class object2_t, class a1_t, class a2_t >
471 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t) const) noexcept {
472 data_->functions.push_back(function_t(std::bind(method, const_cast < object1_t* > (&object), std::placeholders::_1, std::placeholders::_2)));
473 }
474
475 template < class object1_t, class object2_t, class a1_t, class a2_t >
476 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t)) noexcept {
477 data_->functions.push_back(function_t(std::bind(method, const_cast < object1_t* > (&object), std::placeholders::_1, std::placeholders::_2)));
478 }
479
480 template < class object1_t, class object2_t, class a1_t, class a2_t, class a3_t >
481 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t) const) noexcept {
482 data_->functions.push_back(function_t(std::bind(method, const_cast < object1_t* > (&object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)));
483 }
484
485 template < class object1_t, class object2_t, class a1_t, class a2_t, class a3_t >
486 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t)) noexcept {
487 data_->functions.push_back(function_t(std::bind(method, const_cast < object1_t* > (&object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)));
488 }
489
490 template < class object1_t, class object2_t, class a1_t, class a2_t, class a3_t, class a4_t >
491 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t) const) {
492 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)));
493 }
494
495 template < class object1_t, class object2_t, class a1_t, class a2_t, class a3_t, class a4_t >
496 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t)) noexcept {
497 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)));
498 }
499
500 template < class object1_t, class object2_t, class a1_t, class a2_t, class a3_t, class a4_t, class A5 >
501 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5) const) noexcept {
502 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)));
503 }
504
505 template < class object1_t, class object2_t, class a1_t, class a2_t, class a3_t, class a4_t, class A5 >
506 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5)) {
507 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)));
508 }
509
510 template < class object1_t, class object2_t, class a1_t, class a2_t, class a3_t, class a4_t, class A5, class a6_t >
511 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t) const) noexcept {
512 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)));
513 }
514
515 template < class object1_t, class object2_t, class a1_t, class a2_t, class a3_t, class a4_t, class A5, class a6_t >
516 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t)) noexcept {
517 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)));
518 }
519
520 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 >
521 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 {
522 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)));
523 }
524
525 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 >
526 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t, a7_t)) noexcept {
527 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)));
528 }
529
530 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 >
531 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 {
532 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)));
533 }
534
535 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 >
536 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 {
537 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)));
538 }
539
540 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 >
541 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 {
542 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)));
543 }
544
545 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 >
546 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 {
547 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)));
548 }
549
550 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 >
551 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 {
552 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)));
553 }
554
555 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 >
556 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 {
557 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)));
558 }
560
562
566 const no_arguments_function_collection & no_arguments_functions() const {return data_->no_arguments_functions;}
567
570 const function_collection & functions() const {return data_->functions;}
571
574 bool is_empty() const noexcept {return data_->functions.size() == 0 && data_->no_arguments_functions.size() == 0;}
575
578 size_t size() const noexcept {return data_->functions.size() + data_->no_arguments_functions.size();}
580
582
592 async_result begin_invoke(arguments_t&&... arguments);
607 async_result begin_invoke(xtd::async_callback async_callback, const xtd::any_object & async_state, arguments_t&&... arguments);
608
614 result_t end_invoke(async_result async);
615
622 result_t invoke(arguments_t&&... arguments) const {return operator()(arguments...);}
623
627 bool equals(const object & obj) const noexcept override {return is < delegate > (obj) && equals(static_cast < const delegate& > (obj));}
631 bool equals(const delegate & other) const noexcept override {
632 if (data_->functions.size() != other.data_->functions.size() || data_->no_arguments_functions.size() != other.data_->no_arguments_functions.size())
633 return false;
634
635 for (size_t i = 0; i < data_->no_arguments_functions.size(); i++)
636 if (!are_equals(data_->no_arguments_functions[i], other.data_->no_arguments_functions[i]))
637 return false;
638
639 for (size_t i = 0; i < data_->functions.size(); i++)
640 if (!are_equals(data_->functions[i], other.data_->functions[i]))
641 return false;
642
643 return true;
644 }
645
646
648
655 static delegate combine(const array < delegate > & delegates) noexcept {
656 delegate result;
657 for (const delegate& delegate : delegates) {
658 for (const no_arguments_function_t& function : delegate.data_->no_arguments_functions)
659 result.data_->no_arguments_functions.push_back(function);
660 for (const function_t& function : delegate.data_->functions)
661 result.data_->functions.push_back(function);
662 }
663 return result;
664 }
665
671 static delegate combine(const delegate & a, const delegate & b) noexcept {
672 delegate result = a;
673 for (const no_arguments_function_t& function : b.data_->no_arguments_functions)
674 result.data_->no_arguments_functions.push_back(function);
675 for (const function_t& function : b.data_->functions)
676 result.data_->functions.push_back(function);
677 return result;
678 }
679
685 static delegate remove(const delegate & source, const delegate & value) noexcept {
686 delegate result = source;
687 std::for_each(value.data_->no_arguments_functions.begin(), value.data_->no_arguments_functions.end(), [&](auto no_arguments_function) {
688 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);});
689 if (iterator != result.data_->no_arguments_functions.rend()) result.data_->no_arguments_functions.erase((iterator + 1).base());
690 });
691
692 std::for_each(value.data_->functions.begin(), value.data_->functions.end(), [&](auto function) {
693 auto iterator = std::find_if(result.data_->functions.rbegin(), result.data_->functions.rend(), [&](auto item) {return are_equals(item, function);});
694 if (iterator != result.data_->functions.rend()) result.data_->functions.erase((iterator + 1).base());
695 });
696 return result;
697 }
698
704 static delegate remove_all(const delegate & source, const delegate & value) noexcept {
705 delegate result = source;
706 for (const no_arguments_function_t& function : value.data_->no_arguments_functions) {
707 if (find(result.data_->no_arguments_functions.begin(), result.data_->no_arguments_functions.end(), function) != result.data_->no_arguments_functions.end()) {
708 for (typename function_collection::reverse_iterator iterator = result.data_->no_arguments_functions.rbegin(); iterator != result.data_->no_arguments_functions.rend(); ++iterator) {
709 if (are_equals(*iterator, function))
710 result.data_->no_arguments_functions.erase((iterator + 1).base());
711 }
712 }
713 }
714
715 for (const function_t& function : value.data_->functions) {
716 if (find(result.data_->functions.begin(), result.data_->functions.end(), function) != result.data_->functions.end()) {
717 for (typename function_collection::reverse_iterator iterator = result.data_->functions.rbegin(); iterator != result.data_->functions.rend(); ++iterator) {
718 if (are_equals(*iterator, function))
719 result.data_->functions.erase((iterator + 1).base());
720 }
721 }
722 }
723 return result;
724 }
725
726
728
733 result_t operator()(arguments_t... arguments) const {
734 if (data_->no_arguments_functions.size() == 0 && data_->functions.size() == 0) {
735 if constexpr (std::is_void_v < result_t >) return;
736 else if constexpr (std::is_reference_v < result_t >) {
737 using underlying_t = std::remove_reference_t < result_t >;
738 if constexpr (std::is_const_v < underlying_t >) {
739 static const underlying_t empty_value{};
740 return empty_value;
741 } else {
742 static underlying_t empty_value{};
743 return empty_value;
744 }
745 } else return result_t{};
746 }
747
748 if (data_->no_arguments_functions.size()) {
749 for (size_t i = 0; i < data_->no_arguments_functions.size() - (data_->functions.size() == 0 ? 1 : 0); i++) {
750 if (data_->no_arguments_functions[i] == nullptr) xtd::helpers::throw_helper::throws(xtd::helpers::exception_case::argument_null);
751 data_->no_arguments_functions[i]();
752 }
753
754 if (data_->functions.size() == 0) {
755 if (data_->no_arguments_functions.back() == nullptr) xtd::helpers::throw_helper::throws(xtd::helpers::exception_case::argument_null);
756 return data_->no_arguments_functions.back()();
757 }
758 }
759
760 for (size_t i = 0; i < data_->functions.size() - 1; i++) {
762 data_->functions[i](arguments...);
763 }
765 return data_->functions.back()(arguments...);
766 }
767
768
770 template < class type_t >
771 delegate& operator =(const type_t& function) noexcept {
772 data_->no_arguments_functions.clear();
773 data_->functions.clear();
774 data_->functions.push_back(function_t(function));
775 return *this;
776 }
777
778 delegate& operator =(const function_t& function) noexcept {
779 data_->no_arguments_functions.clear();
780 data_->functions.clear();
781 data_->functions.push_back(function);
782 return *this;
783 }
784
785 delegate& operator =(const no_arguments_function_t& function) noexcept {
786 data_->no_arguments_functions.clear();
787 data_->functions.clear();
788 data_->no_arguments_functions.push_back(function);
789 return *this;
790 }
791
792 delegate operator +(const delegate & other) noexcept {
793 delegate result = *this;
794 result += other;
795 return result;
796 }
797
798 delegate operator +(const no_arguments_function_t& function) noexcept {
799 delegate result = *this;
800 result += function;
801 return result;
802 }
803
804 delegate operator +(const function_t& function) noexcept {
805 delegate result = *this;
806 result += function;
807 return result;
808 }
809
810 template < class fn_t >
811 delegate operator +(fn_t function) noexcept {
812 delegate result = *this;
813 result += function;
814 return result;
815 }
816
817 delegate & operator +=(const delegate & delegate) noexcept {
818 *this = delegate::combine(*this, delegate);
819 return *this;
820 }
821
822 delegate & operator +=(const no_arguments_function_t& function) noexcept {
823 *this = delegate::combine(*this, delegate(function));
824 return *this;
825 }
826
827 delegate & operator +=(const function_t& function) noexcept {
828 *this = delegate::combine(*this, delegate(function));
829 return *this;
830 }
831
832 template < class fn_t >
833 delegate & operator +=(fn_t function) noexcept {
834 *this = delegate::combine(*this, delegate(function));
835 return *this;
836 }
837
838 delegate operator -(const delegate & other) noexcept {
839 delegate result = *this;
840 result -= other;
841 return result;
842 }
843
844 delegate operator -(const no_arguments_function_t& function) noexcept {
845 delegate result = *this;
846 result -= function;
847 return result;
848 }
849
850 delegate operator -(const function_t& function) noexcept {
851 delegate result = *this;
852 result -= function;
853 return result;
854 }
855
856 template < class fn_t >
857 delegate operator -(fn_t function) noexcept {
858 delegate result = *this;
859 result -= function;
860 return result;
861 }
862
863 delegate & operator -=(const delegate & delegate) noexcept {
864 *this = delegate::remove(*this, delegate);
865 return *this;
866 }
867
868 delegate & operator -=(const no_arguments_function_t& function) noexcept {
869 *this = delegate::remove(*this, delegate(function));
870 return *this;
871 }
872
873 delegate & operator -=(const function_t& function) noexcept {
874 *this = delegate::remove(*this, delegate(function));
875 return *this;
876 }
877
878 template < class fn_t >
879 delegate & operator -=(fn_t function) noexcept {
880 *this = delegate::remove(*this, delegate(function));
881 return *this;
882 }
884
885 private:
886 struct delegate_async_state;
887
888 static bool are_equals(const std::function < result_t(arguments_t...) > & fct1, const std::function < result_t(arguments_t...) > & fct2) noexcept {
889 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...) > ());
890 }
891
892 static bool are_equals(const std::function < result_t() > & fct1, const std::function < result_t() > & fct2) noexcept {
893 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(*)() > ());
894 }
895
896 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 {
897 auto iterator = std::find_if(begin, end, [&](auto item) {return are_equals(item, function);});
898 if (iterator != end) return iterator;
899 return end;
900 }
901
902 static typename function_collection::const_iterator find(typename function_collection::const_iterator begin, typename function_collection::const_iterator end, const function_t& function) noexcept {
903 auto iterator = std::find_if(begin, end, [&](auto item) {return are_equals(item, function);});
904 if (iterator != end) return iterator;
905 return end;
906 }
907
909 };
910}
911
924#define delegate_ \
925 [&]
926
927// 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:566
const function_collection & functions() const
Gets the delegates array.
Definition delegate.hpp:570
delegate(const function_t &function) noexcept
Initializes a delegate that invokes the specified instance method.
Definition delegate.hpp:436
result_t operator()(arguments_t... arguments) const
invokes the method represented by the current delegate.
Definition delegate.hpp:733
bool equals(const delegate &other) const noexcept override
Determines whether this instance and another specified delegateType object have the same value.
Definition delegate.hpp:631
std::vector< no_arguments_function_t > no_arguments_function_collection
function_t Represents the no arguments function collection type.
Definition delegate.hpp:417
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:685
bool equals(const object &obj) const noexcept override
Determines whether this instance and another specified delegateType object have the same value.
Definition delegate.hpp:627
size_t size() const noexcept
Return the size of invocation list.
Definition delegate.hpp:578
std::vector< function_t > function_collection
function_t Represents the function collection type.
Definition delegate.hpp:419
std::function< result_t(arguments_t...) > function_t
Represents function type.
Definition delegate.hpp:415
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:446
std::function< result_t() > no_arguments_function_t
Represents no arguments function type.
Definition delegate.hpp:413
result_t invoke(arguments_t &&... arguments) const
invokes the method represented by the current delegate.
Definition delegate.hpp:622
bool is_empty() const noexcept
Return if the delegate is empty.
Definition delegate.hpp:574
static delegate combine(const array< delegate > &delegates) noexcept
Concatenates the invocation lists of an array of delegates.
Definition delegate.hpp:655
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:704
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:671
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:454
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:60
@ 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.