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 size_t count() const noexcept {return data_->functions.size();}
120
123 const function_collection& functions() const {return data_->functions;}
124
127 bool is_empty() const noexcept {return count() == 0;}
128
131 size_t size() const noexcept {return count();}
133
135
138 void clear() {data_->functions.clear();}
139
161
167 result_t end_invoke(async_result async);
168
175 result_t invoke() const {return operator()();}
176
180 bool equals(const object& obj) const noexcept override {return is < delegate > (obj) && equals(static_cast < const delegate& > (obj));}
184 bool equals(const delegate& other) const noexcept override {
185 if (data_->functions.size() != other.data_->functions.size())
186 return false;
187
188 for (size_t i = 0; i < data_->functions.size(); i++)
189 if (!are_equals(data_->functions[i], other.data_->functions[i]))
190 return false;
191
192 return true;
193 }
194
195
197
204 static delegate combine(const array < delegate >& delegates) noexcept {
205 delegate result;
206 for (const delegate& delegate : delegates) {
207 for (const function_t& function : delegate.data_->functions)
208 result.data_->functions.push_back(function);
209 }
210 return result;
211 }
212
218 static delegate combine(const delegate& a, const delegate& b) noexcept {
219 delegate result = a;
220 for (const function_t& function : b.data_->functions)
221 result.data_->functions.push_back(function);
222 return result;
223 }
224
230 static delegate remove(const delegate& source, const delegate& value) noexcept {
231 delegate result = source;
232 std::for_each(value.data_->functions.begin(), value.data_->functions.end(), [&](auto function) {
233 auto iterator = std::find_if(result.data_->functions.rbegin(), result.data_->functions.rend(), [&](auto item) {return are_equals(item, function);});
234 if (iterator != result.data_->functions.rend()) result.data_->functions.erase((iterator + 1).base());
235 });
236 return result;
237 }
238
244 static delegate remove_all(const delegate& source, const delegate& value) noexcept {
245 delegate result = source;
246 for (const function_t& function : value.data_->functions) {
247 if (find(result.data_->functions.begin(), result.data_->functions.end(), function) != result.data_->functions.end()) {
248 for (typename function_collection::reverse_iterator iterator = result.data_->functions.rbegin(); iterator != result.data_->functions.rend(); ++iterator) {
249 if (are_equals(*iterator, function))
250 result.data_->functions.erase((iterator + 1).base());
251 }
252 }
253 }
254 return result;
255 }
256
257
259
264 result_t operator()() const {
265 if (data_->functions.size() == 0) {
266 if constexpr(std::is_void_v < result_t >) return;
267 else if constexpr(std::is_reference_v < result_t >) {
268 using underlying_t = std::remove_reference_t < result_t >;
269 if constexpr(std::is_const_v < underlying_t >) {
270 static const underlying_t empty_value{};
271 return empty_value;
272 } else {
273 static underlying_t empty_value{};
274 return empty_value;
275 }
276 } else return result_t{};
277 }
278
279 for (size_t i = 0; i < data_->functions.size() - 1; i++) {
281 data_->functions[i]();
282 }
284 return data_->functions.back()();
285 }
286
287 delegate& operator =(const function_t& function) noexcept {
288 data_->functions.clear();
289 data_->functions.push_back(function);
290 return *this;
291 }
293
295 delegate operator +(const delegate& other) noexcept {
296 delegate result = *this;
297 result += other;
298 return result;
299 }
300
301 delegate operator +(const function_t& function) noexcept {
302 delegate result = *this;
303 result += function;
304 return result;
305 }
306
307 template < class fn_t >
308 delegate operator +(fn_t function) noexcept {
309 delegate result = *this;
310 result += function;
311 return result;
312 }
313
314 delegate& operator +=(const delegate& delegate) noexcept {
315 *this = delegate::combine(*this, delegate);
316 return *this;
317 }
318
319 delegate& operator +=(const function_t& function) noexcept {
320 *this = delegate::combine(*this, delegate(function));
321 return *this;
322 }
323
324 template < class fn_t >
325 delegate& operator +=(fn_t function) noexcept {
326 *this = delegate::combine(*this, delegate(function));
327 return *this;
328 }
329
330 delegate operator -(const delegate& other) noexcept {
331 delegate result = *this;
332 result -= other;
333 return result;
334 }
335
336 delegate operator -(const function_t& function) noexcept {
337 delegate result = *this;
338 result -= function;
339 return result;
340 }
341
342 template < class fn_t >
343 delegate operator -(fn_t function) noexcept {
344 delegate result = *this;
345 result -= function;
346 return result;
347 }
348
349 delegate& operator -=(const delegate& delegate) noexcept {
350 *this = delegate::remove(*this, delegate);
351 return *this;
352 }
353
354 delegate& operator -=(const function_t& function) noexcept {
355 *this = delegate::remove(*this, delegate(function));
356 return *this;
357 }
358
359 template < class fn_t >
360 delegate& operator -=(fn_t function) noexcept {
361 *this = delegate::remove(*this, delegate(function));
362 return *this;
363 }
365
366 private:
367 static bool are_equals(const std::function < result_t() >& fct1, const std::function < result_t() >& fct2) noexcept {
368 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(*)() > ());
369 }
370
371 static typename function_collection::const_iterator find(typename function_collection::const_iterator begin, typename function_collection::const_iterator end, const function_t& function) noexcept {
372 auto iterator = std::find_if(begin, end, [&](auto item) {return are_equals(item, function);});
373 if (iterator != end) return iterator;
374 return end;
375 }
377 };
378
393 template < class result_t, class ...arguments_t >
394 class delegate < result_t(arguments_t...) > : public object, public xtd::iequatable < delegate<result_t(arguments_t...) >> {
395 struct data {
396 std::vector < std::function < result_t()>> no_arguments_functions;
397 std::vector < std::function < result_t(arguments_t...)>> functions;
398 };
399
400 class async_result_invoke : public xtd::iasync_result {
401 struct data;
402 public:
403 async_result_invoke(xtd::async_callback async_callback, const xtd::any_object & async_state);
404 xtd::any_object async_state() const noexcept override;
405 xtd::threading::wait_handle& async_wait_handle() noexcept override;
406 bool completed_synchronously() const noexcept override;
407 bool is_completed() const noexcept override;
408
409 xtd::sptr < data > data_;
410 };
411
412 public:
414
417 using no_arguments_function_t = std::function < result_t() >;
419 using function_t = std::function < result_t(arguments_t...) >;
421 using no_arguments_function_collection = std::vector < no_arguments_function_t >;
423 using function_collection = std::vector < function_t >;
425
427
430 delegate() = default;
432 delegate(delegate&&) = default;
433 delegate(const delegate&) = default;
434 delegate& operator =(const delegate & delegate) = default;
435 delegate(const delegate < result_t() >& delegate) noexcept {data_->no_arguments_functions = delegate.functions();}
437
440 delegate(const function_t& function) noexcept {data_->functions.push_back(function);} // Can't be explicit by design.
441
443 delegate(const no_arguments_function_t& function) noexcept {data_->no_arguments_functions.push_back(function);} // Can't be explicit by design.
445
449 template < class object1_t, class object2_t >
450 delegate(const object1_t& object, result_t(object2_t::*method)() const) noexcept {
451 data_->functions.push_back(function_t(std::bind(method, const_cast < object1_t* > (&object))));
452 }
453
457 template < class object1_t, class object2_t >
458 delegate(const object1_t& object, result_t(object2_t::*method)()) noexcept {
459 data_->functions.push_back(function_t(std::bind(method, const_cast < object1_t* > (&object))));
460 }
461
462
464 template < class object1_t, class object2_t, class a1_t >
465 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t) const) noexcept {
466 data_->functions.push_back(function_t(std::bind(method, const_cast < object1_t* > (&object), std::placeholders::_1)));
467 }
468
469 template < class object1_t, class object2_t, class a1_t >
470 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t)) noexcept {
471 data_->functions.push_back(function_t(std::bind(method, const_cast < object1_t* > (&object), std::placeholders::_1)));
472 }
473
474 template < class object1_t, class object2_t, class a1_t, class a2_t >
475 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t) const) noexcept {
476 data_->functions.push_back(function_t(std::bind(method, const_cast < object1_t* > (&object), std::placeholders::_1, std::placeholders::_2)));
477 }
478
479 template < class object1_t, class object2_t, class a1_t, class a2_t >
480 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t)) noexcept {
481 data_->functions.push_back(function_t(std::bind(method, const_cast < object1_t* > (&object), std::placeholders::_1, std::placeholders::_2)));
482 }
483
484 template < class object1_t, class object2_t, class a1_t, class a2_t, class a3_t >
485 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t) const) noexcept {
486 data_->functions.push_back(function_t(std::bind(method, const_cast < object1_t* > (&object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)));
487 }
488
489 template < class object1_t, class object2_t, class a1_t, class a2_t, class a3_t >
490 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t)) noexcept {
491 data_->functions.push_back(function_t(std::bind(method, const_cast < object1_t* > (&object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)));
492 }
493
494 template < class object1_t, class object2_t, class a1_t, class a2_t, class a3_t, class a4_t >
495 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t) const) {
496 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)));
497 }
498
499 template < class object1_t, class object2_t, class a1_t, class a2_t, class a3_t, class a4_t >
500 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t)) noexcept {
501 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)));
502 }
503
504 template < class object1_t, class object2_t, class a1_t, class a2_t, class a3_t, class a4_t, class A5 >
505 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5) const) noexcept {
506 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)));
507 }
508
509 template < class object1_t, class object2_t, class a1_t, class a2_t, class a3_t, class a4_t, class A5 >
510 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5)) {
511 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)));
512 }
513
514 template < class object1_t, class object2_t, class a1_t, class a2_t, class a3_t, class a4_t, class A5, class a6_t >
515 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t) const) noexcept {
516 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)));
517 }
518
519 template < class object1_t, class object2_t, class a1_t, class a2_t, class a3_t, class a4_t, class A5, class a6_t >
520 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t)) noexcept {
521 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)));
522 }
523
524 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 >
525 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 {
526 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)));
527 }
528
529 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 >
530 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t, a7_t)) noexcept {
531 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)));
532 }
533
534 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 >
535 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 {
536 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)));
537 }
538
539 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 >
540 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 {
541 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)));
542 }
543
544 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 >
545 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 {
546 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)));
547 }
548
549 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 >
550 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 {
551 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)));
552 }
553
554 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 >
555 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 {
556 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)));
557 }
558
559 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 >
560 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 {
561 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)));
562 }
564
566
570 size_t count() const noexcept {return data_->functions.size() + data_->no_arguments_functions.size();}
571
574 const no_arguments_function_collection& no_arguments_functions() const {return data_->no_arguments_functions;}
575
578 const function_collection& functions() const {return data_->functions;}
579
582 bool is_empty() const noexcept {return count() == 0;}
583
586 size_t size() const noexcept {return count();}
588
590
600 async_result begin_invoke(arguments_t&&... arguments);
615 async_result begin_invoke(xtd::async_callback async_callback, const xtd::any_object & async_state, arguments_t&&... arguments);
616
622 result_t end_invoke(async_result async);
623
630 result_t invoke(arguments_t&&... arguments) const {return operator()(arguments...);}
631
635 bool equals(const object & obj) const noexcept override {return is < delegate > (obj) && equals(static_cast < const delegate& > (obj));}
639 bool equals(const delegate & other) const noexcept override {
640 if (data_->functions.size() != other.data_->functions.size() || data_->no_arguments_functions.size() != other.data_->no_arguments_functions.size())
641 return false;
642
643 for (size_t i = 0; i < data_->no_arguments_functions.size(); i++)
644 if (!are_equals(data_->no_arguments_functions[i], other.data_->no_arguments_functions[i]))
645 return false;
646
647 for (size_t i = 0; i < data_->functions.size(); i++)
648 if (!are_equals(data_->functions[i], other.data_->functions[i]))
649 return false;
650
651 return true;
652 }
653
654
656
663 static delegate combine(const array < delegate >& delegates) noexcept {
664 delegate result;
665 for (const delegate& delegate : delegates) {
666 for (const no_arguments_function_t& function : delegate.data_->no_arguments_functions)
667 result.data_->no_arguments_functions.push_back(function);
668 for (const function_t& function : delegate.data_->functions)
669 result.data_->functions.push_back(function);
670 }
671 return result;
672 }
673
679 static delegate combine(const delegate & a, const delegate & b) noexcept {
680 delegate result = a;
681 for (const no_arguments_function_t& function : b.data_->no_arguments_functions)
682 result.data_->no_arguments_functions.push_back(function);
683 for (const function_t& function : b.data_->functions)
684 result.data_->functions.push_back(function);
685 return result;
686 }
687
693 static delegate remove(const delegate & source, const delegate & value) noexcept {
694 delegate result = source;
695 std::for_each(value.data_->no_arguments_functions.begin(), value.data_->no_arguments_functions.end(), [&](auto no_arguments_function) {
696 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);});
697 if (iterator != result.data_->no_arguments_functions.rend()) result.data_->no_arguments_functions.erase((iterator + 1).base());
698 });
699
700 std::for_each(value.data_->functions.begin(), value.data_->functions.end(), [&](auto function) {
701 auto iterator = std::find_if(result.data_->functions.rbegin(), result.data_->functions.rend(), [&](auto item) {return are_equals(item, function);});
702 if (iterator != result.data_->functions.rend()) result.data_->functions.erase((iterator + 1).base());
703 });
704 return result;
705 }
706
712 static delegate remove_all(const delegate & source, const delegate & value) noexcept {
713 delegate result = source;
714 for (const no_arguments_function_t& function : value.data_->no_arguments_functions) {
715 if (find(result.data_->no_arguments_functions.begin(), result.data_->no_arguments_functions.end(), function) != result.data_->no_arguments_functions.end()) {
716 for (typename function_collection::reverse_iterator iterator = result.data_->no_arguments_functions.rbegin(); iterator != result.data_->no_arguments_functions.rend(); ++iterator) {
717 if (are_equals(*iterator, function))
718 result.data_->no_arguments_functions.erase((iterator + 1).base());
719 }
720 }
721 }
722
723 for (const function_t& function : value.data_->functions) {
724 if (find(result.data_->functions.begin(), result.data_->functions.end(), function) != result.data_->functions.end()) {
725 for (typename function_collection::reverse_iterator iterator = result.data_->functions.rbegin(); iterator != result.data_->functions.rend(); ++iterator) {
726 if (are_equals(*iterator, function))
727 result.data_->functions.erase((iterator + 1).base());
728 }
729 }
730 }
731 return result;
732 }
733
734
736
741 result_t operator()(arguments_t... arguments) const {
742 if (data_->no_arguments_functions.size() == 0 && data_->functions.size() == 0) {
743 if constexpr(std::is_void_v < result_t >) return;
744 else if constexpr(std::is_reference_v < result_t >) {
745 using underlying_t = std::remove_reference_t < result_t >;
746 if constexpr(std::is_const_v < underlying_t >) {
747 static const underlying_t empty_value{};
748 return empty_value;
749 } else {
750 static underlying_t empty_value{};
751 return empty_value;
752 }
753 } else return result_t{};
754 }
755
756 if (data_->no_arguments_functions.size()) {
757 for (size_t i = 0; i < data_->no_arguments_functions.size() - (data_->functions.size() == 0 ? 1 : 0); i++) {
758 if (data_->no_arguments_functions[i] == nullptr) xtd::helpers::throw_helper::throws(xtd::helpers::exception_case::argument_null);
759 data_->no_arguments_functions[i]();
760 }
761
762 if (data_->functions.size() == 0) {
763 if (data_->no_arguments_functions.back() == nullptr) xtd::helpers::throw_helper::throws(xtd::helpers::exception_case::argument_null);
764 return data_->no_arguments_functions.back()();
765 }
766 }
767
768 for (size_t i = 0; i < data_->functions.size() - 1; i++) {
770 data_->functions[i](arguments...);
771 }
773 return data_->functions.back()(arguments...);
774 }
775
776
778 template < class type_t >
779 delegate& operator =(const type_t& function) noexcept {
780 data_->no_arguments_functions.clear();
781 data_->functions.clear();
782 data_->functions.push_back(function_t(function));
783 return *this;
784 }
785
786 delegate& operator =(const function_t& function) noexcept {
787 data_->no_arguments_functions.clear();
788 data_->functions.clear();
789 data_->functions.push_back(function);
790 return *this;
791 }
792
793 delegate& operator =(const no_arguments_function_t& function) noexcept {
794 data_->no_arguments_functions.clear();
795 data_->functions.clear();
796 data_->no_arguments_functions.push_back(function);
797 return *this;
798 }
799
800 delegate operator +(const delegate & other) noexcept {
801 delegate result = *this;
802 result += other;
803 return result;
804 }
805
806 delegate operator +(const no_arguments_function_t& function) noexcept {
807 delegate result = *this;
808 result += function;
809 return result;
810 }
811
812 delegate operator +(const function_t& function) noexcept {
813 delegate result = *this;
814 result += function;
815 return result;
816 }
817
818 template < class fn_t >
819 delegate operator +(fn_t function) noexcept {
820 delegate result = *this;
821 result += function;
822 return result;
823 }
824
825 delegate& operator +=(const delegate & delegate) noexcept {
826 *this = delegate::combine(*this, delegate);
827 return *this;
828 }
829
830 delegate& operator +=(const no_arguments_function_t& function) noexcept {
831 *this = delegate::combine(*this, delegate(function));
832 return *this;
833 }
834
835 delegate& operator +=(const function_t& function) noexcept {
836 *this = delegate::combine(*this, delegate(function));
837 return *this;
838 }
839
840 template < class fn_t >
841 delegate& operator +=(fn_t function) noexcept {
842 *this = delegate::combine(*this, delegate(function));
843 return *this;
844 }
845
846 delegate operator -(const delegate & other) noexcept {
847 delegate result = *this;
848 result -= other;
849 return result;
850 }
851
852 delegate operator -(const no_arguments_function_t& function) noexcept {
853 delegate result = *this;
854 result -= function;
855 return result;
856 }
857
858 delegate operator -(const function_t& function) noexcept {
859 delegate result = *this;
860 result -= function;
861 return result;
862 }
863
864 template < class fn_t >
865 delegate operator -(fn_t function) noexcept {
866 delegate result = *this;
867 result -= function;
868 return result;
869 }
870
871 delegate& operator -=(const delegate & delegate) noexcept {
872 *this = delegate::remove(*this, delegate);
873 return *this;
874 }
875
876 delegate& operator -=(const no_arguments_function_t& function) noexcept {
877 *this = delegate::remove(*this, delegate(function));
878 return *this;
879 }
880
881 delegate& operator -=(const function_t& function) noexcept {
882 *this = delegate::remove(*this, delegate(function));
883 return *this;
884 }
885
886 template < class fn_t >
887 delegate& operator -=(fn_t function) noexcept {
888 *this = delegate::remove(*this, delegate(function));
889 return *this;
890 }
892
893 private:
894 struct delegate_async_state;
895
896 static bool are_equals(const std::function < result_t(arguments_t...) >& fct1, const std::function < result_t(arguments_t...) >& fct2) noexcept {
897 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...) > ());
898 }
899
900 static bool are_equals(const std::function < result_t() >& fct1, const std::function < result_t() >& fct2) noexcept {
901 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(*)() > ());
902 }
903
904 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 {
905 auto iterator = std::find_if(begin, end, [&](auto item) {return are_equals(item, function);});
906 if (iterator != end) return iterator;
907 return end;
908 }
909
910 static typename function_collection::const_iterator find(typename function_collection::const_iterator begin, typename function_collection::const_iterator end, const function_t& function) noexcept {
911 auto iterator = std::find_if(begin, end, [&](auto item) {return are_equals(item, function);});
912 if (iterator != end) return iterator;
913 return end;
914 }
915
917 };
918}
919
932#define delegate_ \
933 [&]
934
935// 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:123
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:244
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:138
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:184
bool is_empty() const noexcept
Return if the delegate is empty.
Definition delegate.hpp:127
size_t size() const noexcept
Return the size of invocation list.
Definition delegate.hpp:131
async_result begin_invoke(xtd::async_callback async_callback)
Executes the method represented by the current delegate asynchronously on the thread that the control...
size_t count() const noexcept
Return the size of invocation list.
Definition delegate.hpp:119
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:204
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:180
static delegate combine(const delegate &a, const delegate &b) noexcept
Concatenates the invocation lists of two delegates.
Definition delegate.hpp:218
result_t invoke() const
invokes the method represented by the current delegate.
Definition delegate.hpp:175
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:230
result_t operator()() const
invokes the method represented by the current delegate.
Definition delegate.hpp:264
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:574
const function_collection & functions() const
Gets the delegates array.
Definition delegate.hpp:578
delegate(const function_t &function) noexcept
Initializes a delegate that invokes the specified instance method.
Definition delegate.hpp:440
result_t operator()(arguments_t... arguments) const
invokes the method represented by the current delegate.
Definition delegate.hpp:741
bool equals(const delegate &other) const noexcept override
Determines whether this instance and another specified delegateType object have the same value.
Definition delegate.hpp:639
std::vector< no_arguments_function_t > no_arguments_function_collection
function_t Represents the no arguments function collection type.
Definition delegate.hpp:421
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:693
bool equals(const object &obj) const noexcept override
Determines whether this instance and another specified delegateType object have the same value.
Definition delegate.hpp:635
size_t size() const noexcept
Return the size of invocation list.
Definition delegate.hpp:586
std::vector< function_t > function_collection
function_t Represents the function collection type.
Definition delegate.hpp:423
std::function< result_t(arguments_t...) > function_t
Represents function type.
Definition delegate.hpp:419
size_t count() const noexcept
Return the size of invocation list.
Definition delegate.hpp:570
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:450
std::function< result_t() > no_arguments_function_t
Represents no arguments function type.
Definition delegate.hpp:417
result_t invoke(arguments_t &&... arguments) const
invokes the method represented by the current delegate.
Definition delegate.hpp:630
bool is_empty() const noexcept
Return if the delegate is empty.
Definition delegate.hpp:582
static delegate combine(const array< delegate > &delegates) noexcept
Concatenates the invocation lists of an array of delegates.
Definition delegate.hpp:663
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:712
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:679
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:458
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:45
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.