xtd 0.2.0
delegate.h
Go to the documentation of this file.
1 #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 
16 namespace 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;
81  delegate(const delegate& delegate) noexcept {
82  data_->functions = delegate.data_->functions;
83  }
85  delegate(const function_t& function) noexcept {data_->functions.push_back(function);} // Can't be explicit by design.
86  delegate& operator =(const delegate& delegate) noexcept {
87  data_->functions = delegate.data_->functions;
88  return *this;
89  }
91 
95  template<typename object1_t, typename object2_t>
96  delegate(const object1_t& object, result_t(object2_t::*method)() const) noexcept {
97  data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object))));
98  }
102  template<typename object1_t, typename object2_t>
103  delegate(const object1_t& object, result_t(object2_t::*method)()) noexcept {
104  data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object))));
105  }
107 
109 
113  const std::vector<function_t>& functions() const {return data_->functions;}
114 
117  bool is_empty() const noexcept {return data_->functions.size() == 0;}
118 
121  size_t size() const noexcept {return data_->functions.size();}
123 
125 
128  void clear() {data_->functions.clear();}
129 
135  async_result begin_invoke();
150  async_result begin_invoke(xtd::async_callback async_callback, std::any async_state);
151 
157  result_t end_invoke(async_result async);
158 
165  result_t invoke() const {return operator()();}
166 
172  static delegate combine(const std::vector<delegate>& delegates) noexcept {
173  delegate result;
174  for (const delegate& delegate : delegates) {
175  for (const function_t& function : delegate.data_->functions)
176  result.data_->functions.push_back(function);
177  }
178  return result;
179  }
180 
186  static delegate combine(const delegate& a, const delegate& b) noexcept {
187  delegate result = a;
188  for (const function_t& function : b.data_->functions)
189  result.data_->functions.push_back(function);
190  return result;
191  }
192 
196  bool equals(const delegate& delegate) const noexcept override {
197  if (data_->functions.size() != delegate.data_->functions.size())
198  return false;
199 
200  for (size_t i = 0; i < data_->functions.size(); i++)
201  if (!are_equals(data_->functions[i], delegate.data_->functions[i]))
202  return false;
203 
204  return true;
205  }
206 
212  static delegate remove(const delegate& source, const delegate& value) noexcept {
213  delegate result = source;
214  std::for_each(value.data_->functions.begin(), value.data_->functions.end(), [&](auto function) {
215  auto iterator = std::find_if(result.data_->functions.rbegin(), result.data_->functions.rend(), [&](auto item) {return are_equals(item, function);});
216  if (iterator != result.data_->functions.rend()) result.data_->functions.erase((iterator + 1).base());
217  });
218  return result;
219  }
220 
226  static delegate remove_all(const delegate& source, const delegate& value) noexcept {
227  delegate result = source;
228  for (const function_t& function : value.data_->functions) {
229  if (find(result.data_->functions.begin(), result.data_->functions.end(), function) != result.data_->functions.end()) {
230  for (typename std::vector<function_t>::reverse_iterator iterator = result.data_->functions.rbegin(); iterator != result.data_->functions.rend(); ++iterator) {
231  if (are_equals(*iterator, function))
232  result.data_->functions.erase((iterator + 1).base());
233  }
234  }
235  }
236  return result;
237  }
239 
241 
246  result_t operator()() const {
247  if (data_->functions.size() == 0) return result_t();
248 
249  for (size_t i = 0; i < data_->functions.size() - 1; i++) {
250  if (data_->functions[i] == nullptr) throw xtd::argument_null_exception {csf_};
251  data_->functions[i]();
252  }
253  if (data_->functions.back() == nullptr) throw xtd::argument_null_exception {csf_};
254  return data_->functions.back()();
255  }
256 
257  delegate& operator =(const function_t& function) noexcept {
258  data_->functions.clear();
259  data_->functions.push_back(function);
260  return *this;
261  }
263 
265  delegate operator +(const delegate& other) noexcept {
266  delegate result = *this;
267  result += other;
268  return result;
269  }
270 
271  delegate operator +(const function_t& function) noexcept {
272  delegate result = *this;
273  result += function;
274  return result;
275  }
276 
277  template<typename fn_t>
278  delegate operator +(fn_t function) noexcept {
279  delegate result = *this;
280  result += function;
281  return result;
282  }
283 
284  delegate& operator +=(const delegate& delegate) noexcept {
285  *this = delegate::combine(*this, delegate);
286  return *this;
287  }
288 
289  delegate& operator +=(const function_t& function) noexcept {
290  *this = delegate::combine(*this, delegate(function));
291  return *this;
292  }
293 
294  template<typename fn_t>
295  delegate& operator +=(fn_t function) noexcept {
296  *this = delegate::combine(*this, delegate(function));
297  return *this;
298  }
299 
300  delegate operator -(const delegate& other) noexcept {
301  delegate result = *this;
302  result -= other;
303  return result;
304  }
305 
306  delegate operator -(const function_t& function) noexcept {
307  delegate result = *this;
308  result -= function;
309  return result;
310  }
311 
312  template<typename fn_t>
313  delegate operator -(fn_t function) noexcept {
314  delegate result = *this;
315  result -= function;
316  return result;
317  }
318 
319  delegate& operator -=(const delegate& delegate) noexcept {
320  *this = delegate::remove(*this, delegate);
321  return *this;
322  }
323 
324  delegate& operator -=(const function_t& function) noexcept {
325  *this = delegate::remove(*this, delegate(function));
326  return *this;
327  }
328 
329  template<typename fn_t>
330  delegate& operator -=(fn_t function) noexcept {
331  *this = delegate::remove(*this, delegate(function));
332  return *this;
333  }
334  // @endcond
335 
336  private:
337  static bool are_equals(const std::function<result_t()>& fct1, const std::function<result_t()>& fct2) noexcept {
338  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(*)()>());
339  }
340 
341  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 {
342  auto iterator = std::find_if(begin, end, [&](auto item) {return are_equals(item, function);});
343  if (iterator != end) return iterator;
344  return end;
345  }
346  std::shared_ptr<data> data_ = std::make_shared<data>();
347  };
348 
361  template<typename result_t, typename... arguments_t>
362  class delegate<result_t(arguments_t...)> : public object, public xtd::iequatable<delegate<result_t(arguments_t...)>> {
363  struct data {
364  std::vector<std::function <result_t()>> no_arguments_functions;
365  std::vector<std::function <result_t(arguments_t...)>> functions;
366  };
367 
368  class async_result_invoke : public xtd::iasync_result {
369  struct data;
370  public:
371  async_result_invoke(xtd::async_callback async_callback, std::any async_state);
372  std::any async_state() const noexcept override;
373  xtd::threading::wait_handle& async_wait_handle() noexcept override;
374  bool completed_synchronously() const noexcept override;
375  bool is_completed() const noexcept override;
376 
377  std::shared_ptr<data> data_;
378  };
379 
380  public:
382 
385  using no_arguments_function_t = std::function <result_t()>;
387  using function_t = std::function <result_t(arguments_t...)>;
389 
391 
394  delegate() = default;
397  delegate(const delegate& delegate) noexcept {
398  data_->no_arguments_functions = delegate.data_->no_arguments_functions;
399  data_->functions = delegate.data_->functions;
400  }
402  delegate& operator =(const delegate& delegate) noexcept {
403  data_->no_arguments_functions = delegate.data_->no_arguments_functions;
404  data_->functions = delegate.data_->functions;
405  return *this;
406  }
407  delegate(const delegate<result_t()>& delegate) noexcept {
408  data_->no_arguments_functions = delegate.functions();
409  }
411 
414  delegate(const function_t& function) noexcept {data_->functions.push_back(function);} // Can't be explicit by design.
415 
417  delegate(const no_arguments_function_t& function) noexcept {data_->no_arguments_functions.push_back(function);} // Can't be explicit by design.
419 
423  template<typename object1_t, typename object2_t>
424  delegate(const object1_t& object, result_t(object2_t::*method)() const) noexcept {
425  data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object))));
426  }
427 
431  template<typename object1_t, typename object2_t>
432  delegate(const object1_t& object, result_t(object2_t::*method)()) noexcept {
433  data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object))));
434  }
436 
438  template<typename object1_t, typename object2_t, typename a1_t>
439  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t) const) noexcept {
440  data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1)));
441  }
442 
443  template<typename object1_t, typename object2_t, typename a1_t>
444  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t)) noexcept {
445  data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1)));
446  }
447 
448  template<typename object1_t, typename object2_t, typename a1_t, typename a2_t>
449  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t) const) noexcept {
450  data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2)));
451  }
452 
453  template<typename object1_t, typename object2_t, typename a1_t, typename a2_t>
454  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t)) noexcept {
455  data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2)));
456  }
457 
458  template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t>
459  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t) const) noexcept {
460  data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)));
461  }
462 
463  template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t>
464  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t)) noexcept {
465  data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)));
466  }
467 
468  template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t>
469  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t) const) {
470  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)));
471  }
472 
473  template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t>
474  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t)) noexcept {
475  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)));
476  }
477 
478  template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t, typename A5>
479  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5) const) noexcept {
480  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)));
481  }
482 
483  template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t, typename A5>
484  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5)) {
485  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)));
486  }
487 
488  template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t, typename A5, typename a6_t>
489  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t) const) noexcept {
490  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)));
491  }
492 
493  template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t, typename A5, typename a6_t>
494  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t)) noexcept {
495  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)));
496  }
497 
498  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>
499  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 {
500  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)));
501  }
502 
503  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>
504  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t, a7_t)) noexcept {
505  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)));
506  }
507 
508  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>
509  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 {
510  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)));
511  }
512 
513  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>
514  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 {
515  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)));
516  }
517 
518  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>
519  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 {
520  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)));
521  }
522 
523  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>
524  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 {
525  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)));
526  }
527 
528  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>
529  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 {
530  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)));
531  }
532 
533  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>
534  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 {
535  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)));
536  }
538 
540 
544  const std::vector<no_arguments_function_t>& no_arguments_functions() const {return data_->no_arguments_functions;}
545 
548  const std::vector<function_t>& functions() const {return data_->functions;}
549 
552  bool is_empty() const noexcept {return data_->functions.size() == 0 && data_->no_arguments_functions.size() == 0;}
553 
556  size_t size() const noexcept {return data_->functions.size() + data_->no_arguments_functions.size();}
558 
560 
570  async_result begin_invoke(arguments_t... arguments);
578  async_result begin_invoke(xtd::async_callback async_callback, arguments_t... arguments);
585  async_result begin_invoke(xtd::async_callback async_callback, std::any async_state, arguments_t... arguments);
586 
592  result_t end_invoke(async_result async);
593 
600  result_t invoke(arguments_t... arguments) const {return operator()(arguments...);}
601 
607  static delegate combine(const std::vector<delegate>& delegates) noexcept {
608  delegate result;
609  for (const delegate& delegate : delegates) {
610  for (const no_arguments_function_t& function : delegate.data_->no_arguments_functions)
611  result.data_->no_arguments_functions.push_back(function);
612  for (const function_t& function : delegate.data_->functions)
613  result.data_->functions.push_back(function);
614  }
615  return result;
616  }
617 
623  static delegate combine(const delegate& a, const delegate& b) noexcept {
624  delegate result = a;
625  for (const no_arguments_function_t& function : b.data_->no_arguments_functions)
626  result.data_->no_arguments_functions.push_back(function);
627  for (const function_t& function : b.data_->functions)
628  result.data_->functions.push_back(function);
629  return result;
630  }
631 
635  bool equals(const delegate& delegate) const noexcept override {
636  if (data_->functions.size() != delegate.data_->functions.size() || data_->no_arguments_functions.size() != delegate.data_->no_arguments_functions.size())
637  return false;
638 
639  for (size_t i = 0; i < data_->no_arguments_functions.size(); i++)
640  if (!are_equals(data_->no_arguments_functions[i], delegate.data_->no_arguments_functions[i]))
641  return false;
642 
643  for (size_t i = 0; i < data_->functions.size(); i++)
644  if (!are_equals(data_->functions[i], delegate.data_->functions[i]))
645  return false;
646 
647  return true;
648  }
649 
655  static delegate remove(const delegate& source, const delegate& value) noexcept {
656  delegate result = source;
657  std::for_each(value.data_->no_arguments_functions.begin(), value.data_->no_arguments_functions.end(), [&](auto no_arguments_function) {
658  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);});
659  if (iterator != result.data_->no_arguments_functions.rend()) result.data_->no_arguments_functions.erase((iterator + 1).base());
660  });
661 
662  std::for_each(value.data_->functions.begin(), value.data_->functions.end(), [&](auto function) {
663  auto iterator = std::find_if(result.data_->functions.rbegin(), result.data_->functions.rend(), [&](auto item) {return are_equals(item, function);});
664  if (iterator != result.data_->functions.rend()) result.data_->functions.erase((iterator + 1).base());
665  });
666  return result;
667  }
668 
674  static delegate remove_all(const delegate& source, const delegate& value) noexcept {
675  delegate result = source;
676  for (const no_arguments_function_t& function : value.data_->no_arguments_functions) {
677  if (find(result.data_->no_arguments_functions.begin(), result.data_->no_arguments_functions.end(), function) != result.data_->no_arguments_functions.end()) {
678  for (typename std::vector<function_t>::reverse_iterator iterator = result.data_->no_arguments_functions.rbegin(); iterator != result.data_->no_arguments_functions.rend(); ++iterator) {
679  if (are_equals(*iterator, function))
680  result.data_->no_arguments_functions.erase((iterator + 1).base());
681  }
682  }
683  }
684 
685  for (const function_t& function : value.data_->functions) {
686  if (find(result.data_->functions.begin(), result.data_->functions.end(), function) != result.data_->functions.end()) {
687  for (typename std::vector<function_t>::reverse_iterator iterator = result.data_->functions.rbegin(); iterator != result.data_->functions.rend(); ++iterator) {
688  if (are_equals(*iterator, function))
689  result.data_->functions.erase((iterator + 1).base());
690  }
691  }
692  }
693  return result;
694  }
696 
698 
703  result_t operator()(arguments_t... arguments) const {
704  if (data_->no_arguments_functions.size() == 0 && data_->functions.size() == 0) return result_t();
705 
706  if (data_->no_arguments_functions.size()) {
707  for (size_t i = 0; i < data_->no_arguments_functions.size() - (data_->functions.size() == 0 ? 1 : 0); i++) {
708  if (data_->no_arguments_functions[i] == nullptr) throw xtd::argument_null_exception {csf_};
709  data_->no_arguments_functions[i]();
710  }
711 
712  if (data_->functions.size() == 0) {
713  if (data_->no_arguments_functions.back() == nullptr) throw xtd::argument_null_exception {csf_};
714  return data_->no_arguments_functions.back()();
715  }
716  }
717 
718  for (size_t i = 0; i < data_->functions.size() - 1; i++) {
719  if (data_->functions[i] == nullptr) throw xtd::argument_null_exception {csf_};
720  data_->functions[i](arguments...);
721  }
722  if (data_->functions.back() == nullptr) throw xtd::argument_null_exception {csf_};
723  return data_->functions.back()(arguments...);
724  }
726 
728  template<typename type_t>
729  delegate& operator =(const type_t& function) noexcept {
730  data_->no_arguments_functions.clear();
731  data_->functions.clear();
732  data_->functions.push_back(function_t(function));
733  return *this;
734  }
735 
736  delegate& operator =(const function_t& function) noexcept {
737  data_->no_arguments_functions.clear();
738  data_->functions.clear();
739  data_->functions.push_back(function);
740  return *this;
741  }
742 
743  delegate& operator =(const no_arguments_function_t& function) noexcept {
744  data_->no_arguments_functions.clear();
745  data_->functions.clear();
746  data_->no_arguments_functions.push_back(function);
747  return *this;
748  }
749 
750  delegate operator +(const delegate& other) noexcept {
751  delegate result = *this;
752  result += other;
753  return result;
754  }
755 
756  delegate operator +(const no_arguments_function_t& function) noexcept {
757  delegate result = *this;
758  result += function;
759  return result;
760  }
761 
762  delegate operator +(const function_t& function) noexcept {
763  delegate result = *this;
764  result += function;
765  return result;
766  }
767 
768  template<typename fn_t>
769  delegate operator +(fn_t function) noexcept {
770  delegate result = *this;
771  result += function;
772  return result;
773  }
774 
775  delegate& operator +=(const delegate& delegate) noexcept {
776  *this = delegate::combine(*this, delegate);
777  return *this;
778  }
779 
780  delegate& operator +=(const no_arguments_function_t& function) noexcept {
781  *this = delegate::combine(*this, delegate(function));
782  return *this;
783  }
784 
785  delegate& operator +=(const function_t& function) noexcept {
786  *this = delegate::combine(*this, delegate(function));
787  return *this;
788  }
789 
790  template<typename fn_t>
791  delegate& operator +=(fn_t function) noexcept {
792  *this = delegate::combine(*this, delegate(function));
793  return *this;
794  }
795 
796  delegate operator -(const delegate& other) noexcept {
797  delegate result = *this;
798  result -= other;
799  return result;
800  }
801 
802  delegate operator -(const no_arguments_function_t& function) noexcept {
803  delegate result = *this;
804  result -= function;
805  return result;
806  }
807 
808  delegate operator -(const function_t& function) noexcept {
809  delegate result = *this;
810  result -= function;
811  return result;
812  }
813 
814  template<typename fn_t>
815  delegate operator -(fn_t function) noexcept {
816  delegate result = *this;
817  result -= function;
818  return result;
819  }
820 
821  delegate& operator -=(const delegate& delegate) noexcept {
822  *this = delegate::remove(*this, delegate);
823  return *this;
824  }
825 
826  delegate& operator -=(const no_arguments_function_t& function) noexcept {
827  *this = delegate::remove(*this, delegate(function));
828  return *this;
829  }
830 
831  delegate& operator -=(const function_t& function) noexcept {
832  *this = delegate::remove(*this, delegate(function));
833  return *this;
834  }
835 
836  template<typename fn_t>
837  delegate& operator -=(fn_t function) noexcept {
838  *this = delegate::remove(*this, delegate(function));
839  return *this;
840  }
842 
843  private:
844  static bool are_equals(const std::function<result_t(arguments_t...)>& fct1, const std::function<result_t(arguments_t...)>& fct2) noexcept {
845  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...)>());
846  }
847 
848  static bool are_equals(const std::function<result_t()>& fct1, const std::function<result_t()>& fct2) noexcept {
849  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(*)()>());
850  }
851 
852  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 {
853  auto iterator = std::find_if(begin, end, [&](auto item) {return are_equals(item, function);});
854  if (iterator != end) return iterator;
855  return end;
856  }
857 
858  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 {
859  auto iterator = std::find_if(begin, end, [&](auto item) {return are_equals(item, function);});
860  if (iterator != end) return iterator;
861  return end;
862  }
863 
864  std::shared_ptr<data> data_ = std::make_shared<data>();
865  };
866 }
867 
868 // Required for begin_invoke and end_invoke methods implementation.
869 #include "threading/thread_pool.h"
The exception that is thrown when one of the arguments provided to a method is null.
Definition: argument_null_exception.h:20
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:424
Contains xtd::iequatable interface.
delegate< void(async_result ar)> async_callback
References a method to be called when a corresponding asynchronous operation completes.
Definition: delegate.h:34
Represents the status of an asynchronous operation.
Definition: iasync_result.h:22
result_t invoke(arguments_t... arguments) const
invokes the method represented by the current delegate.
Definition: delegate.h:600
std::function< result_t(arguments_t...)> function_t
function_t pointer type
Definition: delegate.h:387
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:556
bool equals(const delegate &delegate) const noexcept override
Determines whether this instance and another specified delegateType object have the same value...
Definition: delegate.h:196
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:96
std::function< result_t()> function_t
function_t pointer type
Definition: delegate.h:71
static delegate combine(const delegate &a, const delegate &b) noexcept
Concatenates the invocation lists of two delegates.
Definition: delegate.h:186
The xtd namespace contains all fundamental classes to access Hardware, Os, System, and more.
Definition: system_report.h:17
std::shared_ptr< xtd::iasync_result > async_result
Represents the status of an asynchronous operation.
Definition: async_result.h:16
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:397
bool is_empty() const noexcept
Return if the delegate is empty.
Definition: delegate.h:552
#define csf_
Provides information about the current stack frame.
Definition: current_stack_frame.h:30
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:432
delegate(const function_t &function) noexcept
Initializes a delegate that invokes the specified instance method.
Definition: delegate.h:414
result_t invoke() const
invokes the method represented by the current delegate.
Definition: delegate.h:165
Contains xtd::object_ref alias.
static delegate combine(const std::vector< delegate > &delegates) noexcept
Concatenates the invocation lists of an array of delegates.
Definition: delegate.h:172
Contains std::any type and std::bad_any_cast exception.
Contains xtd::argument_null_exception exception.
Defines a generalized method that a value type or class implements to create a type-specific method f...
Definition: iequatable.h:18
void clear()
Clear delegates array.
Definition: delegate.h:128
The operating system is other.
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:103
Indicates that all styles except allow_binary_specifier, allow_octal_specifier and allow_hex_specifie...
static delegate combine(const std::vector< delegate > &delegates) noexcept
Concatenates the invocation lists of an array of delegates.
Definition: delegate.h:607
bool equals(const delegate &delegate) const noexcept override
Determines whether this instance and another specified delegateType object have the same value...
Definition: delegate.h:635
Contains xtd::object class.
Supports all classes in the xtd class hierarchy and provides low-level services to derived classes...
Definition: object.h:32
std::function< result_t()> no_arguments_function_t
no_arguments_function_t pointer type
Definition: delegate.h:385
Contains xtd::async_result alias.
const std::vector< function_t > & functions() const
Gets the delegates array.
Definition: delegate.h:548
Contains xtd::threading::thread_pool class.
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:674
const std::vector< function_t > & functions() const
Gets the delegates array.
Definition: delegate.h:113
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:226
delegate(const delegate &delegate) noexcept
Initializes a delegate that invokes the specified delegate instance.
Definition: delegate.h:81
result_t operator()() const
invokes the method represented by the current delegate.
Definition: delegate.h:246
result_t operator()(arguments_t... arguments) const
invokes the method represented by the current delegate.
Definition: delegate.h:703
const std::vector< no_arguments_function_t > & no_arguments_functions() const
Gets the no arguments delegates array.
Definition: delegate.h:544
Encapsulates operating system specific objects that wait for exclusive access to shared resources...
Definition: wait_handle.h:48
static delegate combine(const delegate &a, const delegate &b) noexcept
Concatenates the invocation lists of two delegates.
Definition: delegate.h:623