xtd - Reference Guide  0.2.0
Modern c++17/20 framework to create console, GUI and unit test applications on Windows, macOS, Linux, iOS and android.
delegate.h
Go to the documentation of this file.
1 #pragma once
5 
6 #include <functional>
7 #include <memory>
8 #include <stdexcept>
9 #include <vector>
11 #include "object.h"
12 
14 namespace xtd {
16  template<typename result_t>
17  class delegate;
19 
29  template<typename result_t>
30  class delegate<result_t()> : public object {
31  public:
33  using function_t = std::function <result_t()>;
34 
36  delegate() = default;
39  delegate(const delegate& delegate) noexcept : functions_(delegate.functions_) {}
41  delegate(const function_t& function) noexcept { functions_.push_back(function); }
42  delegate& operator=(const delegate& delegate) noexcept {
43  functions_ = delegate.functions_;
44  return *this;
45  }
47 
51  template<typename object1_t, typename object2_t>
52  delegate(const object1_t& object, result_t(object2_t::*method)() const) noexcept {
53  functions_.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object))));
54  }
58  template<typename object1_t, typename object2_t>
59  delegate(const object1_t& object, result_t(object2_t::*method)()) noexcept {
60  functions_.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object))));
61  }
62 
66  result_t operator()() const {
67  if (functions_.size() == 0) return result_t();
68 
69  for (size_t i = 0; i < functions_.size() - 1; i++) {
70  if (functions_[i] == nullptr) throw xtd::argument_null_exception(current_stack_frame_);
71  functions_[i]();
72  }
73  if (functions_.back() == nullptr) throw xtd::argument_null_exception(current_stack_frame_);
74  return functions_.back()();
75  }
76 
79  const std::vector<function_t>& functions() const {return functions_;}
80 
82  void clear() {functions_.clear();}
83 
87  result_t invoke() const { return operator()(); }
88 
94  static delegate combine(const std::vector<delegate>& delegates) noexcept {
95  delegate result;
96  for (const delegate& delegate : delegates) {
97  for (const function_t& function : delegate.functions_)
98  result.functions_.push_back(function);
99  }
100  return result;
101  }
102 
108  static delegate combine(const delegate& a, const delegate& b) noexcept {
109  delegate result = a;
110  for (const function_t& function : b.functions_)
111  result.functions_.push_back(function);
112  return result;
113  }
114 
117  bool is_empty() const noexcept { return functions_.size() == 0; }
118 
121  size_t size() const noexcept { return functions_.size(); }
122 
128  static delegate remove(const delegate& source, const delegate& value) noexcept {
129  delegate result = source;
130  for (const function_t& function : value.functions_) {
131  if (find(result.functions_.begin(), result.functions_.end(), function) != result.functions_.end()) {
132  for (typename std::vector<function_t>::reverse_iterator iterator = result.functions_.rbegin(); iterator != result.functions_.rend(); ++iterator) {
133  if (are_equals(*iterator, function)) {
134  result.functions_.erase((iterator + 1).base());
135  break;
136  }
137  }
138  }
139  }
140  return result;
141  }
142 
148  static delegate remove_all(const delegate& source, const delegate& value) noexcept {
149  delegate result = source;
150  for (const function_t& function : value.functions_) {
151  if (find(result.functions_.begin(), result.functions_.end(), function) != result.functions_.end()) {
152  for (typename std::vector<function_t>::reverse_iterator iterator = result.functions_.rbegin(); iterator != result.functions_.rend(); ++iterator) {
153  if (are_equals(*iterator, function)) {
154  result.functions_.erase((iterator + 1).base());
155  }
156  }
157  }
158  }
159  return result;
160  }
161 
165  bool operator ==(const delegate& delegate) const noexcept {
166  if (functions_.size() != delegate.functions_.size())
167  return false;
168 
169  for (size_t i = 0; i < functions_.size(); i++)
170  if (!are_equals(functions_[i], delegate.functions_[i]))
171  return false;
172 
173  return true;
174  }
175 
179  bool operator !=(const delegate& delegate) const { return !operator==(delegate); }
180 
181  delegate& operator=(const function_t& function) noexcept {
182  functions_.clear();
183  functions_.push_back(function);
184  return *this;
185  }
186 
188  delegate operator+(const delegate& other) noexcept {
189  delegate result = *this;
190  result += other;
191  return result;
192  }
193 
194  delegate operator+(const function_t& function) noexcept {
195  delegate result = *this;
196  result += function;
197  return result;
198  }
199 
200  delegate& operator+=(const delegate& delegate) noexcept {
201  *this = delegate::combine(*this, delegate);
202  return *this;
203  }
204 
205  delegate& operator+=(const function_t& function) noexcept {
206  *this = delegate::combine(*this, delegate(function));
207  return *this;
208  }
209 
210  delegate operator-(const delegate& other) noexcept {
211  delegate result = *this;
212  result -= other;
213  return result;
214  }
215 
216  delegate operator-(const function_t& function) noexcept {
217  delegate result = *this;
218  result -= function;
219  return result;
220  }
221 
222  delegate& operator-=(const delegate& delegate) noexcept {
223  *this = delegate::remove(*this, delegate);
224  return *this;
225  }
226 
227  delegate& operator-=(const function_t& function) noexcept {
228  *this = delegate::remove(*this, delegate(function));
229  return *this;
230  }
231 
232  template<typename fn_t>
233  delegate& operator-=(fn_t function) noexcept {
234  *this = delegate::remove(*this, delegate(function));
235  return *this;
236  }
237  // @endcond
238 
239  private:
240  static bool are_equals(const std::function<result_t()>& fct1, const std::function<result_t()>& fct2) noexcept {
241  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(*)()>());
242  }
243 
244  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 {
245  for (typename std::vector<function_t>::const_iterator iterator = begin; iterator != end; ++iterator)
246  if (are_equals(*iterator, function))
247  return iterator;
248  return end;
249  }
250 
251  std::vector<function_t> functions_;
252  };
253 
263  template<typename result_t, typename... arguments_t>
264  class delegate<result_t(arguments_t...)> : public object {
265  public:
267  using no_arguments_function_t = std::function <result_t()>;
269  using function_t = std::function <result_t(arguments_t...)>;
270 
272  delegate() = default;
275  delegate(const delegate& delegate) noexcept : no_arguments_functions_(delegate.no_arguments_functions_), functions_(delegate.functions_) {}
277  delegate& operator=(const delegate& delegate) noexcept {
278  no_arguments_functions_ = delegate.no_arguments_functions_;
279  functions_ = delegate.functions_;
280  return *this;
281  }
282  delegate(const delegate<result_t()>& delegate) noexcept : no_arguments_functions_(delegate.functions()) {}
284 
287  delegate(const function_t& function) noexcept {functions_.push_back(function);}
288 
290  delegate(const no_arguments_function_t& function) noexcept { no_arguments_functions_.push_back(function); }
292 
296  template<typename object1_t, typename object2_t>
297  delegate(const object1_t& object, result_t(object2_t::*method)() const) noexcept {
298  functions_.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object))));
299  }
300 
304  template<typename object1_t, typename object2_t>
305  delegate(const object1_t& object, result_t(object2_t::*method)()) noexcept {
306  functions_.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object))));
307  }
308 
310  template<typename object1_t, typename object2_t, typename a1_t>
311  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t) const) noexcept {
312  functions_.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1)));
313  }
314 
315  template<typename object1_t, typename object2_t, typename a1_t>
316  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t)) noexcept {
317  functions_.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1)));
318  }
319 
320  template<typename object1_t, typename object2_t, typename a1_t, typename a2_t>
321  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t) const) noexcept {
322  functions_.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2)));
323  }
324 
325  template<typename object1_t, typename object2_t, typename a1_t, typename a2_t>
326  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t)) noexcept {
327  functions_.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2)));
328  }
329 
330  template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t>
331  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t) const) noexcept {
332  functions_.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)));
333  }
334 
335  template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t>
336  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t)) noexcept {
337  functions_.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)));
338  }
339 
340  template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t>
341  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t) const) {
342  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)));
343  }
344 
345  template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t>
346  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t)) noexcept {
347  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)));
348  }
349 
350  template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t, typename A5>
351  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5) const) noexcept {
352  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)));
353  }
354 
355  template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t, typename A5>
356  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5)) {
357  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)));
358  }
359 
360  template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t, typename A5, typename a6_t>
361  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t) const) noexcept {
362  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)));
363  }
364 
365  template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t, typename A5, typename a6_t>
366  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t)) noexcept {
367  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)));
368  }
369 
370  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>
371  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 {
372  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)));
373  }
374 
375  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>
376  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t, a7_t)) noexcept {
377  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)));
378  }
379 
380  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>
381  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 {
382  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)));
383  }
384 
385  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>
386  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 {
387  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)));
388  }
389 
390  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>
391  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 {
392  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)));
393  }
394 
395  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>
396  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 {
397  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)));
398  }
399 
400  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>
401  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 {
402  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)));
403  }
404 
405  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>
406  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 {
407  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)));
408  }
410 
414  result_t operator()(arguments_t... arguments) const {
415  if (no_arguments_functions_.size() == 0 && functions_.size() == 0) return result_t();
416 
417  if (no_arguments_functions_.size()) {
418  for (size_t i = 0; i < no_arguments_functions_.size() - (functions_.size() == 0 ? 1 : 0); i++) {
419  if (no_arguments_functions_[i] == nullptr) throw xtd::argument_null_exception(current_stack_frame_);
420  no_arguments_functions_[i]();
421  }
422 
423  if (functions_.size() == 0) {
424  if (no_arguments_functions_.back() == nullptr) throw xtd::argument_null_exception(current_stack_frame_);
425  return no_arguments_functions_.back()();
426  }
427  }
428 
429  for (size_t i = 0; i < functions_.size() - 1; i++) {
430  if (functions_[i] == nullptr) throw xtd::argument_null_exception(current_stack_frame_);
431  functions_[i](arguments...);
432  }
433  if (functions_.back() == nullptr) throw xtd::argument_null_exception(current_stack_frame_);
434  return functions_.back()(arguments...);
435  }
436 
439  const std::vector<no_arguments_function_t>& no_arguments_functions() const {return no_arguments_functions_;}
440 
443  const std::vector<function_t>& functions() const {return functions_;}
444 
446  void clear() {
447  no_arguments_functions_.clear();
448  functions_.clear();
449  }
450 
454  result_t invoke(arguments_t... arguments) const { return operator()(arguments...); }
455 
461  static delegate combine(const std::vector<delegate>& delegates) noexcept {
462  delegate result;
463  for (const delegate& delegate : delegates) {
464  for (const no_arguments_function_t& function : delegate.no_arguments_functions_)
465  result.no_arguments_functions_.push_back(function);
466  for (const function_t& function : delegate.functions_)
467  result.functions_.push_back(function);
468  }
469  return result;
470  }
471 
477  static delegate combine(const delegate& a, const delegate& b) noexcept {
478  delegate result = a;
479  for (const no_arguments_function_t& function : b.no_arguments_functions_)
480  result.no_arguments_functions_.push_back(function);
481  for (const function_t& function : b.functions_)
482  result.functions_.push_back(function);
483  return result;
484  }
485 
488  bool is_empty() const noexcept { return functions_.size() == 0 && no_arguments_functions_.size() == 0; }
489 
492  size_t size() const noexcept { return functions_.size() + no_arguments_functions_.size(); }
493 
499  static delegate remove(const delegate& source, const delegate& value) noexcept {
500  delegate result = source;
501  for (const no_arguments_function_t& function : value.no_arguments_functions_) {
502  if (find(result.no_arguments_functions_.begin(), result.no_arguments_functions_.end(), function) != result.no_arguments_functions_.end()) {
503  for (typename std::vector<no_arguments_function_t>::reverse_iterator iterator = result.no_arguments_functions_.rbegin(); iterator != result.no_arguments_functions_.rend(); ++iterator) {
504  if (are_equals(*iterator, function)) {
505  result.no_arguments_functions_.erase((iterator + 1).base());
506  break;
507  }
508  }
509  }
510  }
511 
512  for (const function_t& function : value.functions_) {
513  if (find(result.functions_.begin(), result.functions_.end(), function) != result.functions_.end()) {
514  for (typename std::vector<function_t>::reverse_iterator iterator = result.functions_.rbegin(); iterator != result.functions_.rend(); ++iterator) {
515  if (are_equals(*iterator, function)) {
516  result.functions_.erase((iterator + 1).base());
517  break;
518  }
519  }
520  }
521  }
522  return result;
523  }
524 
530  static delegate remove_all(const delegate& source, const delegate& value) noexcept {
531  delegate result = source;
532  for (const no_arguments_function_t& function : value.no_arguments_functions_) {
533  if (find(result.no_arguments_functions_.begin(), result.no_arguments_functions_.end(), function) != result.no_arguments_functions_.end()) {
534  for (typename std::vector<function_t>::reverse_iterator iterator = result.no_arguments_functions_.rbegin(); iterator != result.no_arguments_functions_.rend(); ++iterator) {
535  if (are_equals(*iterator, function)) {
536  result.no_arguments_functions_.erase((iterator + 1).base());
537  }
538  }
539  }
540  }
541 
542  for (const function_t& function : value.functions_) {
543  if (find(result.functions_.begin(), result.functions_.end(), function) != result.functions_.end()) {
544  for (typename std::vector<function_t>::reverse_iterator iterator = result.functions_.rbegin(); iterator != result.functions_.rend(); ++iterator) {
545  if (are_equals(*iterator, function)) {
546  result.functions_.erase((iterator + 1).base());
547  }
548  }
549  }
550  }
551  return result;
552  }
553 
557  bool operator==(const delegate& delegate) const noexcept {
558  if (functions_.size() != delegate.functions_.size() || no_arguments_functions_.size() != delegate.no_arguments_functions_.size())
559  return false;
560 
561  for (size_t i = 0; i < no_arguments_functions_.size(); i++)
562  if (!are_equals(no_arguments_functions_[i], delegate.no_arguments_functions_[i]))
563  return false;
564 
565  for (size_t i = 0; i < functions_.size(); i++)
566  if (!are_equals(functions_[i], delegate.functions_[i]))
567  return false;
568 
569  return true;
570  }
571 
575  bool operator!=(const delegate& delegate) const { return !operator==(delegate); }
576 
578  template<typename type_t>
579  delegate& operator=(const type_t& function) noexcept {
580  no_arguments_functions_.clear();
581  functions_.clear();
582  functions_.push_back(function_t(function));
583  return *this;
584  }
585 
586  delegate& operator=(const function_t& function) noexcept {
587  no_arguments_functions_.clear();
588  functions_.clear();
589  functions_.push_back(function);
590  return *this;
591  }
592 
593  delegate& operator=(const no_arguments_function_t& function) noexcept {
594  no_arguments_functions_.clear();
595  functions_.clear();
596  no_arguments_functions_.push_back(function);
597  return *this;
598  }
599 
600  delegate operator+(const delegate& other) noexcept {
601  delegate result = *this;
602  result += other;
603  return result;
604  }
605 
606  delegate operator+(const no_arguments_function_t& function) noexcept {
607  delegate result = *this;
608  result += function;
609  return result;
610  }
611 
612  delegate operator+(const function_t& function) noexcept {
613  delegate result = *this;
614  result += function;
615  return result;
616  }
617 
618  template<typename fn_t>
619  delegate operator+(fn_t function) noexcept {
620  delegate result = *this;
621  result += function;
622  return result;
623  }
624 
625  delegate& operator+=(const delegate& delegate) noexcept {
626  *this = delegate::combine(*this, delegate);
627  return *this;
628  }
629 
630  delegate& operator+=(const no_arguments_function_t& function) noexcept {
631  *this = delegate::combine(*this, delegate(function));
632  return *this;
633  }
634 
635  delegate& operator+=(const function_t& function) noexcept {
636  *this = delegate::combine(*this, delegate(function));
637  return *this;
638  }
639 
640  template<typename fn_t>
641  delegate& operator+=(fn_t function) noexcept {
642  *this = delegate::combine(*this, delegate(function));
643  return *this;
644  }
645 
646  delegate operator-(const delegate& other) noexcept {
647  delegate result = *this;
648  result -= other;
649  return result;
650  }
651 
652  delegate operator-(const no_arguments_function_t& function) noexcept {
653  delegate result = *this;
654  result -= function;
655  return result;
656  }
657 
658  delegate operator-(const function_t& function) noexcept {
659  delegate result = *this;
660  result -= function;
661  return result;
662  }
663 
664  template<typename fn_t>
665  delegate operator-(fn_t function) noexcept {
666  delegate result = *this;
667  result -= function;
668  return result;
669  }
670 
671  delegate& operator-=(const delegate& delegate) noexcept {
672  *this = delegate::remove(*this, delegate);
673  return *this;
674  }
675 
676  delegate& operator-=(const no_arguments_function_t& function) noexcept {
677  *this = delegate::remove(*this, delegate(function));
678  return *this;
679  }
680 
681  delegate& operator-=(const function_t& function) noexcept {
682  *this = delegate::remove(*this, delegate(function));
683  return *this;
684  }
685 
686  template<typename fn_t>
687  delegate& operator-=(fn_t function) noexcept {
688  *this = delegate::remove(*this, delegate(function));
689  return *this;
690  }
692 
693  private:
694  static bool are_equals(const std::function<result_t(arguments_t...)>& fct1, const std::function<result_t(arguments_t...)>& fct2) noexcept {
695  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...)>());
696  }
697 
698  static bool are_equals(const std::function<result_t()>& fct1, const std::function<result_t()>& fct2) noexcept {
699  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(*)()>());
700  }
701 
702  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 {
703  for (typename std::vector<no_arguments_function_t>::const_iterator iterator = begin; iterator != end; ++iterator)
704  if (are_equals(*iterator, function))
705  return iterator;
706  return end;
707  }
708 
709  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 {
710  for (typename std::vector<function_t>::const_iterator iterator = begin; iterator != end; ++iterator)
711  if (are_equals(*iterator, function))
712  return iterator;
713  return end;
714  }
715 
716  std::vector<no_arguments_function_t> no_arguments_functions_;
717  std::vector<function_t> functions_;
718  };
719 }
The exception that is thrown when one of the arguments provided to a method is null.
Definition: argument_null_exception.h:18
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:297
result_t invoke(arguments_t... arguments) const
invokes the method represented by the current delegate.
Definition: delegate.h:454
std::function< result_t(arguments_t...)> function_t
function_t pointer type
Definition: delegate.h:269
size_t size() const noexcept
Return the size of invocation list.
Definition: delegate.h:121
size_t size() const noexcept
Return the size of invocation list.
Definition: delegate.h:492
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:52
std::function< result_t()> function_t
function_t pointer type
Definition: delegate.h:33
static delegate combine(const delegate &a, const delegate &b) noexcept
Concatenates the invocation lists of two delegates.
Definition: delegate.h:108
The xtd namespace contains all fundamental classes to access Hardware, Os, System, and more.
Definition: system_report.h:17
bool is_empty() const noexcept
Return if the delegate is empty.
Definition: delegate.h:117
delegate(const delegate &delegate) noexcept
Initializes a delegate that invokes the specified delegate instance.
Definition: delegate.h:275
bool is_empty() const noexcept
Return if the delegate is empty.
Definition: delegate.h:488
#define current_stack_frame_
Provides information about the current stack frame.
Definition: stack_frame.h:201
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:305
bool operator==(const delegate &delegate) const noexcept
Determines whether this instance and another specified delegateType object have the same value...
Definition: delegate.h:557
delegate(const function_t &function) noexcept
Initializes a delegate that invokes the specified instance method.
Definition: delegate.h:287
void clear()
Clear delegates array.
Definition: delegate.h:446
result_t invoke() const
invokes the method represented by the current delegate.
Definition: delegate.h:87
static delegate combine(const std::vector< delegate > &delegates) noexcept
Concatenates the invocation lists of an array of delegates.
Definition: delegate.h:94
Contains xtd::argument_null_exception exception.
void clear()
Clear delegates array.
Definition: delegate.h:82
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:59
static delegate combine(const std::vector< delegate > &delegates) noexcept
Concatenates the invocation lists of an array of delegates.
Definition: delegate.h:461
Contains xtd::object class.
Supports all classes in the xtd class hierarchy and provides low-level services to derived classes...
Definition: object.h:26
std::function< result_t()> no_arguments_function_t
no_arguments_function_t pointer type
Definition: delegate.h:267
const std::vector< function_t > & functions() const
Gets the delegates array.
Definition: delegate.h:443
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:530
const std::vector< function_t > & functions() const
Gets the delegates array.
Definition: delegate.h:79
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:148
delegate(const delegate &delegate) noexcept
Initializes a delegate that invokes the specified delegate instance.
Definition: delegate.h:39
result_t operator()() const
invokes the method represented by the current delegate.
Definition: delegate.h:66
bool operator!=(const delegate &delegate) const
Determines whether this instance and another specified delegateType object have the same value...
Definition: delegate.h:575
result_t operator()(arguments_t... arguments) const
invokes the method represented by the current delegate.
Definition: delegate.h:414
const std::vector< no_arguments_function_t > & no_arguments_functions() const
Gets the no arguments delegates array.
Definition: delegate.h:439
static delegate combine(const delegate &a, const delegate &b) noexcept
Concatenates the invocation lists of two delegates.
Definition: delegate.h:477