1 #ifndef SCX_FUNCTION_HPP
2 #define SCX_FUNCTION_HPP
10 namespace FunctionType
{
16 typedef FunctionType::e EmFunctionType
;
18 /* Function base class */
19 template<typename signature
>
22 template<typename ret_t
>
23 class FunctionBase
<ret_t (void)>
26 virtual ~FunctionBase() { };
27 virtual ret_t
operator()(void) const = 0;
28 virtual EmFunctionType
GetType() const = 0;
29 virtual void* GetReceiver() const = 0;
32 template<typename ret_t
,
34 class FunctionBase
<ret_t (arg_t
)>
37 virtual ~FunctionBase() { };
38 virtual ret_t
operator()(arg_t
) const = 0;
39 virtual EmFunctionType
GetType() const = 0;
40 virtual void* GetReceiver() const = 0;
43 template<typename ret_t
,
46 class FunctionBase
<ret_t (arg1_t
, arg2_t
)>
49 virtual ~FunctionBase() { };
50 virtual ret_t
operator()(arg1_t
, arg2_t
) const = 0;
51 virtual EmFunctionType
GetType() const = 0;
52 virtual void* GetReceiver() const = 0;
55 template<typename ret_t
,
59 class FunctionBase
<ret_t (arg1_t
, arg2_t
, arg3_t
)>
62 virtual ~FunctionBase() { };
63 virtual ret_t
operator()(arg1_t
, arg2_t
, arg3_t
) const = 0;
64 virtual EmFunctionType
GetType() const = 0;
65 virtual void* GetReceiver() const = 0;
68 template<typename ret_t
,
73 class FunctionBase
<ret_t (arg1_t
, arg2_t
, arg3_t
, arg4_t
)>
76 virtual ~FunctionBase() { };
77 virtual ret_t
operator()(arg1_t
, arg2_t
, arg3_t
, arg4_t
) const = 0;
78 virtual EmFunctionType
GetType() const = 0;
79 virtual void* GetReceiver() const = 0;
82 template<typename ret_t
,
88 class FunctionBase
<ret_t (arg1_t
, arg2_t
, arg3_t
, arg4_t
, arg5_t
)>
91 virtual ~FunctionBase() { };
92 virtual ret_t
operator()(arg1_t
, arg2_t
, arg3_t
, arg4_t
, arg5_t
) const = 0;
93 virtual EmFunctionType
GetType() const = 0;
94 virtual void* GetReceiver() const = 0;
97 /* Function mem class */
98 template<typename signature
>
101 #define SCX_FUNCTION_COPY_FUNCTION_MEM_COMMON(argts...) \
102 typedef ret_t (recv_t::*fn_t)(argts); \
104 FunctionMem(fn_t fn, recv_t* recv): \
109 FunctionMem(const FunctionMem& func) { \
110 m_Function = func.m_Function; \
111 m_Receiver = func.m_Receiver; \
114 EmFunctionType GetType() const { return FunctionType::Mem; }\
116 void* GetReceiver() const { return m_Receiver; }\
122 template<typename ret_t
, typename recv_t
>
123 class FunctionMem
<ret_t (recv_t
*)>: public FunctionBase
<ret_t (void)>
125 SCX_FUNCTION_COPY_FUNCTION_MEM_COMMON(void);
128 virtual ret_t
operator()(void) const
130 return (m_Receiver
->*m_Function
)();
134 template<typename ret_t
, typename recv_t
,
136 class FunctionMem
<ret_t (recv_t
*, arg_t
)>: public FunctionBase
<ret_t (arg_t
)>
138 SCX_FUNCTION_COPY_FUNCTION_MEM_COMMON(arg_t
);
141 virtual ret_t
operator()(arg_t arg
) const
143 return (m_Receiver
->*m_Function
)(arg
);
147 template<typename ret_t
, typename recv_t
,
150 class FunctionMem
<ret_t (recv_t
*, arg1_t
, arg2_t
)>:
151 public FunctionBase
<ret_t (arg1_t
, arg2_t
)>
153 SCX_FUNCTION_COPY_FUNCTION_MEM_COMMON(arg1_t
, arg2_t
);
156 virtual ret_t
operator()(arg1_t arg1
, arg2_t arg2
) const
158 return (m_Receiver
->*m_Function
)(arg1
, arg2
);
162 template<typename ret_t
, typename recv_t
,
166 class FunctionMem
<ret_t (recv_t
*, arg1_t
, arg2_t
, arg3_t
)>:
167 public FunctionBase
<ret_t (arg1_t
, arg2_t
, arg3_t
)>
169 SCX_FUNCTION_COPY_FUNCTION_MEM_COMMON(arg1_t
, arg2_t
, arg3_t
);
172 virtual ret_t
operator()(arg1_t arg1
, arg2_t arg2
, arg3_t arg3
) const
174 return (m_Receiver
->*m_Function
)(arg1
, arg2
, arg3
);
178 template<typename ret_t
, typename recv_t
,
183 class FunctionMem
<ret_t (recv_t
*, arg1_t
, arg2_t
, arg3_t
, arg4_t
)>:
184 public FunctionBase
<ret_t (arg1_t
, arg2_t
, arg3_t
, arg4_t
)>
186 SCX_FUNCTION_COPY_FUNCTION_MEM_COMMON(arg1_t
, arg2_t
, arg3_t
, arg4_t
);
189 virtual ret_t
operator()(arg1_t arg1
, arg2_t arg2
, arg3_t arg3
, arg4_t arg4
) const
191 return (m_Receiver
->*m_Function
)(arg1
, arg2
, arg3
, arg4
);
195 template<typename ret_t
, typename recv_t
,
201 class FunctionMem
<ret_t (recv_t
*, arg1_t
, arg2_t
, arg3_t
, arg4_t
, arg5_t
)>:
202 public FunctionBase
<ret_t (arg1_t
, arg2_t
, arg3_t
, arg4_t
, arg5_t
)>
204 SCX_FUNCTION_COPY_FUNCTION_MEM_COMMON(arg1_t
, arg2_t
, arg3_t
, arg4_t
, arg5_t
);
207 virtual ret_t
operator()(arg1_t arg1
, arg2_t arg2
, arg3_t arg3
, arg4_t arg4
, arg5_t arg5
) const
209 return (m_Receiver
->*m_Function
)(arg1
, arg2
, arg3
, arg4
, arg5
);
213 #undef SCX_FUNCTION_COPY_FUNCTION_MEM_COMMON
215 /* Function ptr class */
216 template<typename signature
>
219 #define SCX_FUNCTION_COPY_FUNCTION_PTR_COMMON \
221 FunctionPtr(fn_t fn): \
226 EmFunctionType GetType() const \
228 return FunctionType::Ptr; \
231 void* GetReceiver() const \
239 template<typename ret_t
,
241 class FunctionPtr
<ret_t (arg_t
)>: public FunctionBase
<ret_t (arg_t
)>
243 typedef ret_t (*fn_t
)(arg_t
);
245 SCX_FUNCTION_COPY_FUNCTION_PTR_COMMON
;
248 virtual ret_t
operator()(arg_t arg
) const
250 return m_Function(arg
);
254 template<typename ret_t
>
255 class FunctionPtr
<ret_t (void)>: public FunctionBase
<ret_t (void)>
257 typedef ret_t (*fn_t
)(void);
259 SCX_FUNCTION_COPY_FUNCTION_PTR_COMMON
;
262 virtual ret_t
operator()(void) const
268 template<typename ret_t
,
271 class FunctionPtr
<ret_t (arg1_t
, arg2_t
)>:
272 public FunctionBase
<ret_t (arg1_t
, arg2_t
)>
274 typedef ret_t (*fn_t
)(arg1_t
, arg2_t
);
276 SCX_FUNCTION_COPY_FUNCTION_PTR_COMMON
;
279 virtual ret_t
operator()(arg1_t arg1
, arg2_t arg2
) const {
280 return m_Function(arg1
, arg2
);
284 template<typename ret_t
,
288 class FunctionPtr
<ret_t (arg1_t
, arg2_t
, arg3_t
)>:
289 public FunctionBase
<ret_t (arg1_t
, arg2_t
, arg3_t
)>
291 typedef ret_t (*fn_t
)(arg1_t
, arg2_t
, arg3_t
);
293 SCX_FUNCTION_COPY_FUNCTION_PTR_COMMON
;
296 virtual ret_t
operator()(arg1_t arg1
, arg2_t arg2
, arg3_t arg3
) const
298 return m_Function(arg1
, arg2
, arg3
);
302 template<typename ret_t
,
307 class FunctionPtr
<ret_t (arg1_t
, arg2_t
, arg3_t
, arg4_t
)>:
308 public FunctionBase
<ret_t (arg1_t
, arg2_t
, arg3_t
, arg4_t
)>
310 typedef ret_t (*fn_t
)(arg1_t
, arg2_t
, arg3_t
, arg4_t
);
312 SCX_FUNCTION_COPY_FUNCTION_PTR_COMMON
;
315 virtual ret_t
operator()(arg1_t arg1
, arg2_t arg2
, arg3_t arg3
, arg4_t arg4
) const
317 return m_Function(arg1
, arg2
, arg3
, arg4
);
321 template<typename ret_t
,
327 class FunctionPtr
<ret_t (arg1_t
, arg2_t
, arg3_t
, arg4_t
, arg5_t
)>:
328 public FunctionBase
<ret_t (arg1_t
, arg2_t
, arg3_t
, arg4_t
, arg5_t
)>
330 typedef ret_t (*fn_t
)(arg1_t
, arg2_t
, arg3_t
, arg4_t
, arg5_t
);
332 SCX_FUNCTION_COPY_FUNCTION_PTR_COMMON
;
335 virtual ret_t
operator()(arg1_t arg1
, arg2_t arg2
, arg3_t arg3
, arg4_t arg4
, arg5_t arg5
) const
337 return m_Function(arg1
, arg2
, arg3
, arg4
, arg5
);
341 #undef SCX_FUNCTION_COPY_FUNCTION_PTR_COMMON
343 /* Function wrapper */
344 template<typename signature
>
347 #define SCX_FUNCTION_COPY_FUNCTION_COMMON_VOID \
349 template<typename fn_t, typename recv_t> \
350 Function(fn_t fn, recv_t recv) { \
351 m_PtrFn = new FunctionMem<ret_t (recv_t)>(fn, recv); \
352 m_RefMap.insert(RefMapPair(m_PtrFn, 1)); \
355 Function(ret_t (*fn)(void)) { \
356 m_PtrFn = new FunctionPtr<ret_t (void)>(fn); \
357 m_RefMap.insert(RefMapPair(m_PtrFn, 1)); \
360 template<typename fn_t, typename recv_t> \
361 void Bind(fn_t fn, recv_t recv) { \
363 m_PtrFn = new FunctionMem<ret_t (recv_t)>(fn, recv); \
364 m_RefMap.insert(RefMapPair(m_PtrFn, 1)); \
367 void Bind(ret_t (*fn)(void)) { \
369 m_PtrFn = new FunctionPtr<ret_t (void)>(fn); \
370 m_RefMap.insert(RefMapPair(m_PtrFn, 1)); \
373 SCX_FUNCTION_COPY_FUNCTION_COMMON(void)
375 #define SCX_FUNCTION_COPY_FUNCTION_COMMON_NVOID(argts...) \
377 template<typename fn_t, typename recv_t> \
378 Function(fn_t fn, recv_t recv) { \
379 m_PtrFn = new FunctionMem<ret_t (recv_t, argts)>(fn, recv); \
380 m_RefMap.insert(RefMapPair(m_PtrFn, 1)); \
383 Function(ret_t (*fn)(argts)) { \
384 m_PtrFn = new FunctionPtr<ret_t (argts)>(fn); \
385 m_RefMap.insert(RefMapPair(m_PtrFn, 1)); \
388 template<typename fn_t, typename recv_t> \
389 void Bind(fn_t fn, recv_t recv) { \
391 m_PtrFn = new FunctionMem<ret_t (recv_t, argts)>(fn, recv); \
392 m_RefMap.insert(RefMapPair(m_PtrFn, 1)); \
395 void Bind(ret_t (*fn)(argts)) { \
397 m_PtrFn = new FunctionPtr<ret_t (argts)>(fn); \
398 m_RefMap.insert(RefMap(m_PtrFn, 1)); \
401 SCX_FUNCTION_COPY_FUNCTION_COMMON(argts)
403 #define SCX_FUNCTION_COPY_FUNCTION_COMMON(argts...) \
404 typedef FunctionBase<ret_t (argts)> FunctionBase_t; \
407 Function(): m_PtrFn(NULL) { } \
409 Function(const Function& f): \
410 m_PtrFn(f.m_PtrFn) { \
411 if (m_PtrFn != NULL) \
412 ++m_RefMap[m_PtrFn]; \
419 const Function& operator=(const Function& f) { \
422 m_PtrFn = f.m_PtrFn; \
423 if (m_PtrFn != NULL) \
424 ++m_RefMap[m_PtrFn]; \
429 EmFunctionType GetType() const { \
430 return m_PtrFn->GetType(); \
433 void* GetReceiver() const { \
434 return m_PtrFn->GetReceiver(); \
438 void CheckRefMap() { \
439 if (m_PtrFn != NULL) { \
441 m_RefMap.find((FunctionBase_t*)m_PtrFn); \
442 if (iter->second <= 1) { \
443 m_RefMap.erase(iter); \
453 static std::map<FunctionBase_t*, size_t> m_RefMap; \
454 typedef typename std::map<FunctionBase_t*, size_t>::iterator RefMapIter; \
455 typedef typename std::pair<FunctionBase_t*, size_t> RefMapPair; \
456 FunctionBase_t* m_PtrFn
458 template<typename ret_t
, typename arg_t
>
459 class Function
<ret_t (arg_t
)>
461 SCX_FUNCTION_COPY_FUNCTION_COMMON_NVOID(arg_t
);
465 ret_t
operator()(arg_t arg
) const
467 return (*m_PtrFn
)(arg
);
471 template<typename ret_t
, typename arg_t
>
472 std::map
<FunctionBase
<ret_t (arg_t
)>*, size_t> Function
<ret_t (arg_t
)>::m_RefMap
;
474 template<typename ret_t
>
475 class Function
<ret_t (void)>
477 SCX_FUNCTION_COPY_FUNCTION_COMMON_VOID
;
480 ret_t
operator()(void) const {
485 template<typename ret_t
>
486 std::map
<FunctionBase
<ret_t (void)>*, size_t> Function
<ret_t (void)>::m_RefMap
;
488 template<typename ret_t
,
491 class Function
<ret_t (arg1_t
, arg2_t
)>
493 SCX_FUNCTION_COPY_FUNCTION_COMMON_NVOID(arg1_t
, arg2_t
);
496 ret_t
operator()(arg1_t arg1
, arg2_t arg2
) const
498 return (*m_PtrFn
)(arg1
, arg2
);
502 template<typename ret_t
,
505 std::map
<FunctionBase
<ret_t (arg1_t
, arg2_t
)>*, size_t> Function
<ret_t (arg1_t
, arg2_t
)>::m_RefMap
;
507 template<typename ret_t
,
511 class Function
<ret_t (arg1_t
, arg2_t
, arg3_t
)>
513 SCX_FUNCTION_COPY_FUNCTION_COMMON_NVOID(arg1_t
, arg2_t
, arg3_t
);
516 ret_t
operator()(arg1_t arg1
, arg2_t arg2
, arg3_t arg3
) const
518 return (*m_PtrFn
)(arg1
, arg2
, arg3
);
522 template<typename ret_t
,
526 std::map
<FunctionBase
<ret_t (arg1_t
, arg2_t
, arg3_t
)>*, size_t> Function
<ret_t (arg1_t
, arg2_t
, arg3_t
)>::m_RefMap
;
528 template<typename ret_t
,
533 class Function
<ret_t (arg1_t
, arg2_t
, arg3_t
, arg4_t
)>
535 SCX_FUNCTION_COPY_FUNCTION_COMMON_NVOID(arg1_t
, arg2_t
, arg3_t
, arg4_t
);
538 ret_t
operator()(arg1_t arg1
, arg2_t arg2
, arg3_t arg3
, arg4_t arg4
) const
540 return (*m_PtrFn
)(arg1
, arg2
, arg3
, arg4
);
544 template<typename ret_t
,
549 std::map
<FunctionBase
<ret_t (arg1_t
, arg2_t
, arg3_t
, arg4_t
)>*, size_t> Function
<ret_t (arg1_t
, arg2_t
, arg3_t
, arg4_t
)>::m_RefMap
;
551 template<typename ret_t
,
557 class Function
<ret_t (arg1_t
, arg2_t
, arg3_t
, arg4_t
, arg5_t
)>
559 SCX_FUNCTION_COPY_FUNCTION_COMMON_NVOID(arg1_t
, arg2_t
, arg3_t
, arg4_t
, arg5_t
);
562 ret_t
operator()(arg1_t arg1
, arg2_t arg2
, arg3_t arg3
, arg4_t arg4
, arg5_t arg5
) const {
563 return (*m_PtrFn
)(arg1
, arg2
, arg3
, arg4
, arg5
);
567 template<typename ret_t
,
573 std::map
<FunctionBase
<ret_t (arg1_t
, arg2_t
, arg3_t
, arg4_t
, arg5_t
)>*, size_t> Function
<ret_t (arg1_t
, arg2_t
, arg3_t
, arg4_t
, arg5_t
)>::m_RefMap
;
575 #undef SCX_FUNCTION_COPY_FUNCTION_COMMON_VOID
576 #undef SCX_FUNCTION_COPY_FUNCTION_COMMON
577 #undef SCX_FUNCTION_COPY_FUNCTION_COMMON_NVOID