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
34 using async_callback = delegate<void(async_result ar)>;
35
48 template<typename result_t>
49 class delegate<result_t()> : public xtd::object, public xtd::iequatable<delegate<result_t()>> {
50 struct data {
51 std::vector<std::function <result_t()>> functions;
52 };
53
54 class async_result_invoke : public xtd::iasync_result {
55 struct data;
56 public:
57 async_result_invoke(xtd::async_callback async_callback, std::any async_state);
58 std::any async_state() const noexcept override;
59 xtd::threading::wait_handle& async_wait_handle() noexcept override;
60 bool completed_synchronously() const noexcept override;
61 bool is_completed() const noexcept override;
62
63 std::shared_ptr<data> data_;
64 };
65
66 public:
68
71 using function_t = std::function <result_t()>;
73
75
78 delegate() = default;
80 delegate(delegate&&) = default;
81 delegate(const delegate&) = default;
82 delegate& operator =(const delegate& delegate) = default;
84
87 delegate(const function_t& function) noexcept {data_->functions.push_back(function);} // Can't be explicit by design.
88
92 template<typename object1_t, typename object2_t>
93 delegate(const object1_t& object, result_t(object2_t::*method)() const) noexcept {
94 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object))));
95 }
99 template<typename object1_t, typename object2_t>
100 delegate(const object1_t& object, result_t(object2_t::*method)()) noexcept {
101 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object))));
102 }
104
106
110 const std::vector<function_t>& functions() const {return data_->functions;}
111
114 bool is_empty() const noexcept {return data_->functions.size() == 0;}
115
118 size_t size() const noexcept {return data_->functions.size();}
120
122
125 void clear() {data_->functions.clear();}
126
148
154 result_t end_invoke(async_result async);
155
162 result_t invoke() const {return operator()();}
163
167 bool equals(const delegate& delegate) const noexcept override {
168 if (data_->functions.size() != delegate.data_->functions.size())
169 return false;
170
171 for (size_t i = 0; i < data_->functions.size(); i++)
172 if (!are_equals(data_->functions[i], delegate.data_->functions[i]))
173 return false;
174
175 return true;
176 }
178
180
187 static delegate combine(const std::vector<delegate>& delegates) noexcept {
188 delegate result;
189 for (const delegate& delegate : delegates) {
190 for (const function_t& function : delegate.data_->functions)
191 result.data_->functions.push_back(function);
192 }
193 return result;
194 }
195
201 static delegate combine(const delegate& a, const delegate& b) noexcept {
202 delegate result = a;
203 for (const function_t& function : b.data_->functions)
204 result.data_->functions.push_back(function);
205 return result;
206 }
207
213 static delegate remove(const delegate& source, const delegate& value) noexcept {
214 delegate result = source;
215 std::for_each(value.data_->functions.begin(), value.data_->functions.end(), [&](auto function) {
216 auto iterator = std::find_if(result.data_->functions.rbegin(), result.data_->functions.rend(), [&](auto item) {return are_equals(item, function);});
217 if (iterator != result.data_->functions.rend()) result.data_->functions.erase((iterator + 1).base());
218 });
219 return result;
220 }
221
227 static delegate remove_all(const delegate& source, const delegate& value) noexcept {
228 delegate result = source;
229 for (const function_t& function : value.data_->functions) {
230 if (find(result.data_->functions.begin(), result.data_->functions.end(), function) != result.data_->functions.end()) {
231 for (typename std::vector<function_t>::reverse_iterator iterator = result.data_->functions.rbegin(); iterator != result.data_->functions.rend(); ++iterator) {
232 if (are_equals(*iterator, function))
233 result.data_->functions.erase((iterator + 1).base());
234 }
235 }
236 }
237 return result;
238 }
240
242
247 result_t operator()() const {
248 if (data_->functions.size() == 0) return result_t();
249
250 for (size_t i = 0; i < data_->functions.size() - 1; i++) {
251 if (data_->functions[i] == nullptr) throw xtd::argument_null_exception {csf_};
252 data_->functions[i]();
253 }
254 if (data_->functions.back() == nullptr) throw xtd::argument_null_exception {csf_};
255 return data_->functions.back()();
256 }
257
258 delegate& operator =(const function_t& function) noexcept {
259 data_->functions.clear();
260 data_->functions.push_back(function);
261 return *this;
262 }
264
266 delegate operator +(const delegate& other) noexcept {
267 delegate result = *this;
268 result += other;
269 return result;
270 }
271
272 delegate operator +(const function_t& function) noexcept {
273 delegate result = *this;
274 result += function;
275 return result;
276 }
277
278 template<typename fn_t>
279 delegate operator +(fn_t function) noexcept {
280 delegate result = *this;
281 result += function;
282 return result;
283 }
284
285 delegate& operator +=(const delegate& delegate) noexcept {
286 *this = delegate::combine(*this, delegate);
287 return *this;
288 }
289
290 delegate& operator +=(const function_t& function) noexcept {
291 *this = delegate::combine(*this, delegate(function));
292 return *this;
293 }
294
295 template<typename fn_t>
296 delegate& operator +=(fn_t function) noexcept {
297 *this = delegate::combine(*this, delegate(function));
298 return *this;
299 }
300
301 delegate operator -(const delegate& other) noexcept {
302 delegate result = *this;
303 result -= other;
304 return result;
305 }
306
307 delegate operator -(const function_t& function) noexcept {
308 delegate result = *this;
309 result -= function;
310 return result;
311 }
312
313 template<typename fn_t>
314 delegate operator -(fn_t function) noexcept {
315 delegate result = *this;
316 result -= function;
317 return result;
318 }
319
320 delegate& operator -=(const delegate& delegate) noexcept {
321 *this = delegate::remove(*this, delegate);
322 return *this;
323 }
324
325 delegate& operator -=(const function_t& function) noexcept {
326 *this = delegate::remove(*this, delegate(function));
327 return *this;
328 }
329
330 template<typename fn_t>
331 delegate& operator -=(fn_t function) noexcept {
332 *this = delegate::remove(*this, delegate(function));
333 return *this;
334 }
336
337 private:
338 static bool are_equals(const std::function<result_t()>& fct1, const std::function<result_t()>& fct2) noexcept {
339 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(*)()>());
340 }
341
342 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 {
343 auto iterator = std::find_if(begin, end, [&](auto item) {return are_equals(item, function);});
344 if (iterator != end) return iterator;
345 return end;
346 }
347 std::shared_ptr<data> data_ = std::make_shared<data>();
348 };
349
362 template<typename result_t, typename... arguments_t>
363 class delegate<result_t(arguments_t...)> : public object, public xtd::iequatable<delegate<result_t(arguments_t...)>> {
364 struct data {
365 std::vector<std::function <result_t()>> no_arguments_functions;
366 std::vector<std::function <result_t(arguments_t...)>> functions;
367 };
368
369 class async_result_invoke : public xtd::iasync_result {
370 struct data;
371 public:
372 async_result_invoke(xtd::async_callback async_callback, std::any async_state);
373 std::any async_state() const noexcept override;
374 xtd::threading::wait_handle& async_wait_handle() noexcept override;
375 bool completed_synchronously() const noexcept override;
376 bool is_completed() const noexcept override;
377
378 std::shared_ptr<data> data_;
379 };
380
381 public:
383
386 using no_arguments_function_t = std::function <result_t()>;
388 using function_t = std::function <result_t(arguments_t...)>;
390
392
395 delegate() = default;
397 delegate(delegate&&) = default;
398 delegate(const delegate&) = default;
399 delegate& operator =(const delegate& delegate) = default;
400 delegate(const delegate<result_t()>& delegate) noexcept {data_->no_arguments_functions = delegate.functions();}
402
405 delegate(const function_t& function) noexcept {data_->functions.push_back(function);} // Can't be explicit by design.
406
408 delegate(const no_arguments_function_t& function) noexcept {data_->no_arguments_functions.push_back(function);} // Can't be explicit by design.
410
414 template<typename object1_t, typename object2_t>
415 delegate(const object1_t& object, result_t(object2_t::*method)() const) noexcept {
416 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object))));
417 }
418
422 template<typename object1_t, typename object2_t>
423 delegate(const object1_t& object, result_t(object2_t::*method)()) noexcept {
424 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object))));
425 }
427
429 template<typename object1_t, typename object2_t, typename a1_t>
430 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t) const) noexcept {
431 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1)));
432 }
433
434 template<typename object1_t, typename object2_t, typename a1_t>
435 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t)) noexcept {
436 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1)));
437 }
438
439 template<typename object1_t, typename object2_t, typename a1_t, typename a2_t>
440 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t) const) noexcept {
441 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2)));
442 }
443
444 template<typename object1_t, typename object2_t, typename a1_t, typename a2_t>
445 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t)) noexcept {
446 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2)));
447 }
448
449 template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t>
450 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t) const) noexcept {
451 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)));
452 }
453
454 template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t>
455 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t)) noexcept {
456 data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)));
457 }
458
459 template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t>
460 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t) const) {
461 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)));
462 }
463
464 template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t>
465 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t)) noexcept {
466 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)));
467 }
468
469 template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t, typename A5>
470 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5) const) noexcept {
471 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)));
472 }
473
474 template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t, typename A5>
475 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5)) {
476 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)));
477 }
478
479 template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t, typename A5, typename a6_t>
480 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t) const) noexcept {
481 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)));
482 }
483
484 template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t, typename A5, typename a6_t>
485 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t)) 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, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6)));
487 }
488
489 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>
490 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 {
491 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)));
492 }
493
494 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>
495 delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t, a7_t)) noexcept {
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, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7)));
497 }
498
499 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>
500 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 {
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, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7, std::placeholders::_8)));
502 }
503
504 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>
505 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 {
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, std::placeholders::_6, std::placeholders::_7, std::placeholders::_8)));
507 }
508
509 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>
510 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 {
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, std::placeholders::_6, std::placeholders::_7, std::placeholders::_8, std::placeholders::_9)));
512 }
513
514 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>
515 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 {
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, std::placeholders::_7, std::placeholders::_8, std::placeholders::_9)));
517 }
518
519 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>
520 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 {
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, std::placeholders::_7, std::placeholders::_8, std::placeholders::_9, std::placeholders::_10)));
522 }
523
524 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>
525 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 {
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, std::placeholders::_8, std::placeholders::_9, std::placeholders::_10)));
527 }
529
531
535 const std::vector<no_arguments_function_t>& no_arguments_functions() const {return data_->no_arguments_functions;}
536
539 const std::vector<function_t>& functions() const {return data_->functions;}
540
543 bool is_empty() const noexcept {return data_->functions.size() == 0 && data_->no_arguments_functions.size() == 0;}
544
547 size_t size() const noexcept {return data_->functions.size() + data_->no_arguments_functions.size();}
549
551
561 async_result begin_invoke(arguments_t... arguments);
576 async_result begin_invoke(xtd::async_callback async_callback, std::any async_state, arguments_t... arguments);
577
583 result_t end_invoke(async_result async);
584
591 result_t invoke(arguments_t... arguments) const {return operator()(arguments...);}
592
596 bool equals(const delegate& delegate) const noexcept override {
597 if (data_->functions.size() != delegate.data_->functions.size() || data_->no_arguments_functions.size() != delegate.data_->no_arguments_functions.size())
598 return false;
599
600 for (size_t i = 0; i < data_->no_arguments_functions.size(); i++)
601 if (!are_equals(data_->no_arguments_functions[i], delegate.data_->no_arguments_functions[i]))
602 return false;
603
604 for (size_t i = 0; i < data_->functions.size(); i++)
605 if (!are_equals(data_->functions[i], delegate.data_->functions[i]))
606 return false;
607
608 return true;
609 }
611
613
620 static delegate combine(const std::vector<delegate>& delegates) noexcept {
621 delegate result;
622 for (const delegate& delegate : delegates) {
623 for (const no_arguments_function_t& function : delegate.data_->no_arguments_functions)
624 result.data_->no_arguments_functions.push_back(function);
625 for (const function_t& function : delegate.data_->functions)
626 result.data_->functions.push_back(function);
627 }
628 return result;
629 }
630
636 static delegate combine(const delegate& a, const delegate& b) noexcept {
637 delegate result = a;
638 for (const no_arguments_function_t& function : b.data_->no_arguments_functions)
639 result.data_->no_arguments_functions.push_back(function);
640 for (const function_t& function : b.data_->functions)
641 result.data_->functions.push_back(function);
642 return result;
643 }
644
650 static delegate remove(const delegate& source, const delegate& value) noexcept {
651 delegate result = source;
652 std::for_each(value.data_->no_arguments_functions.begin(), value.data_->no_arguments_functions.end(), [&](auto no_arguments_function) {
653 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);});
654 if (iterator != result.data_->no_arguments_functions.rend()) result.data_->no_arguments_functions.erase((iterator + 1).base());
655 });
656
657 std::for_each(value.data_->functions.begin(), value.data_->functions.end(), [&](auto function) {
658 auto iterator = std::find_if(result.data_->functions.rbegin(), result.data_->functions.rend(), [&](auto item) {return are_equals(item, function);});
659 if (iterator != result.data_->functions.rend()) result.data_->functions.erase((iterator + 1).base());
660 });
661 return result;
662 }
663
669 static delegate remove_all(const delegate& source, const delegate& value) noexcept {
670 delegate result = source;
671 for (const no_arguments_function_t& function : value.data_->no_arguments_functions) {
672 if (find(result.data_->no_arguments_functions.begin(), result.data_->no_arguments_functions.end(), function) != result.data_->no_arguments_functions.end()) {
673 for (typename std::vector<function_t>::reverse_iterator iterator = result.data_->no_arguments_functions.rbegin(); iterator != result.data_->no_arguments_functions.rend(); ++iterator) {
674 if (are_equals(*iterator, function))
675 result.data_->no_arguments_functions.erase((iterator + 1).base());
676 }
677 }
678 }
679
680 for (const function_t& function : value.data_->functions) {
681 if (find(result.data_->functions.begin(), result.data_->functions.end(), function) != result.data_->functions.end()) {
682 for (typename std::vector<function_t>::reverse_iterator iterator = result.data_->functions.rbegin(); iterator != result.data_->functions.rend(); ++iterator) {
683 if (are_equals(*iterator, function))
684 result.data_->functions.erase((iterator + 1).base());
685 }
686 }
687 }
688 return result;
689 }
691
693
698 result_t operator()(arguments_t... arguments) const {
699 if (data_->no_arguments_functions.size() == 0 && data_->functions.size() == 0) return result_t();
700
701 if (data_->no_arguments_functions.size()) {
702 for (size_t i = 0; i < data_->no_arguments_functions.size() - (data_->functions.size() == 0 ? 1 : 0); i++) {
703 if (data_->no_arguments_functions[i] == nullptr) throw xtd::argument_null_exception {csf_};
704 data_->no_arguments_functions[i]();
705 }
706
707 if (data_->functions.size() == 0) {
708 if (data_->no_arguments_functions.back() == nullptr) throw xtd::argument_null_exception {csf_};
709 return data_->no_arguments_functions.back()();
710 }
711 }
712
713 for (size_t i = 0; i < data_->functions.size() - 1; i++) {
714 if (data_->functions[i] == nullptr) throw xtd::argument_null_exception {csf_};
715 data_->functions[i](arguments...);
716 }
717 if (data_->functions.back() == nullptr) throw xtd::argument_null_exception {csf_};
718 return data_->functions.back()(arguments...);
719 }
721
723 template<typename type_t>
724 delegate& operator =(const type_t& function) noexcept {
725 data_->no_arguments_functions.clear();
726 data_->functions.clear();
727 data_->functions.push_back(function_t(function));
728 return *this;
729 }
730
731 delegate& operator =(const function_t& function) noexcept {
732 data_->no_arguments_functions.clear();
733 data_->functions.clear();
734 data_->functions.push_back(function);
735 return *this;
736 }
737
738 delegate& operator =(const no_arguments_function_t& function) noexcept {
739 data_->no_arguments_functions.clear();
740 data_->functions.clear();
741 data_->no_arguments_functions.push_back(function);
742 return *this;
743 }
744
745 delegate operator +(const delegate& other) noexcept {
746 delegate result = *this;
747 result += other;
748 return result;
749 }
750
751 delegate operator +(const no_arguments_function_t& function) noexcept {
752 delegate result = *this;
753 result += function;
754 return result;
755 }
756
757 delegate operator +(const function_t& function) noexcept {
758 delegate result = *this;
759 result += function;
760 return result;
761 }
762
763 template<typename fn_t>
764 delegate operator +(fn_t function) noexcept {
765 delegate result = *this;
766 result += function;
767 return result;
768 }
769
770 delegate& operator +=(const delegate& delegate) noexcept {
771 *this = delegate::combine(*this, delegate);
772 return *this;
773 }
774
775 delegate& operator +=(const no_arguments_function_t& function) noexcept {
776 *this = delegate::combine(*this, delegate(function));
777 return *this;
778 }
779
780 delegate& operator +=(const function_t& function) noexcept {
781 *this = delegate::combine(*this, delegate(function));
782 return *this;
783 }
784
785 template<typename fn_t>
786 delegate& operator +=(fn_t function) noexcept {
787 *this = delegate::combine(*this, delegate(function));
788 return *this;
789 }
790
791 delegate operator -(const delegate& other) noexcept {
792 delegate result = *this;
793 result -= other;
794 return result;
795 }
796
797 delegate operator -(const no_arguments_function_t& function) noexcept {
798 delegate result = *this;
799 result -= function;
800 return result;
801 }
802
803 delegate operator -(const function_t& function) noexcept {
804 delegate result = *this;
805 result -= function;
806 return result;
807 }
808
809 template<typename fn_t>
810 delegate operator -(fn_t function) noexcept {
811 delegate result = *this;
812 result -= function;
813 return result;
814 }
815
816 delegate& operator -=(const delegate& delegate) noexcept {
817 *this = delegate::remove(*this, delegate);
818 return *this;
819 }
820
821 delegate& operator -=(const no_arguments_function_t& function) noexcept {
822 *this = delegate::remove(*this, delegate(function));
823 return *this;
824 }
825
826 delegate& operator -=(const function_t& function) noexcept {
827 *this = delegate::remove(*this, delegate(function));
828 return *this;
829 }
830
831 template<typename fn_t>
832 delegate& operator -=(fn_t function) noexcept {
833 *this = delegate::remove(*this, delegate(function));
834 return *this;
835 }
837
838 private:
839 static bool are_equals(const std::function<result_t(arguments_t...)>& fct1, const std::function<result_t(arguments_t...)>& fct2) noexcept {
840 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...)>());
841 }
842
843 static bool are_equals(const std::function<result_t()>& fct1, const std::function<result_t()>& fct2) noexcept {
844 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(*)()>());
845 }
846
847 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 {
848 auto iterator = std::find_if(begin, end, [&](auto item) {return are_equals(item, function);});
849 if (iterator != end) return iterator;
850 return end;
851 }
852
853 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 {
854 auto iterator = std::find_if(begin, end, [&](auto item) {return are_equals(item, function);});
855 if (iterator != end) return iterator;
856 return end;
857 }
858
859 std::shared_ptr<data> data_ = std::make_shared<data>();
860 };
861}
862
863// 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:20
bool equals(const delegate &delegate) const noexcept override
Determines whether this instance and another specified delegateType object have the same value.
Definition delegate.h:167
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:100
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:227
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:93
void clear()
Clear delegates array.
Definition delegate.h:125
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:187
bool is_empty() const noexcept
Return if the delegate is empty.
Definition delegate.h:114
size_t size() const noexcept
Return the size of invocation list.
Definition delegate.h:118
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:87
const std::vector< function_t > & functions() const
Gets the delegates array.
Definition delegate.h:110
std::function< result_t()> function_t
function_t pointer type
Definition delegate.h:71
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:201
result_t invoke() const
invokes the method represented by the current delegate.
Definition delegate.h:162
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:213
result_t operator()() const
invokes the method represented by the current delegate.
Definition delegate.h:247
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:386
const std::vector< function_t > & functions() const
Gets the delegates array.
Definition delegate.h:539
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:591
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:620
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:596
const std::vector< no_arguments_function_t > & no_arguments_functions() const
Gets the no arguments delegates array.
Definition delegate.h:535
std::function< result_t(arguments_t...)> function_t
function_t pointer type
Definition delegate.h:388
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:423
size_t size() const noexcept
Return the size of invocation list.
Definition delegate.h:547
result_t operator()(arguments_t... arguments) const
invokes the method represented by the current delegate.
Definition delegate.h:698
bool is_empty() const noexcept
Return if the delegate is empty.
Definition delegate.h:543
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:650
static delegate combine(const delegate &a, const delegate &b) noexcept
Concatenates the invocation lists of two delegates.
Definition delegate.h:636
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:669
delegate(const function_t &function) noexcept
Initializes a delegate that invokes the specified instance method.
Definition delegate.h:405
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:415
Represents the status of an asynchronous operation.
Definition iasync_result.h:22
Defines a generalized method that a value type or class implements to create a type-specific method f...
Definition iequatable.h:18
Supports all classes in the xtd class hierarchy and provides low-level services to derived classes....
Definition object.h:32
Encapsulates operating system specific objects that wait for exclusive access to shared resources.
Definition wait_handle.h:50
#define csf_
Provides information about the current stack frame.
Definition current_stack_frame.h:30
std::shared_ptr< xtd::iasync_result > async_result
Represents the status of an asynchronous operation.
Definition async_result.h:16
delegate< void(async_result ar)> async_callback
References a method to be called when a corresponding asynchronous operation completes.
Definition delegate.h:34
@ 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.