~
[scx.git] / include / Function.hpp
blob7889920cb6e89d4b1e92adec336ae2817a919a0f
1 #ifndef SCX_FUNCTION_HPP
2 #define SCX_FUNCTION_HPP
4 #include <cstddef>
5 #include <map>
6 #include <cassert>
8 namespace scx {
10 namespace FunctionType {
11 enum e{
12 Ptr,
13 Mem
16 typedef FunctionType::e EmFunctionType;
18 /* Function base class */
19 template<typename signature>
20 class FunctionBase;
22 template<typename ret_t>
23 class FunctionBase<ret_t (void)>
25 public:
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,
33 typename arg_t>
34 class FunctionBase<ret_t (arg_t)>
36 public:
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,
44 typename arg1_t,
45 typename arg2_t>
46 class FunctionBase<ret_t (arg1_t, arg2_t)>
48 public:
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,
56 typename arg1_t,
57 typename arg2_t,
58 typename arg3_t>
59 class FunctionBase<ret_t (arg1_t, arg2_t, arg3_t)>
61 public:
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,
69 typename arg1_t,
70 typename arg2_t,
71 typename arg3_t,
72 typename arg4_t>
73 class FunctionBase<ret_t (arg1_t, arg2_t, arg3_t, arg4_t)>
75 public:
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,
83 typename arg1_t,
84 typename arg2_t,
85 typename arg3_t,
86 typename arg4_t,
87 typename arg5_t>
88 class FunctionBase<ret_t (arg1_t, arg2_t, arg3_t, arg4_t, arg5_t)>
90 public:
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>
99 class FunctionMem;
101 #define SCX_FUNCTION_COPY_FUNCTION_MEM_COMMON(argts...) \
102 typedef ret_t (recv_t::*fn_t)(argts); \
103 public:\
104 FunctionMem(fn_t fn, recv_t* recv): \
105 m_Function(fn), \
106 m_Receiver(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; }\
118 private: \
119 fn_t m_Function; \
120 recv_t* 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);
127 public:
128 virtual ret_t operator()(void) const
130 return (m_Receiver->*m_Function)();
134 template<typename ret_t, typename recv_t,
135 typename arg_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);
140 public:
141 virtual ret_t operator()(arg_t arg) const
143 return (m_Receiver->*m_Function)(arg);
147 template<typename ret_t, typename recv_t,
148 typename arg1_t,
149 typename arg2_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);
155 public:
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,
163 typename arg1_t,
164 typename arg2_t,
165 typename arg3_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);
171 public:
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,
179 typename arg1_t,
180 typename arg2_t,
181 typename arg3_t,
182 typename arg4_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);
188 public:
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,
196 typename arg1_t,
197 typename arg2_t,
198 typename arg3_t,
199 typename arg4_t,
200 typename arg5_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);
206 public:
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>
217 class FunctionPtr;
219 #define SCX_FUNCTION_COPY_FUNCTION_PTR_COMMON \
220 public:\
221 FunctionPtr(fn_t fn): \
222 m_Function(fn) \
226 EmFunctionType GetType() const \
228 return FunctionType::Ptr; \
231 void* GetReceiver() const \
233 return NULL; \
236 private:\
237 fn_t m_Function
239 template<typename ret_t,
240 typename arg_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;
247 public:
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;
261 public:
262 virtual ret_t operator()(void) const
264 return m_Function();
268 template<typename ret_t,
269 typename arg1_t,
270 typename arg2_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;
278 public:
279 virtual ret_t operator()(arg1_t arg1, arg2_t arg2) const {
280 return m_Function(arg1, arg2);
284 template<typename ret_t,
285 typename arg1_t,
286 typename arg2_t,
287 typename arg3_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;
295 public:
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,
303 typename arg1_t,
304 typename arg2_t,
305 typename arg3_t,
306 typename arg4_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;
314 public:
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,
322 typename arg1_t,
323 typename arg2_t,
324 typename arg3_t,
325 typename arg4_t,
326 typename arg5_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;
334 public:
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>
345 class Function;
347 #define SCX_FUNCTION_COPY_FUNCTION_COMMON_VOID \
348 public:\
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) { \
362 CheckRefMap(); \
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)) { \
368 CheckRefMap(); \
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...) \
376 public:\
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) { \
390 CheckRefMap(); \
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)) { \
396 CheckRefMap(); \
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; \
406 public:\
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]; \
415 ~Function() { \
416 CheckRefMap(); \
419 const Function& operator=(const Function& f) { \
420 if (&f != this) { \
421 CheckRefMap(); \
422 m_PtrFn = f.m_PtrFn; \
423 if (m_PtrFn != NULL) \
424 ++m_RefMap[m_PtrFn]; \
426 return *this; \
429 EmFunctionType GetType() const { \
430 return m_PtrFn->GetType(); \
433 void* GetReceiver() const { \
434 return m_PtrFn->GetReceiver(); \
437 private:\
438 void CheckRefMap() { \
439 if (m_PtrFn != NULL) { \
440 RefMapIter iter = \
441 m_RefMap.find((FunctionBase_t*)m_PtrFn); \
442 if (iter->second <= 1) { \
443 m_RefMap.erase(iter); \
444 delete m_PtrFn; \
445 } else { \
446 --iter->second; \
448 m_PtrFn = NULL; \
452 private:\
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);
463 public:
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;
479 public:
480 ret_t operator()(void) const {
481 return (*m_PtrFn)();
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,
489 typename arg1_t,
490 typename arg2_t>
491 class Function<ret_t (arg1_t, arg2_t)>
493 SCX_FUNCTION_COPY_FUNCTION_COMMON_NVOID(arg1_t, arg2_t);
495 public:
496 ret_t operator()(arg1_t arg1, arg2_t arg2) const
498 return (*m_PtrFn)(arg1, arg2);
502 template<typename ret_t,
503 typename arg1_t,
504 typename arg2_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,
508 typename arg1_t,
509 typename arg2_t,
510 typename arg3_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);
515 public:
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,
523 typename arg1_t,
524 typename arg2_t,
525 typename arg3_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,
529 typename arg1_t,
530 typename arg2_t,
531 typename arg3_t,
532 typename arg4_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);
537 public:
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,
545 typename arg1_t,
546 typename arg2_t,
547 typename arg3_t,
548 typename arg4_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,
552 typename arg1_t,
553 typename arg2_t,
554 typename arg3_t,
555 typename arg4_t,
556 typename arg5_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);
561 public:
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,
568 typename arg1_t,
569 typename arg2_t,
570 typename arg3_t,
571 typename arg4_t,
572 typename arg5_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
580 #endif