xtd 0.2.0
Loading...
Searching...
No Matches
delegate.h
Go to the documentation of this file.
1
4#pragma once
5#include "any.h"
7#include "async_result.h"
8#include "iequatable.h"
9#include "object.h"
10#include "object_ref.h"
11#include <functional>
12#include <stdexcept>
13#include <vector>
14
16namespace xtd {
18 template<typename result_t>
19 class delegate;
20
21 template<typename result_t, typename... arguments_t>
22 class delegate<result_t(arguments_t...)>;
24
36 using async_callback = delegate<void(async_result ar)>;
37
52 template<typename result_t>
53 class delegate<result_t()> : public xtd::object, public xtd::iequatable<delegate<result_t()>> {
54 struct data {
55 std::vector<std::function <result_t()>> functions;
56 };
57
58 class async_result_invoke : public xtd::iasync_result {
59 struct data;
60 public:
61 async_result_invoke(xtd::async_callback async_callback, std::any async_state);
62 std::any async_state() const noexcept override;
63 xtd::threading::wait_handle& async_wait_handle() noexcept override;
64 bool completed_synchronously() const noexcept override;
65 bool is_completed() const noexcept override;
66
67 xtd::sptr<data> data_;
68 };
69
70 public:
72
75 using function_t = std::function <result_t()>;
77
79
82 delegate() = default;
84 delegate(delegate&&) = default;
85 delegate(const delegate&) = default;
86 delegate& operator =(const delegate& delegate) = default;
88
91 delegate(const function_t& function) noexcept {data_->functions.push_back(function);} // Can't be explicit by design.
92
96 template<typename object1_t, typename object2_t>
97 delegate(const object1_t& object, result_t(object2_t::*method)() const) noexcept {
98 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object))));
99 }
103 template<typename object1_t, typename object2_t>
104 delegate(const object1_t& object, result_t(object2_t::*method)()) noexcept {
105 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object))));
106 }
108
110
114 const std::vector<function_t>& functions() const {return data_->functions;}
115
118 bool is_empty() const noexcept {return data_->functions.size() == 0;}
119
122 size_t size() const noexcept {return data_->functions.size();}
124
126
129 void clear() {data_->functions.clear();}
130
152
158 result_t end_invoke(async_result async);
159
166 result_t invoke() const {return operator()();}
167
168 using object::equals;
172 bool equals(const delegate& delegate) const noexcept override {
173 if (data_->functions.size() != delegate.data_->functions.size())
174 return false;
175
176 for (size_t i = 0; i < data_->functions.size(); i++)
177 if (!are_equals(data_->functions[i], delegate.data_->functions[i]))
178 return false;
179
180 return true;
181 }
183
185
192 static delegate combine(const std::vector<delegate>& delegates) noexcept {
193 delegate result;
194 for (const delegate& delegate : delegates) {
195 for (const function_t& function : delegate.data_->functions)
196 result.data_->functions.push_back(function);
197 }
198 return result;
199 }
200
206 static delegate combine(const delegate& a, const delegate& b) noexcept {
207 delegate result = a;
208 for (const function_t& function : b.data_->functions)
209 result.data_->functions.push_back(function);
210 return result;
211 }
212
218 static delegate remove(const delegate& source, const delegate& value) noexcept {
219 delegate result = source;
220 std::for_each(value.data_->functions.begin(), value.data_->functions.end(), [&](auto function) {
221 auto iterator = std::find_if(result.data_->functions.rbegin(), result.data_->functions.rend(), [&](auto item) {return are_equals(item, function);});
222 if (iterator != result.data_->functions.rend()) result.data_->functions.erase((iterator + 1).base());
223 });
224 return result;
225 }
226
232 static delegate remove_all(const delegate& source, const delegate& value) noexcept {
233 delegate result = source;
234 for (const function_t& function : value.data_->functions) {
235 if (find(result.data_->functions.begin(), result.data_->functions.end(), function) != result.data_->functions.end()) {
236 for (typename std::vector<function_t>::reverse_iterator iterator = result.data_->functions.rbegin(); iterator != result.data_->functions.rend(); ++iterator) {
237 if (are_equals(*iterator, function))
238 result.data_->functions.erase((iterator + 1).base());
239 }
240 }
241 }
242 return result;
243 }
245
247
252 result_t operator()() const {
253 if (data_->functions.size() == 0) return result_t();
254
255 for (size_t i = 0; i < data_->functions.size() - 1; i++) {
256 if (data_->functions[i] == nullptr) throw xtd::argument_null_exception {};
257 data_->functions[i]();
258 }
259 if (data_->functions.back() == nullptr) throw xtd::argument_null_exception {};
260 return data_->functions.back()();
261 }
262
263 delegate& operator =(const function_t& function) noexcept {
264 data_->functions.clear();
265 data_->functions.push_back(function);
266 return *this;
267 }
269
271 delegate operator +(const delegate& other) noexcept {
272 delegate result = *this;
273 result += other;
274 return result;
275 }
276
277 delegate operator +(const function_t& function) noexcept {
278 delegate result = *this;
279 result += function;
280 return result;
281 }
282
283 template<typename fn_t>
284 delegate operator +(fn_t function) noexcept {
285 delegate result = *this;
286 result += function;
287 return result;
288 }
289
290 delegate& operator +=(const delegate& delegate) noexcept {
291 *this = delegate::combine(*this, delegate);
292 return *this;
293 }
294
295 delegate& operator +=(const function_t& function) noexcept {
296 *this = delegate::combine(*this, delegate(function));
297 return *this;
298 }
299
300 template<typename fn_t>
301 delegate& operator +=(fn_t function) noexcept {
302 *this = delegate::combine(*this, delegate(function));
303 return *this;
304 }
305
306 delegate operator -(const delegate& other) noexcept {
307 delegate result = *this;
308 result -= other;
309 return result;
310 }
311
312 delegate operator -(const function_t& function) noexcept {
313 delegate result = *this;
314 result -= function;
315 return result;
316 }
317
318 template<typename fn_t>
319 delegate operator -(fn_t function) noexcept {
320 delegate result = *this;
321 result -= function;
322 return result;
323 }
324
325 delegate& operator -=(const delegate& delegate) noexcept {
326 *this = delegate::remove(*this, delegate);
327 return *this;
328 }
329
330 delegate& operator -=(const function_t& function) noexcept {
331 *this = delegate::remove(*this, delegate(function));
332 return *this;
333 }
334
335 template<typename fn_t>
336 delegate& operator -=(fn_t function) noexcept {
337 *this = delegate::remove(*this, delegate(function));
338 return *this;
339 }
341
342 private:
343 static bool are_equals(const std::function<result_t()>& fct1, const std::function<result_t()>& fct2) noexcept {
344 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(*)()>());
345 }
346
347 static typename std::vector<function_t>::const_iterator find(typename std::vector<function_t>::const_iterator begin, typename std::vector<function_t>::const_iterator end, const function_t& function) noexcept {
348 auto iterator = std::find_if(begin, end, [&](auto item) {return are_equals(item, function);});
349 if (iterator != end) return iterator;
350 return end;
351 }
352 xtd::sptr<data> data_ = xtd::new_sptr<data>();
353 };
354
369 template<typename result_t, typename... arguments_t>
370 class delegate<result_t(arguments_t...)> : public object, public xtd::iequatable<delegate<result_t(arguments_t...)>> {
371 struct data {
372 std::vector<std::function <result_t()>> no_arguments_functions;
373 std::vector<std::function <result_t(arguments_t...)>> functions;
374 };
375
376 class async_result_invoke : public xtd::iasync_result {
377 struct data;
378 public:
379 async_result_invoke(xtd::async_callback async_callback, std::any async_state);
380 std::any async_state() const noexcept override;
381 xtd::threading::wait_handle& async_wait_handle() noexcept override;
382 bool completed_synchronously() const noexcept override;
383 bool is_completed() const noexcept override;
384
385 xtd::sptr<data> data_;
386 };
387
388 public:
390
393 using no_arguments_function_t = std::function <result_t()>;
395 using function_t = std::function <result_t(arguments_t...)>;
397
399
402 delegate() = default;
404 delegate(delegate&&) = default;
405 delegate(const delegate&) = default;
406 delegate& operator =(const delegate& delegate) = default;
407 delegate(const delegate<result_t()>& delegate) noexcept {data_->no_arguments_functions = delegate.functions();}
409
412 delegate(const function_t& function) noexcept {data_->functions.push_back(function);} // Can't be explicit by design.
413
415 delegate(const no_arguments_function_t& function) noexcept {data_->no_arguments_functions.push_back(function);} // Can't be explicit by design.
417
421 template<typename object1_t, typename object2_t>
422 delegate(const object1_t& object, result_t(object2_t::*method)() const) noexcept {
423 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object))));
424 }
425
429 template<typename object1_t, typename object2_t>
430 delegate(const object1_t& object, result_t(object2_t::*method)()) noexcept {
431 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object))));
432 }
434
436 template<typename object1_t, typename object2_t, typename a1_t>
437 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t) const) noexcept {
438 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1)));
439 }
440
441 template<typename object1_t, typename object2_t, typename a1_t>
442 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t)) noexcept {
443 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1)));
444 }
445
446 template<typename object1_t, typename object2_t, typename a1_t, typename a2_t>
447 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t) const) noexcept {
448 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2)));
449 }
450
451 template<typename object1_t, typename object2_t, typename a1_t, typename a2_t>
452 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t)) noexcept {
453 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2)));
454 }
455
456 template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t>
457 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t) const) noexcept {
458 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)));
459 }
460
461 template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t>
462 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t)) noexcept {
463 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)));
464 }
465
466 template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t>
467 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t) const) {
468 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)));
469 }
470
471 template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t>
472 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t)) noexcept {
473 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)));
474 }
475
476 template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t, typename A5>
477 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5) const) noexcept {
478 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)));
479 }
480
481 template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t, typename A5>
482 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5)) {
483 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)));
484 }
485
486 template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t, typename A5, typename a6_t>
487 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t) const) noexcept {
488 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)));
489 }
490
491 template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t, typename A5, typename a6_t>
492 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t)) noexcept {
493 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)));
494 }
495
496 template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t, typename A5, typename a6_t, typename a7_t>
497 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 {
498 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)));
499 }
500
501 template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t, typename A5, typename a6_t, typename a7_t>
502 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t, a7_t)) noexcept {
503 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)));
504 }
505
506 template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t, typename A5, typename a6_t, typename a7_t, typename a8_t>
507 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 {
508 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)));
509 }
510
511 template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t, typename A5, typename a6_t, typename a7_t, typename a8_t>
512 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 {
513 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)));
514 }
515
516 template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t, typename A5, typename a6_t, typename a7_t, typename a8_t, typename a9_t>
517 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 {
518 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)));
519 }
520
521 template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t, typename A5, typename a6_t, typename a7_t, typename a8_t, typename a9_t>
522 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 {
523 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)));
524 }
525
526 template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t, typename A5, typename a6_t, typename a7_t, typename a8_t, typename a9_t, typename a10_t>
527 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 {
528 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)));
529 }
530
531 template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t, typename A5, typename a6_t, typename a7_t, typename a8_t, typename a9_t, typename a10_t>
532 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 {
533 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)));
534 }
536
538
542 const std::vector<no_arguments_function_t>& no_arguments_functions() const {return data_->no_arguments_functions;}
543
546 const std::vector<function_t>& functions() const {return data_->functions;}
547
550 bool is_empty() const noexcept {return data_->functions.size() == 0 && data_->no_arguments_functions.size() == 0;}
551
554 size_t size() const noexcept {return data_->functions.size() + data_->no_arguments_functions.size();}
556
558
568 async_result begin_invoke(arguments_t... arguments);
583 async_result begin_invoke(xtd::async_callback async_callback, std::any async_state, arguments_t... arguments);
584
590 result_t end_invoke(async_result async);
591
598 result_t invoke(arguments_t... arguments) const {return operator()(arguments...);}
599
600 using object::equals;
604 bool equals(const delegate& delegate) const noexcept override {
605 if (data_->functions.size() != delegate.data_->functions.size() || data_->no_arguments_functions.size() != delegate.data_->no_arguments_functions.size())
606 return false;
607
608 for (size_t i = 0; i < data_->no_arguments_functions.size(); i++)
609 if (!are_equals(data_->no_arguments_functions[i], delegate.data_->no_arguments_functions[i]))
610 return false;
611
612 for (size_t i = 0; i < data_->functions.size(); i++)
613 if (!are_equals(data_->functions[i], delegate.data_->functions[i]))
614 return false;
615
616 return true;
617 }
619
621
628 static delegate combine(const std::vector<delegate>& delegates) noexcept {
629 delegate result;
630 for (const delegate& delegate : delegates) {
631 for (const no_arguments_function_t& function : delegate.data_->no_arguments_functions)
632 result.data_->no_arguments_functions.push_back(function);
633 for (const function_t& function : delegate.data_->functions)
634 result.data_->functions.push_back(function);
635 }
636 return result;
637 }
638
644 static delegate combine(const delegate& a, const delegate& b) noexcept {
645 delegate result = a;
646 for (const no_arguments_function_t& function : b.data_->no_arguments_functions)
647 result.data_->no_arguments_functions.push_back(function);
648 for (const function_t& function : b.data_->functions)
649 result.data_->functions.push_back(function);
650 return result;
651 }
652
658 static delegate remove(const delegate& source, const delegate& value) noexcept {
659 delegate result = source;
660 std::for_each(value.data_->no_arguments_functions.begin(), value.data_->no_arguments_functions.end(), [&](auto no_arguments_function) {
661 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);});
662 if (iterator != result.data_->no_arguments_functions.rend()) result.data_->no_arguments_functions.erase((iterator + 1).base());
663 });
664
665 std::for_each(value.data_->functions.begin(), value.data_->functions.end(), [&](auto function) {
666 auto iterator = std::find_if(result.data_->functions.rbegin(), result.data_->functions.rend(), [&](auto item) {return are_equals(item, function);});
667 if (iterator != result.data_->functions.rend()) result.data_->functions.erase((iterator + 1).base());
668 });
669 return result;
670 }
671
677 static delegate remove_all(const delegate& source, const delegate& value) noexcept {
678 delegate result = source;
679 for (const no_arguments_function_t& function : value.data_->no_arguments_functions) {
680 if (find(result.data_->no_arguments_functions.begin(), result.data_->no_arguments_functions.end(), function) != result.data_->no_arguments_functions.end()) {
681 for (typename std::vector<function_t>::reverse_iterator iterator = result.data_->no_arguments_functions.rbegin(); iterator != result.data_->no_arguments_functions.rend(); ++iterator) {
682 if (are_equals(*iterator, function))
683 result.data_->no_arguments_functions.erase((iterator + 1).base());
684 }
685 }
686 }
687
688 for (const function_t& function : value.data_->functions) {
689 if (find(result.data_->functions.begin(), result.data_->functions.end(), function) != result.data_->functions.end()) {
690 for (typename std::vector<function_t>::reverse_iterator iterator = result.data_->functions.rbegin(); iterator != result.data_->functions.rend(); ++iterator) {
691 if (are_equals(*iterator, function))
692 result.data_->functions.erase((iterator + 1).base());
693 }
694 }
695 }
696 return result;
697 }
699
701
706 result_t operator()(arguments_t... arguments) const {
707 if (data_->no_arguments_functions.size() == 0 && data_->functions.size() == 0) return result_t();
708
709 if (data_->no_arguments_functions.size()) {
710 for (size_t i = 0; i < data_->no_arguments_functions.size() - (data_->functions.size() == 0 ? 1 : 0); i++) {
711 if (data_->no_arguments_functions[i] == nullptr) throw xtd::argument_null_exception {};
712 data_->no_arguments_functions[i]();
713 }
714
715 if (data_->functions.size() == 0) {
716 if (data_->no_arguments_functions.back() == nullptr) throw xtd::argument_null_exception {};
717 return data_->no_arguments_functions.back()();
718 }
719 }
720
721 for (size_t i = 0; i < data_->functions.size() - 1; i++) {
722 if (data_->functions[i] == nullptr) throw xtd::argument_null_exception {};
723 data_->functions[i](arguments...);
724 }
725 if (data_->functions.back() == nullptr) throw xtd::argument_null_exception {};
726 return data_->functions.back()(arguments...);
727 }
729
731 template<typename type_t>
732 delegate& operator =(const type_t& function) noexcept {
733 data_->no_arguments_functions.clear();
734 data_->functions.clear();
735 data_->functions.push_back(function_t(function));
736 return *this;
737 }
738
739 delegate& operator =(const function_t& function) noexcept {
740 data_->no_arguments_functions.clear();
741 data_->functions.clear();
742 data_->functions.push_back(function);
743 return *this;
744 }
745
746 delegate& operator =(const no_arguments_function_t& function) noexcept {
747 data_->no_arguments_functions.clear();
748 data_->functions.clear();
749 data_->no_arguments_functions.push_back(function);
750 return *this;
751 }
752
753 delegate operator +(const delegate& other) noexcept {
754 delegate result = *this;
755 result += other;
756 return result;
757 }
758
759 delegate operator +(const no_arguments_function_t& function) noexcept {
760 delegate result = *this;
761 result += function;
762 return result;
763 }
764
765 delegate operator +(const function_t& function) noexcept {
766 delegate result = *this;
767 result += function;
768 return result;
769 }
770
771 template<typename fn_t>
772 delegate operator +(fn_t function) noexcept {
773 delegate result = *this;
774 result += function;
775 return result;
776 }
777
778 delegate& operator +=(const delegate& delegate) noexcept {
779 *this = delegate::combine(*this, delegate);
780 return *this;
781 }
782
783 delegate& operator +=(const no_arguments_function_t& function) noexcept {
784 *this = delegate::combine(*this, delegate(function));
785 return *this;
786 }
787
788 delegate& operator +=(const function_t& function) noexcept {
789 *this = delegate::combine(*this, delegate(function));
790 return *this;
791 }
792
793 template<typename fn_t>
794 delegate& operator +=(fn_t function) noexcept {
795 *this = delegate::combine(*this, delegate(function));
796 return *this;
797 }
798
799 delegate operator -(const delegate& other) noexcept {
800 delegate result = *this;
801 result -= other;
802 return result;
803 }
804
805 delegate operator -(const no_arguments_function_t& function) noexcept {
806 delegate result = *this;
807 result -= function;
808 return result;
809 }
810
811 delegate operator -(const function_t& function) noexcept {
812 delegate result = *this;
813 result -= function;
814 return result;
815 }
816
817 template<typename fn_t>
818 delegate operator -(fn_t function) noexcept {
819 delegate result = *this;
820 result -= function;
821 return result;
822 }
823
824 delegate& operator -=(const delegate& delegate) noexcept {
825 *this = delegate::remove(*this, delegate);
826 return *this;
827 }
828
829 delegate& operator -=(const no_arguments_function_t& function) noexcept {
830 *this = delegate::remove(*this, delegate(function));
831 return *this;
832 }
833
834 delegate& operator -=(const function_t& function) noexcept {
835 *this = delegate::remove(*this, delegate(function));
836 return *this;
837 }
838
839 template<typename fn_t>
840 delegate& operator -=(fn_t function) noexcept {
841 *this = delegate::remove(*this, delegate(function));
842 return *this;
843 }
845
846 private:
847 static bool are_equals(const std::function<result_t(arguments_t...)>& fct1, const std::function<result_t(arguments_t...)>& fct2) noexcept {
848 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...)>());
849 }
850
851 static bool are_equals(const std::function<result_t()>& fct1, const std::function<result_t()>& fct2) noexcept {
852 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(*)()>());
853 }
854
855 static typename std::vector<no_arguments_function_t>::const_iterator find(typename std::vector<no_arguments_function_t>::const_iterator begin, typename std::vector<no_arguments_function_t>::const_iterator end, const no_arguments_function_t& function) noexcept {
856 auto iterator = std::find_if(begin, end, [&](auto item) {return are_equals(item, function);});
857 if (iterator != end) return iterator;
858 return end;
859 }
860
861 static typename std::vector<function_t>::const_iterator find(typename std::vector<function_t>::const_iterator begin, typename std::vector<function_t>::const_iterator end, const function_t& function) noexcept {
862 auto iterator = std::find_if(begin, end, [&](auto item) {return are_equals(item, function);});
863 if (iterator != end) return iterator;
864 return end;
865 }
866
867 xtd::sptr<data> data_ = xtd::new_sptr<data>();
868 };
869}
870
871// Required for begin_invoke and end_invoke methods implementation.
Contains std::any type and std::bad_any_cast exception.
Contains xtd::argument_null_exception exception.
Contains xtd::async_result alias.
The exception that is thrown when one of the arguments provided to a method is null.
Definition argument_null_exception.h:23
bool equals(const delegate &delegate) const noexcept override
Determines whether this instance and another specified delegateType object have the same value.
Definition delegate.h:172
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.h:104
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.h:232
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.h:97
void clear()
Clear delegates array.
Definition delegate.h:129
delegate()=default
Initializes an empty delegate.
static delegate combine(const std::vector< delegate > &delegates) noexcept
Concatenates the invocation lists of an array of delegates.
Definition delegate.h:192
bool is_empty() const noexcept
Return if the delegate is empty.
Definition delegate.h:118
size_t size() const noexcept
Return the size of invocation list.
Definition delegate.h:122
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.h:91
const std::vector< function_t > & functions() const
Gets the delegates array.
Definition delegate.h:114
std::function< result_t()> function_t
function_t pointer type
Definition delegate.h:75
async_result begin_invoke(xtd::async_callback async_callback, std::any async_state)
Executes the method represented by the current delegate asynchronously on the thread that the control...
result_t end_invoke(async_result async)
Retrieves the return value of the asynchronous operation represented by the async_result_invoke passe...
static delegate combine(const delegate &a, const delegate &b) noexcept
Concatenates the invocation lists of two delegates.
Definition delegate.h:206
result_t invoke() const
invokes the method represented by the current delegate.
Definition delegate.h:166
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.h:218
result_t operator()() const
invokes the method represented by the current delegate.
Definition delegate.h:252
async_result begin_invoke()
Executes the method represented by the current delegate asynchronously on the thread that the control...
std::function< result_t()> no_arguments_function_t
no_arguments_function_t pointer type
Definition delegate.h:393
const std::vector< function_t > & functions() const
Gets the delegates array.
Definition delegate.h:546
async_result begin_invoke(xtd::async_callback async_callback, std::any async_state, arguments_t... arguments)
Executes the method represented by the current delegate asynchronously on the thread that the control...
async_result begin_invoke(arguments_t... arguments)
Executes the method represented by the current delegate asynchronously on the thread that the control...
result_t invoke(arguments_t... arguments) const
invokes the method represented by the current delegate.
Definition delegate.h:598
result_t end_invoke(async_result async)
Retrieves the return value of the asynchronous operation represented by the async_result_invoke passe...
static delegate combine(const std::vector< delegate > &delegates) noexcept
Concatenates the invocation lists of an array of delegates.
Definition delegate.h:628
delegate()=default
Initializes an empty delegate.
bool equals(const delegate &delegate) const noexcept override
Determines whether this instance and another specified delegateType object have the same value.
Definition delegate.h:604
const std::vector< no_arguments_function_t > & no_arguments_functions() const
Gets the no arguments delegates array.
Definition delegate.h:542
std::function< result_t(arguments_t...)> function_t
function_t pointer type
Definition delegate.h:395
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.h:430
size_t size() const noexcept
Return the size of invocation list.
Definition delegate.h:554
result_t operator()(arguments_t... arguments) const
invokes the method represented by the current delegate.
Definition delegate.h:706
bool is_empty() const noexcept
Return if the delegate is empty.
Definition delegate.h:550
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.h:658
static delegate combine(const delegate &a, const delegate &b) noexcept
Concatenates the invocation lists of two delegates.
Definition delegate.h:644
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.h:677
delegate(const function_t &function) noexcept
Initializes a delegate that invokes the specified instance method.
Definition delegate.h:412
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...
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.h:422
Represents the status of an asynchronous operation.
Definition iasync_result.h:25
Defines a generalized method that a value type or class implements to create a type-specific method f...
Definition iequatable.h:22
Supports all classes in the xtd class hierarchy and provides low-level services to derived classes....
Definition object.h:42
Encapsulates operating system specific objects that wait for exclusive access to shared resources.
Definition wait_handle.h:52
std::shared_ptr< type_t > sptr
The xtd::sptr object is a shared pointer.
Definition sptr.h:25
xtd::sptr< xtd::iasync_result > async_result
Represents the status of an asynchronous operation.
Definition async_result.h:19
delegate< void(async_result ar)> async_callback
References a method to be called when a corresponding asynchronous operation completes.
Definition delegate.h:36
@ other
The operating system is other.
@ a
The A key.
@ end
The END key.
@ i
The I key.
@ b
The B key.
@ function
The FUNCTION modifier key.
Contains xtd::iequatable interface.
The xtd namespace contains all fundamental classes to access Hardware, Os, System,...
Definition xtd_about_box.h:10
Contains xtd::object class.
Contains xtd::object_ref alias.
Contains xtd::threading::thread_pool class.