MEL
Microthread & Execution library
Callback_Impl.h
1 /*
2  * SPDX-FileCopyrightText: 2005,2022 Daniel Barrientos
3  * <danivillamanin@gmail.com>
4  *
5  * SPDX-License-Identifier: MIT
6  */
7 using mel::core::FunctionCallbackInterface;
8 using mel::core::FunctorCallbackInterface;
9 
10 namespace mel
11 {
12  namespace core
13  {
14 
25 #if VARIABLE_NUM_ARGS == VARIABLE_MAX_ARGS
27  {
28  };
30  {
31  };
32  const static use_functor_t use_functor = use_functor_t();
33  const static use_function_t use_function = use_function_t();
34 
36  template <class T, class TRet, VARIABLE_ARGS> struct _CallbackCreator
37  {
38 
39  static CallbackInterface<TRet, VARIABLE_ARGS_DECL>*
40  create( T&& functor )
41  {
42  // typedef typename ::std::decay<T>::type NewType;
43  // return new FunctorCallbackInterface<TRet, NewType,
44  // VARIABLE_ARGS_DECL>(::std::forward<NewType>(functor));
45  return new FunctorCallbackInterface<
46  TRet, typename ::std::remove_reference<T>::type,
47  VARIABLE_ARGS_DECL>( ::std::forward<T>( functor ) );
48  }
49  };
50 
51  template <class TRet, VARIABLE_ARGS> class Callback_Base
52  {
53  public:
54  typedef TRet ReturnType;
55 
61  template <class T>
62  Callback_Base( T&& functor, const use_functor_t& )
63  {
64  mCallBack =
65  _CallbackCreator<T, TRet, VARIABLE_ARGS_DECL>::create(
66  ::std::forward<T>( functor ) );
67  }
68 
69  template <class T>
70  Callback_Base( T&& functor, const use_function_t& )
71  {
72  mCallBack =
73  new FunctionCallbackInterface<TRet, VARIABLE_ARGS_DECL>(
74  ::std::forward<T>( functor ) );
75  }
76 
77  Callback_Base( const Callback_Base<TRet, VARIABLE_ARGS_DECL>& ev2 )
78  {
79  mCallBack = 0;
80  *this = ev2;
81  }
82  virtual ~Callback_Base() { delete mCallBack; };
87  bool operator==(
88  const Callback_Base<TRet, VARIABLE_ARGS_DECL>& ev2 ) const
89  {
90  return *mCallBack == *( ev2.mCallBack );
91  }
96  Callback_Base<TRet, VARIABLE_ARGS_DECL>&
97  operator=( const Callback_Base<TRet, VARIABLE_ARGS_DECL>& ev2 );
98 
99  virtual Callback_Base<TRet, VARIABLE_ARGS_DECL>* clone() const
100  {
101  return new Callback_Base<TRet, VARIABLE_ARGS_DECL>( *this );
102  }
106  CallbackInterface<TRet, VARIABLE_ARGS_DECL>* getCallback()
107  {
108  return mCallBack;
109  }
110 
111  protected:
115  CallbackInterface<TRet, VARIABLE_ARGS_DECL>* mCallBack;
116 
117  private:
118  Callback_Base() { mCallBack = 0; };
119  };
120 
121  template <class TRet, VARIABLE_ARGS_NODEFAULT>
122  Callback_Base<TRet, VARIABLE_ARGS_DECL>&
123  Callback_Base<TRet, VARIABLE_ARGS_DECL>::operator=(
124  const Callback_Base<TRet, VARIABLE_ARGS_DECL>& ev2 )
125  {
126  if ( this != &ev2 )
127  {
128  delete mCallBack;
129  mCallBack = (CallbackInterface<TRet, VARIABLE_ARGS_DECL>*)
130  ev2.mCallBack->clone();
131  }
132  return *this;
133  }
134 
136  // CLASS Callback
137  template <class TRet, VARIABLE_ARGS>
138  class Callback :
140  public Callback_Base<TRet, VARIABLE_ARGS_DECL>
142  {
143  public:
149  TRet operator()( VARIABLE_ARGS_IMPL )
150  {
151  return ( *Callback_Base<TRet, VARIABLE_ARGS_DECL>::mCallBack )(
152  VARIABLE_ARGS_USE );
153  }
159  template <class T>
160  Callback( T&& functor, const use_functor_t& c )
161  : Callback_Base<TRet, VARIABLE_ARGS_DECL>(
162  ::std::forward<T>( functor ), c )
163  {
164  }
165  template <class T>
166  Callback( T&& functor, const use_function_t& c )
167  : Callback_Base<TRet, VARIABLE_ARGS_DECL>(
168  std::forward<T>( functor ), c )
169  {
170  }
171  Callback( const Callback<TRet, VARIABLE_ARGS_DECL>& ev2 )
172  : Callback_Base<TRet, VARIABLE_ARGS_DECL>( ev2 ){};
173  Callback<TRet, VARIABLE_ARGS_DECL>* clone() const
174  {
175  return new Callback<TRet, VARIABLE_ARGS_DECL>( *this );
176  }
177 
178  private:
179  Callback()
180  {
181  Callback_Base<TRet, VARIABLE_ARGS_DECL>::mCallBack = 0;
182  };
183  };
184 
186  template <class TRet>
187  class Callback<TRet, void> : public Callback_Base<TRet, void>
188  {
189  public:
193  TRet operator()()
194  {
195  return ( *Callback_Base<TRet, void>::mCallBack )();
196  }
197 
203  // template<class T> Callback(T& functor, const use_functor_t& c) :
204  // Callback_Base<TRet, void>(functor, c) {}
205  template <class T>
206  Callback( T&& functor, const use_functor_t& c )
207  : Callback_Base<TRet, void>( ::std::forward<T>( functor ), c )
208  {
209  }
210  template <class T>
211  Callback( T&& functor, const use_function_t& c )
212  : Callback_Base<TRet, void>( ::std::forward<T>( functor ), c )
213  {
214  }
215  Callback( const Callback<TRet, void>& ev2 )
216  : Callback_Base<TRet, void>( ev2 ){};
217  Callback<TRet, void>* clone() const
218  {
219  return new Callback<TRet, void>( *this );
220  }
221 
222  private:
223  Callback() { Callback_Base<TRet, void>::mCallBack = 0; };
224  };
225 
226  template <class TRet, class T>
227  Callback<TRet, void>* makeEvent( T functor )
228  {
229  return new Callback<TRet, void>( functor,
230  ::mel::core::use_functor );
231  }
232 
233 #else
234 
235  template <class T, class TRet, VARIABLE_ARGS>
236  struct _CallbackCreator<T, TRet, VARIABLE_ARGS_DECL, void>
237  {
238 
239  static CallbackInterface<TRet, VARIABLE_ARGS_DECL>*
240  create( T&& functor )
241  {
242 
243  //??TODO EL PROBLEMA ES QUE ESTE DECAY HACE QUE EL FORWARD
244  // VUELVA A
245  // EMITIR UN &&. EL PROBLEMA ES QUE LOS TIPOS DE LOS CALLBACKS
246  // NO CUADRARAN typedef typename ::std::decay<T>::type NewType;
247  // typedef typename ::std::remove_reference<T>::type NewType;
248  // typedef T NewType;
249  // return new FunctorCallbackInterface<TRet,
250  // NewType,
251  // VARIABLE_ARGS_DECL>(::std::forward<NewType>(functor));
252  return new FunctorCallbackInterface<
253  TRet, typename ::std::remove_reference<T>::type,
254  VARIABLE_ARGS_DECL>( ::std::forward<T>( functor ) );
255  }
256  };
257 
258  template <class TRet, VARIABLE_ARGS>
259  class Callback_Base<TRet, VARIABLE_ARGS_DECL, void>
260  {
261 
262  public:
263  typedef TRet ReturnType;
264  // typedef Args ArgType;
265 
266  Callback_Base() { mCallBack = 0; };
267 
268  template <class T>
269  Callback_Base( T&& functor, const use_functor_t& )
270  {
271  mCallBack =
272  _CallbackCreator<T, TRet, VARIABLE_ARGS_DECL>::create(
273  ::std::forward<T>( functor ) );
274  // mCallBack = new FunctorCallbackInterface<TRet, T,
275  // VARIABLE_ARGS_DECL>(::std::forward<T>(functor));
276  }
277  template <class T>
278  Callback_Base( T&& functor, const use_function_t& )
279  {
280  mCallBack =
281  new FunctionCallbackInterface<TRet, VARIABLE_ARGS_DECL>(
282  ::std::forward<T>( functor ) );
283  }
284  Callback_Base( const Callback_Base<TRet, VARIABLE_ARGS_DECL>& ev2 )
285  {
286  mCallBack = 0;
287  *this = ev2;
288  }
289  virtual ~Callback_Base() { delete mCallBack; };
294  bool operator==(
295  const Callback_Base<TRet, VARIABLE_ARGS_DECL>& ev2 ) const
296  {
297  return *mCallBack == *( ev2.mCallBack );
298  }
303  Callback_Base<TRet, VARIABLE_ARGS_DECL>&
304  operator=( const Callback_Base<TRet, VARIABLE_ARGS_DECL>& ev2 );
305 
306  virtual Callback_Base<TRet, VARIABLE_ARGS_DECL>* clone() const
307  {
308  return new Callback_Base<TRet, VARIABLE_ARGS_DECL>( *this );
309  }
313  CallbackInterface<TRet, VARIABLE_ARGS_DECL>* getCallback()
314  {
315  return mCallBack;
316  }
317 
318  protected:
322  CallbackInterface<TRet, VARIABLE_ARGS_DECL>* mCallBack;
323  };
324  template <class TRet, VARIABLE_ARGS>
325  Callback_Base<TRet, VARIABLE_ARGS_DECL>&
326  Callback_Base<TRet, VARIABLE_ARGS_DECL>::operator=(
327  const Callback_Base<TRet, VARIABLE_ARGS_DECL>& ev2 )
328  {
329  if ( this != &ev2 )
330  {
331  delete mCallBack;
332  mCallBack = (CallbackInterface<TRet, VARIABLE_ARGS_DECL>*)
333  ev2.mCallBack->clone();
334  }
335  return *this;
336  }
337 
338  template <class TRet, VARIABLE_ARGS>
339  class Callback<TRet, VARIABLE_ARGS_DECL, void>
340  : public Callback_Base<TRet, VARIABLE_ARGS_DECL>
341  {
342  public:
348  TRet operator()( VARIABLE_ARGS_IMPL )
349  {
350  return ( *Callback_Base<TRet, VARIABLE_ARGS_DECL>::mCallBack )(
351  VARIABLE_ARGS_USE );
352  }
353 
359  template <class T>
360  Callback( T&& functor, const use_functor_t& c )
361  : Callback_Base<TRet, VARIABLE_ARGS_DECL>(
362  ::std::forward<T>( functor ), c ){};
363  template <class T>
364  Callback( T&& functor, const use_function_t& c )
365  : Callback_Base<TRet, VARIABLE_ARGS_DECL>(
366  ::std::forward<T>( functor ), c ){};
367  Callback( const Callback<TRet, VARIABLE_ARGS_DECL>& ev2 )
368  : Callback_Base<TRet, VARIABLE_ARGS_DECL>( ev2 ){};
369  Callback<TRet, VARIABLE_ARGS_DECL>* clone() const
370  {
371  return new Callback<TRet, VARIABLE_ARGS_DECL>( *this );
372  }
373 
374  private:
375  Callback()
376  {
377  Callback_Base<TRet, VARIABLE_ARGS_DECL>::mCallBack = 0;
378  };
379  };
380 #endif
381  } // namespace core
382 } // namespace mel
TRet operator()()
Definition: Callback_Impl.h:193
Callback(T &&functor, const use_functor_t &c)
Definition: Callback_Impl.h:206
create Callback from callable
Definition: Callback_Impl.h:142
Callback(T &&functor, const use_functor_t &c)
Definition: Callback_Impl.h:160
TRet operator()(VARIABLE_ARGS_IMPL)
Definition: Callback_Impl.h:149
Small operator==(const AnyType &, const AnyType &)
Definition: Callback_Impl.h:11
Definition: Callback_Impl.h:30
Definition: Callback_Impl.h:27