Sming Framework API
Sming - Open Source framework for high efficiency WiFi SoC ESP8266 native development with C++ language.
Delegate.h
1 /****
2  * Sming Framework Project - Open Source framework for high efficiency native ESP8266 development.
3  * Created 2015 by Skurydin Alexey
4  * http://github.com/anakod/Sming
5  * All files of the Sming Core are provided under the LGPL v3 license.
6  *
7  * Delegate.h
8  *
9  ****/
10 
16 #ifndef _SMING_CORE_DELEGATE_H_
17 #define _SMING_CORE_DELEGATE_H_
18 
19 #include <user_config.h>
20 
24 template <class ReturnType, typename... ParamsList> class IDelegateCaller
25 {
26 public:
27  virtual ~IDelegateCaller() = default;
28 
33  virtual ReturnType invoke(ParamsList...) = 0;
34 
37  __forceinline void increase()
38  {
39  references++;
40  }
41 
45  __forceinline void decrease()
46  {
47  references--;
48  if(references == 0) {
49  delete this;
50  }
51  }
52 
53 private:
54  uint32_t references = 1;
55 };
56 
57 template <class> class MethodCaller; /* undefined */
58 
61 template <class ClassType, class ReturnType, typename... ParamsList>
62 class MethodCaller<ReturnType (ClassType::*)(ParamsList...)> : public IDelegateCaller<ReturnType, ParamsList...>
63 {
67  typedef ReturnType (ClassType::*MethodDeclaration)(ParamsList...);
68 
69 public:
74  MethodCaller(ClassType* c, MethodDeclaration m) : mClass(c), mMethod(m)
75  {
76  }
77 
82  ReturnType invoke(ParamsList... args) override
83  {
84  return (mClass->*mMethod)(args...);
85  }
86 
87 private:
88  ClassType* mClass;
89  MethodDeclaration mMethod;
90 };
91 
94 template <class MethodDeclaration, class ReturnType, typename... ParamsList>
95 class FunctionCaller : public IDelegateCaller<ReturnType, ParamsList...>
96 {
97 public:
101  FunctionCaller(MethodDeclaration m) : mMethod(m)
102  {
103  }
104 
109  ReturnType invoke(ParamsList... args) override
110  {
111  return (mMethod)(args...);
112  }
113 
114 private:
115  MethodDeclaration mMethod;
116 };
117 
118 template <class> class Delegate; /* undefined */
119 
122 template <class ReturnType, class... ParamsList> class Delegate<ReturnType(ParamsList...)>
123 {
126  typedef ReturnType (*FunctionDeclaration)(ParamsList...);
127 
128  template <typename ClassType> using MethodDeclaration = ReturnType (ClassType::*)(ParamsList...);
129 
130 public:
133  __forceinline Delegate()
134  {
135  }
136 
137  // Class method
142  template <class ClassType> __forceinline Delegate(MethodDeclaration<ClassType> m, ClassType* c)
143  {
144  if(m != nullptr) {
146  }
147  }
148 
149  // Function
153  __forceinline Delegate(FunctionDeclaration m)
154  {
155  if(m != nullptr) {
156  impl = new FunctionCaller<FunctionDeclaration, ReturnType, ParamsList...>(m);
157  }
158  }
159 
160  __forceinline ~Delegate()
161  {
162  if(impl != nullptr) {
163  impl->decrease();
164  }
165  }
166 
171  __forceinline ReturnType operator()(ParamsList... params) const
172  {
173  return impl->invoke(params...);
174  }
175 
179  __forceinline Delegate(Delegate&& that)
180  {
181  impl = that.impl;
182  that.impl = nullptr;
183  }
184 
188  __forceinline Delegate(const Delegate& that)
189  {
190  copy(that);
191  }
192 
197  __forceinline Delegate& operator=(const Delegate& that) // copy assignment
198  {
199  copy(that);
200  return *this;
201  }
202 
207  Delegate& operator=(Delegate&& that) // move assignment
208  {
209  if(this != &that) {
210  if(impl != nullptr) {
211  impl->decrease();
212  }
213 
214  impl = that.impl;
215  that.impl = nullptr;
216  }
217  return *this;
218  }
219 
223  __forceinline operator bool() const
224  {
225  return impl != nullptr;
226  }
227 
228 protected:
229  void copy(const Delegate& other)
230  {
231  if(impl != other.impl) {
232  if(impl != nullptr) {
233  impl->decrease();
234  }
235  impl = other.impl;
236  if(impl != nullptr) {
237  impl->increase();
238  }
239  }
240  }
241 
242 private:
243  IDelegateCaller<ReturnType, ParamsList...>* impl = nullptr;
244 };
245 
247 #endif /* _SMING_CORE_DELEGATE_H_ */
__forceinline Delegate(const Delegate &that)
Copy a delegate from another Delegate object.
Definition: Delegate.h:188
__forceinline Delegate()
Instantiate a delegate object.
Definition: Delegate.h:133
ReturnType invoke(ParamsList...args) override
Invoke the delegate function.
Definition: Delegate.h:109
MethodCaller(ClassType *c, MethodDeclaration m)
Instantiate a delegate method caller object.
Definition: Delegate.h:74
__forceinline Delegate(FunctionDeclaration m)
Delegate a function.
Definition: Delegate.h:153
__forceinline Delegate(Delegate &&that)
Move a delegate from another object.
Definition: Delegate.h:179
Definition: Delegate.h:57
__forceinline void decrease()
Decrease the quantity of delegate caller references by one.
Definition: Delegate.h:45
__forceinline Delegate(MethodDeclaration< ClassType > m, ClassType *c)
Delegate a class method.
Definition: Delegate.h:142
Delegate function caller class.
Definition: Delegate.h:95
ReturnType invoke(ParamsList...args) override
Invoke the delegate method.
Definition: Delegate.h:82
Definition: Delegate.h:118
__forceinline Delegate & operator=(const Delegate &that)
Copy a delegate from another Delegate object.
Definition: Delegate.h:197
__forceinline void increase()
Increase the quantity of delegate caller references by one.
Definition: Delegate.h:37
virtual ReturnType invoke(ParamsList...)=0
Invode the delegate.
__forceinline ReturnType operator()(ParamsList...params) const
Invoke a delegate.
Definition: Delegate.h:171
Delegate & operator=(Delegate &&that)
Move a delegate from another Delegate object.
Definition: Delegate.h:207
IDelegateCaller class.
Definition: Delegate.h:24
FunctionCaller(MethodDeclaration m)
Instantiate a delegate function caller object.
Definition: Delegate.h:101