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 
36  using function_t = std::function <result_t()>;
38 
40 
43  delegate() = default;
46  delegate(const delegate& delegate) noexcept {
47  data_->functions = delegate.data_->functions;
48  }
50  delegate(const function_t& function) noexcept { data_->functions.push_back(function); }
51  delegate& operator=(const delegate& delegate) noexcept {
52  data_->functions = delegate.data_->functions;
53  return *this;
54  }
56 
60  template<typename object1_t, typename object2_t>
61  delegate(const object1_t& object, result_t(object2_t::*method)() const) noexcept {
62  data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object))));
63  }
67  template<typename object1_t, typename object2_t>
68  delegate(const object1_t& object, result_t(object2_t::*method)()) noexcept {
69  data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object))));
70  }
72 
74 
78  const std::vector<function_t>& functions() const {return data_->functions;}
79 
81  void clear() {data_->functions.clear();}
82 
86  result_t invoke() const { return operator()(); }
87 
93  static delegate combine(const std::vector<delegate>& delegates) noexcept {
94  delegate result;
95  for (const delegate& delegate : delegates) {
96  for (const function_t& function : delegate.data_->functions)
97  result.data_->functions.push_back(function);
98  }
99  return result;
100  }
101 
107  static delegate combine(const delegate& a, const delegate& b) noexcept {
108  delegate result = a;
109  for (const function_t& function : b.data_->functions)
110  result.data_->functions.push_back(function);
111  return result;
112  }
113 
116  bool is_empty() const noexcept { return data_->functions.size() == 0; }
117 
120  size_t size() const noexcept { return data_->functions.size(); }
121 
127  static delegate remove(const delegate& source, const delegate& value) noexcept {
128  delegate result = source;
129  for (const function_t& function : value.data_->functions) {
130  if (find(result.data_->functions.begin(), result.data_->functions.end(), function) != result.data_->functions.end()) {
131  for (typename std::vector<function_t>::reverse_iterator iterator = result.data_->functions.rbegin(); iterator != result.data_->functions.rend(); ++iterator) {
132  if (are_equals(*iterator, function)) {
133  result.data_->functions.erase((iterator + 1).base());
134  break;
135  }
136  }
137  }
138  }
139  return result;
140  }
141 
147  static delegate remove_all(const delegate& source, const delegate& value) noexcept {
148  delegate result = source;
149  for (const function_t& function : value.data_->functions) {
150  if (find(result.data_->functions.begin(), result.data_->functions.end(), function) != result.data_->functions.end()) {
151  for (typename std::vector<function_t>::reverse_iterator iterator = result.data_->functions.rbegin(); iterator != result.data_->functions.rend(); ++iterator) {
152  if (are_equals(*iterator, function))
153  result.data_->functions.erase((iterator + 1).base());
154  }
155  }
156  }
157  return result;
158  }
160 
162 
167  result_t operator()() const {
168  if (data_->functions.size() == 0) return result_t();
169 
170  for (size_t i = 0; i < data_->functions.size() - 1; i++) {
171  if (data_->functions[i] == nullptr) throw xtd::argument_null_exception(current_stack_frame_);
172  data_->functions[i]();
173  }
174  if (data_->functions.back() == nullptr) throw xtd::argument_null_exception(current_stack_frame_);
175  return data_->functions.back()();
176  }
177 
181  bool operator ==(const delegate& delegate) const noexcept {
182  if (data_->functions.size() != delegate.data_->functions.size())
183  return false;
184 
185  for (size_t i = 0; i < data_->functions.size(); i++)
186  if (!are_equals(data_->functions[i], delegate.data_->functions[i]))
187  return false;
188 
189  return true;
190  }
191 
195  bool operator !=(const delegate& delegate) const { return !operator==(delegate); }
196 
197  delegate& operator=(const function_t& function) noexcept {
198  data_->functions.clear();
199  data_->functions.push_back(function);
200  return *this;
201  }
203 
205  delegate operator+(const delegate& other) noexcept {
206  delegate result = *this;
207  result += other;
208  return result;
209  }
210 
211  delegate operator+(const function_t& function) noexcept {
212  delegate result = *this;
213  result += function;
214  return result;
215  }
216 
217  delegate& operator+=(const delegate& delegate) noexcept {
218  *this = delegate::combine(*this, delegate);
219  return *this;
220  }
221 
222  delegate& operator+=(const function_t& function) noexcept {
223  *this = delegate::combine(*this, delegate(function));
224  return *this;
225  }
226 
227  delegate operator-(const delegate& other) noexcept {
228  delegate result = *this;
229  result -= other;
230  return result;
231  }
232 
233  delegate operator-(const function_t& function) noexcept {
234  delegate result = *this;
235  result -= function;
236  return result;
237  }
238 
239  delegate& operator-=(const delegate& delegate) noexcept {
240  *this = delegate::remove(*this, delegate);
241  return *this;
242  }
243 
244  delegate& operator-=(const function_t& function) noexcept {
245  *this = delegate::remove(*this, delegate(function));
246  return *this;
247  }
248 
249  template<typename fn_t>
250  delegate& operator-=(fn_t function) noexcept {
251  *this = delegate::remove(*this, delegate(function));
252  return *this;
253  }
254  // @endcond
255 
256  private:
257  static bool are_equals(const std::function<result_t()>& fct1, const std::function<result_t()>& fct2) noexcept {
258  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(*)()>());
259  }
260 
261  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 {
262  for (typename std::vector<function_t>::const_iterator iterator = begin; iterator != end; ++iterator)
263  if (are_equals(*iterator, function))
264  return iterator;
265  return end;
266  }
267 
268  struct data {
269  std::vector<function_t> functions;
270  };
271  std::shared_ptr<data> data_ = std::make_shared<data>();
272  };
273 
283  template<typename result_t, typename... arguments_t>
284  class delegate<result_t(arguments_t...)> : public object {
285  public:
287 
290  using no_arguments_function_t = std::function <result_t()>;
292  using function_t = std::function <result_t(arguments_t...)>;
294 
296 
299  delegate() = default;
302  delegate(const delegate& delegate) noexcept {
303  data_->no_arguments_functions = delegate.data_->no_arguments_functions;
304  data_->functions = delegate.data_->functions;
305  }
307  delegate& operator=(const delegate& delegate) noexcept {
308  data_->no_arguments_functions = delegate.data_->no_arguments_functions;
309  data_->functions = delegate.data_->functions;
310  return *this;
311  }
312  delegate(const delegate<result_t()>& delegate) noexcept {
313  data_->no_arguments_functions = delegate.functions();
314  }
316 
319  delegate(const function_t& function) noexcept {data_->functions.push_back(function);}
320 
322  delegate(const no_arguments_function_t& function) noexcept { data_->no_arguments_functions.push_back(function); }
324 
328  template<typename object1_t, typename object2_t>
329  delegate(const object1_t& object, result_t(object2_t::*method)() const) noexcept {
330  data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object))));
331  }
332 
336  template<typename object1_t, typename object2_t>
337  delegate(const object1_t& object, result_t(object2_t::*method)()) noexcept {
338  data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object))));
339  }
341 
343  template<typename object1_t, typename object2_t, typename a1_t>
344  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t) const) noexcept {
345  data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1)));
346  }
347 
348  template<typename object1_t, typename object2_t, typename a1_t>
349  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t)) noexcept {
350  data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1)));
351  }
352 
353  template<typename object1_t, typename object2_t, typename a1_t, typename a2_t>
354  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t) const) noexcept {
355  data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2)));
356  }
357 
358  template<typename object1_t, typename object2_t, typename a1_t, typename a2_t>
359  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t)) noexcept {
360  data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2)));
361  }
362 
363  template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t>
364  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t) const) noexcept {
365  data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)));
366  }
367 
368  template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t>
369  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t)) noexcept {
370  data_->functions.push_back(function_t(std::bind(method, const_cast<object1_t*>(&object), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)));
371  }
372 
373  template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t>
374  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t) const) {
375  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)));
376  }
377 
378  template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t>
379  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t)) noexcept {
380  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)));
381  }
382 
383  template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t, typename A5>
384  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5) const) noexcept {
385  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)));
386  }
387 
388  template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t, typename A5>
389  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5)) {
390  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)));
391  }
392 
393  template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t, typename A5, typename a6_t>
394  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t) const) noexcept {
395  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)));
396  }
397 
398  template<typename object1_t, typename object2_t, typename a1_t, typename a2_t, typename a3_t, typename a4_t, typename A5, typename a6_t>
399  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t)) noexcept {
400  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)));
401  }
402 
403  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>
404  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 {
405  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)));
406  }
407 
408  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>
409  delegate(const object1_t& object, result_t(object2_t::*method)(a1_t, a2_t, a3_t, a4_t, A5, a6_t, a7_t)) noexcept {
410  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)));
411  }
412 
413  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>
414  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 {
415  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)));
416  }
417 
418  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>
419  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 {
420  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)));
421  }
422 
423  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>
424  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 {
425  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)));
426  }
427 
428  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>
429  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 {
430  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)));
431  }
432 
433  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>
434  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 {
435  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)));
436  }
437 
438  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>
439  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 {
440  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)));
441  }
443 
445 
449  const std::vector<no_arguments_function_t>& no_arguments_functions() const {return data_->no_arguments_functions;}
450 
453  const std::vector<function_t>& functions() const {return data_->functions;}
454 
456  void clear() {
457  data_->no_arguments_functions.clear();
458  data_->functions.clear();
459  }
460 
464  result_t invoke(arguments_t... arguments) const { return operator()(arguments...); }
465 
471  static delegate combine(const std::vector<delegate>& delegates) noexcept {
472  delegate result;
473  for (const delegate& delegate : delegates) {
474  for (const no_arguments_function_t& function : delegate.data_->no_arguments_functions)
475  result.data_->no_arguments_functions.push_back(function);
476  for (const function_t& function : delegate.data_->functions)
477  result.data_->functions.push_back(function);
478  }
479  return result;
480  }
481 
487  static delegate combine(const delegate& a, const delegate& b) noexcept {
488  delegate result = a;
489  for (const no_arguments_function_t& function : b.data_->no_arguments_functions)
490  result.data_->no_arguments_functions.push_back(function);
491  for (const function_t& function : b.data_->functions)
492  result.data_->functions.push_back(function);
493  return result;
494  }
495 
498  bool is_empty() const noexcept { return data_->functions.size() == 0 && data_->no_arguments_functions.size() == 0; }
499 
502  size_t size() const noexcept { return data_->functions.size() + data_->no_arguments_functions.size(); }
503 
509  static delegate remove(const delegate& source, const delegate& value) noexcept {
510  delegate result = source;
511  for (const no_arguments_function_t& function : value.data_->no_arguments_functions) {
512  if (find(result.data_->no_arguments_functions.begin(), result.data_->no_arguments_functions.end(), function) != result.data_->no_arguments_functions.end()) {
513  for (typename std::vector<no_arguments_function_t>::reverse_iterator iterator = result.data_->no_arguments_functions.rbegin(); iterator != result.data_->no_arguments_functions.rend(); ++iterator) {
514  if (are_equals(*iterator, function)) {
515  result.data_->no_arguments_functions.erase((iterator + 1).base());
516  break;
517  }
518  }
519  }
520  }
521 
522  for (const function_t& function : value.data_->functions) {
523  if (find(result.data_->functions.begin(), result.data_->functions.end(), function) != result.data_->functions.end()) {
524  for (typename std::vector<function_t>::reverse_iterator iterator = result.data_->functions.rbegin(); iterator != result.data_->functions.rend(); ++iterator) {
525  if (are_equals(*iterator, function)) {
526  result.data_->functions.erase((iterator + 1).base());
527  break;
528  }
529  }
530  }
531  }
532  return result;
533  }
534 
540  static delegate remove_all(const delegate& source, const delegate& value) noexcept {
541  delegate result = source;
542  for (const no_arguments_function_t& function : value.data_->no_arguments_functions) {
543  if (find(result.data_->no_arguments_functions.begin(), result.data_->no_arguments_functions.end(), function) != result.data_->no_arguments_functions.end()) {
544  for (typename std::vector<function_t>::reverse_iterator iterator = result.data_->no_arguments_functions.rbegin(); iterator != result.data_->no_arguments_functions.rend(); ++iterator) {
545  if (are_equals(*iterator, function))
546  result.data_->no_arguments_functions.erase((iterator + 1).base());
547  }
548  }
549  }
550 
551  for (const function_t& function : value.data_->functions) {
552  if (find(result.data_->functions.begin(), result.data_->functions.end(), function) != result.data_->functions.end()) {
553  for (typename std::vector<function_t>::reverse_iterator iterator = result.data_->functions.rbegin(); iterator != result.data_->functions.rend(); ++iterator) {
554  if (are_equals(*iterator, function))
555  result.data_->functions.erase((iterator + 1).base());
556  }
557  }
558  }
559  return result;
560  }
562 
564 
569  result_t operator()(arguments_t... arguments) const {
570  if (data_->no_arguments_functions.size() == 0 && data_->functions.size() == 0) return result_t();
571 
572  if (data_->no_arguments_functions.size()) {
573  for (size_t i = 0; i < data_->no_arguments_functions.size() - (data_->functions.size() == 0 ? 1 : 0); i++) {
574  if (data_->no_arguments_functions[i] == nullptr) throw xtd::argument_null_exception(current_stack_frame_);
575  data_->no_arguments_functions[i]();
576  }
577 
578  if (data_->functions.size() == 0) {
579  if (data_->no_arguments_functions.back() == nullptr) throw xtd::argument_null_exception(current_stack_frame_);
580  return data_->no_arguments_functions.back()();
581  }
582  }
583 
584  for (size_t i = 0; i < data_->functions.size() - 1; i++) {
585  if (data_->functions[i] == nullptr) throw xtd::argument_null_exception(current_stack_frame_);
586  data_->functions[i](arguments...);
587  }
588  if (data_->functions.back() == nullptr) throw xtd::argument_null_exception(current_stack_frame_);
589  return data_->functions.back()(arguments...);
590  }
591 
595  bool operator==(const delegate& delegate) const noexcept {
596  if (data_->functions.size() != delegate.data_->functions.size() || data_->no_arguments_functions.size() != delegate.data_->no_arguments_functions.size())
597  return false;
598 
599  for (size_t i = 0; i < data_->no_arguments_functions.size(); i++)
600  if (!are_equals(data_->no_arguments_functions[i], delegate.data_->no_arguments_functions[i]))
601  return false;
602 
603  for (size_t i = 0; i < data_->functions.size(); i++)
604  if (!are_equals(data_->functions[i], delegate.data_->functions[i]))
605  return false;
606 
607  return true;
608  }
609 
613  bool operator!=(const delegate& delegate) const { return !operator==(delegate); }
615 
617  template<typename type_t>
618  delegate& operator=(const type_t& function) noexcept {
619  data_->no_arguments_functions.clear();
620  data_->functions.clear();
621  data_->functions.push_back(function_t(function));
622  return *this;
623  }
624 
625  delegate& operator=(const function_t& function) noexcept {
626  data_->no_arguments_functions.clear();
627  data_->functions.clear();
628  data_->functions.push_back(function);
629  return *this;
630  }
631 
632  delegate& operator=(const no_arguments_function_t& function) noexcept {
633  data_->no_arguments_functions.clear();
634  data_->functions.clear();
635  data_->no_arguments_functions.push_back(function);
636  return *this;
637  }
638 
639  delegate operator+(const delegate& other) noexcept {
640  delegate result = *this;
641  result += other;
642  return result;
643  }
644 
645  delegate operator+(const no_arguments_function_t& function) noexcept {
646  delegate result = *this;
647  result += function;
648  return result;
649  }
650 
651  delegate operator+(const function_t& function) noexcept {
652  delegate result = *this;
653  result += function;
654  return result;
655  }
656 
657  template<typename fn_t>
658  delegate operator+(fn_t function) noexcept {
659  delegate result = *this;
660  result += function;
661  return result;
662  }
663 
664  delegate& operator+=(const delegate& delegate) noexcept {
665  *this = delegate::combine(*this, delegate);
666  return *this;
667  }
668 
669  delegate& operator+=(const no_arguments_function_t& function) noexcept {
670  *this = delegate::combine(*this, delegate(function));
671  return *this;
672  }
673 
674  delegate& operator+=(const function_t& function) noexcept {
675  *this = delegate::combine(*this, delegate(function));
676  return *this;
677  }
678 
679  template<typename fn_t>
680  delegate& operator+=(fn_t function) noexcept {
681  *this = delegate::combine(*this, delegate(function));
682  return *this;
683  }
684 
685  delegate operator-(const delegate& other) noexcept {
686  delegate result = *this;
687  result -= other;
688  return result;
689  }
690 
691  delegate operator-(const no_arguments_function_t& function) noexcept {
692  delegate result = *this;
693  result -= function;
694  return result;
695  }
696 
697  delegate operator-(const function_t& function) noexcept {
698  delegate result = *this;
699  result -= function;
700  return result;
701  }
702 
703  template<typename fn_t>
704  delegate operator-(fn_t function) noexcept {
705  delegate result = *this;
706  result -= function;
707  return result;
708  }
709 
710  delegate& operator-=(const delegate& delegate) noexcept {
711  *this = delegate::remove(*this, delegate);
712  return *this;
713  }
714 
715  delegate& operator-=(const no_arguments_function_t& function) noexcept {
716  *this = delegate::remove(*this, delegate(function));
717  return *this;
718  }
719 
720  delegate& operator-=(const function_t& function) noexcept {
721  *this = delegate::remove(*this, delegate(function));
722  return *this;
723  }
724 
725  template<typename fn_t>
726  delegate& operator-=(fn_t function) noexcept {
727  *this = delegate::remove(*this, delegate(function));
728  return *this;
729  }
731 
732  private:
733  static bool are_equals(const std::function<result_t(arguments_t...)>& fct1, const std::function<result_t(arguments_t...)>& fct2) noexcept {
734  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...)>());
735  }
736 
737  static bool are_equals(const std::function<result_t()>& fct1, const std::function<result_t()>& fct2) noexcept {
738  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(*)()>());
739  }
740 
741  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 {
742  for (typename std::vector<no_arguments_function_t>::const_iterator iterator = begin; iterator != end; ++iterator)
743  if (are_equals(*iterator, function))
744  return iterator;
745  return end;
746  }
747 
748  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 {
749  for (typename std::vector<function_t>::const_iterator iterator = begin; iterator != end; ++iterator)
750  if (are_equals(*iterator, function))
751  return iterator;
752  return end;
753  }
754  struct data {
755  std::vector<no_arguments_function_t> no_arguments_functions;
756  std::vector<function_t> functions;
757  };
758  std::shared_ptr<data> data_ = std::make_shared<data>();
759  };
760 }
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:329
result_t invoke(arguments_t... arguments) const
invokes the method represented by the current delegate.
Definition: delegate.h:464
std::function< result_t(arguments_t...)> function_t
function_t pointer type
Definition: delegate.h:292
size_t size() const noexcept
Return the size of invocation list.
Definition: delegate.h:120
size_t size() const noexcept
Return the size of invocation list.
Definition: delegate.h:502
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:61
std::function< result_t()> function_t
function_t pointer type
Definition: delegate.h:36
static delegate combine(const delegate &a, const delegate &b) noexcept
Concatenates the invocation lists of two delegates.
Definition: delegate.h:107
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:116
delegate(const delegate &delegate) noexcept
Initializes a delegate that invokes the specified delegate instance.
Definition: delegate.h:302
bool is_empty() const noexcept
Return if the delegate is empty.
Definition: delegate.h:498
#define current_stack_frame_
Provides information about the current stack frame.
Definition: stack_frame.h:219
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:337
bool operator==(const delegate &delegate) const noexcept
Determines whether this instance and another specified delegateType object have the same value...
Definition: delegate.h:595
delegate(const function_t &function) noexcept
Initializes a delegate that invokes the specified instance method.
Definition: delegate.h:319
void clear()
Clear delegates array.
Definition: delegate.h:456
result_t invoke() const
invokes the method represented by the current delegate.
Definition: delegate.h:86
static delegate combine(const std::vector< delegate > &delegates) noexcept
Concatenates the invocation lists of an array of delegates.
Definition: delegate.h:93
Contains xtd::argument_null_exception exception.
void clear()
Clear delegates array.
Definition: delegate.h:81
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:68
static delegate combine(const std::vector< delegate > &delegates) noexcept
Concatenates the invocation lists of an array of delegates.
Definition: delegate.h:471
Contains xtd::object class.
Supports all classes in the xtd class hierarchy and provides low-level services to derived classes...
Definition: object.h:30
std::function< result_t()> no_arguments_function_t
no_arguments_function_t pointer type
Definition: delegate.h:290
const std::vector< function_t > & functions() const
Gets the delegates array.
Definition: delegate.h:453
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:540
const std::vector< function_t > & functions() const
Gets the delegates array.
Definition: delegate.h:78
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:147
delegate(const delegate &delegate) noexcept
Initializes a delegate that invokes the specified delegate instance.
Definition: delegate.h:46
result_t operator()() const
invokes the method represented by the current delegate.
Definition: delegate.h:167
bool operator!=(const delegate &delegate) const
Determines whether this instance and another specified delegateType object have the same value...
Definition: delegate.h:613
result_t operator()(arguments_t... arguments) const
invokes the method represented by the current delegate.
Definition: delegate.h:569
const std::vector< no_arguments_function_t > & no_arguments_functions() const
Gets the no arguments delegates array.
Definition: delegate.h:449
static delegate combine(const delegate &a, const delegate &b) noexcept
Concatenates the invocation lists of two delegates.
Definition: delegate.h:487