1 // Modified by Timur Davidenko...
2 
3 //**************** callback.hpp **********************
4 // Copyright 1994 Rich Hickey
5 /* Permission to use, copy, modify, distribute and sell this software
6  * for any purpose is hereby granted without fee,
7  * provided that the above copyright notice appear in all copies and
8  * that both that copyright notice and this permission notice appear
9  * in supporting documentation.  Rich Hickey makes no
10  * representations about the suitability of this software for any
11  * purpose.  It is provided "as is" without express or implied warranty.
12 */
13 
14 // 08/31/96 Rich Hickey
15 // Added ==, != and <
16 //  They are not inline, source is in file callback.cpp
17 //  Note: You must compile and link in callback.obj if you use them
18 // C++ doesn't allow ptr-to-func to void * anymore -> changed to void (*)(void)
19 // Added compiler workarounds for MS VC++ 4.2
20 // Prefixed all macros with RHCB
21 // Note: derivation from FunctorBase is now public, and access functions
22 // (for func, callee etc) are provided >>for implementation use only<<
23 
24 // 06/12/94 Rich Hickey
25 // 3rd major revision
26 // Now functors are concrete classes, and should be held by value
27 // Virtual function mechanism removed
28 // Generic functor() mechanism added for building functors
29 // from both stand-alone functions and object/ptr-to-mem-func pairs
30 
31 #ifndef FUNCTOR_H
32 #define FUNCTOR_H
33 
34 #include <assert.h>
35 #include <list>
36 #include <string.h>
37 
38 /*
39 To use:
40 
41 If you wish to build a component that provides/needs a callback, simply
42 specify and hold a Functor of the type corresponding to the args
43 you wish to pass and the return value you need. There are 10 Functors
44 from which to choose:
45 
46 Functor0
47 Functor1<P1>
48 Functor2<P1,P2>
49 Functor3<P1,P2,P3>
50 Functor4<P1,P2,P3,P4>
51 Functor5<P1,P2,P3,P4,P5>
52 Functor0wRet<RT>
53 Functor1wRet<P1,RT>
54 Functor2wRet<P1,P2,RT>
55 Functor3wRet<P1,P2,P3,RT>
56 Functor4wRet<P1,P2,P3,P4,RT>
57 
58 These are parameterized by their args and return value if any. Each has
59 a default ctor and an operator() with the corresponding signature.
60 
61 They can be treated and used just like ptr-to-functions.
62 
63 If you want to be a client of a component that uses callbacks, you
64 create a Functor by calling functor().
65 
66 There are three flavors of functor - you can create a functor from:
67 
68 a ptr-to-stand-alone function
69 an object and a pointer-to-member function.
70 a pointer-to-member function (which will be called on first arg of functor)
71 
72 Note: this last was not covered in the article - see CBEXAM3.CPP
73 
74 functor( ptr-to-function)
75 functor( reference-to-object,ptr-to-member-function)
76 functor( ptr-to-member-function)
77 
78 The functor system is 100% type safe. It is also type flexible. You can
79 build a functor out of a function that is 'type compatible' with the
80 target functor - it need not have an exactly matching signature. By
81 type compatible I mean a function with the same number of arguments, of
82 types reachable from the functor's argument types by implicit conversion.
83 The return type of the function must be implicitly convertible to the
84 return type of the functor. A functor with no return can be built from a
85 function with a return - the return value is simply ignored.
86 (See ethel example below)
87 
88 All the correct virtual function behavior is preserved. (see ricky
89 example below).
90 
91 If you somehow try to create something in violation
92 of the type system you will get a compile-time or template-instantiation-
93 time error.
94 
95 The Functor base class and translator
96 classes are artifacts of this implementation. You should not write
97 code that relies upon their existence. Nor should you rely on the return
98 value of functor being anything in particular.
99 
100 All that is guaranteed is that the Functor classes have a default ctor,
101 a ctor that can accept 0 as an initializer,
102 an operator() with the requested argument types and return type, an
103 operator that will allow it to be evaluated in a conditional (with
104 'true' meaning the functor is set, 'false' meaning it is not), and that
105 Functors can be constructed from the result of functor(), given
106 you've passed something compatible to functor(). In addition you
107 can compare 2 functors with ==, !=, and <. 2 functors with the same
108 'callee' (function, object and/or ptr-to-mem-func) shall compare
109 equal. op < forms an ordering relation across all callee types -> the
110 actual order is not meaningful or to be depended upon.
111 
112 /////////////////////// BEGIN Example 1 //////////////////////////
113 #include <iostream.h>
114 #include "callback.hpp"
115 
116 //do5Times() is a function that takes a functor and invokes it 5 times
117 
118 void do5Times(const Functor1<int> &doIt)
119         {
120         for(int i=0;i<5;i++)
121                 doIt(i);
122         }
123 
124 //Here are some standalone functions
125 
126 void fred(int i){cout << "fred: " << i<<endl;}
127 int ethel(long l){cout << "ethel: " << l<<endl;return l;}
128 
129 //Here is a class with a virtual function, and a derived class
130 
131 class B{
132 public:
133         virtual void ricky(int i)
134            {cout << "B::ricky: " << i<<endl;}
135 };
136 
137 class D:public B{
138 public:
139         void ricky(int i)
140            {cout << "D::ricky: " << i<<endl;}
141 };
142 
143 void main()
144         {
145         //create a typedef of the functor type to simplify dummy argument
146         typedef Functor1<int> *FtorType;
147 
148         Functor1<int> ftor;     //a functor variable
149         //make a functor from ptr-to-function
150         ftor = functor( fred );
151         do5Times(ftor);
152         //note ethel is not an exact match - ok, is compatible
153         ftor = functor( ethel );
154         do5Times(ftor);
155 
156         //create a D object to be a callback target
157         D myD;
158         //make functor from object and ptr-to-member-func
159         ftor = functor( myD,&B::ricky );
160         do5Times(ftor);
161         }
162 /////////////////////// END of example 1 //////////////////////////
163 
164 /////////////////////// BEGIN Example 2 //////////////////////////
165 #include <iostream.h>
166 #include "callback.hpp"
167 
168 //Button is a component that provides a functor-based
169 //callback mechanism, so you can wire it up to whatever you wish
170 
171 class Button{
172 public:
173         //ctor takes a functor and stores it away in a member
174 
175         Button(const Functor0 &uponClickDoThis):notify(uponClickDoThis)
176                 {}
177         void click()
178                 {
179                 //invoke the functor, thus calling back client
180                 notify();
181                 }
182 private:
183         //note this is a data member with a verb for a name - matches its
184         //function-like usage
185         Functor0 notify;
186 };
187 
188 class CDPlayer{
189 public:
190         void play()
191                 {cout << "Playing"<<endl;}
192         void stop()
193                 {cout << "Stopped"<<endl;}
194 };
195 
196 void main()
197         {
198         CDPlayer myCD;
199         Button playButton(functor((Functor0*)0,myCD,&CDPlayer::play));
200         Button stopButton(functor((Functor0*)0,myCD,&CDPlayer::stop));
201         playButton.click();     //calls myCD.play()
202         stopButton.click();  //calls myCD.stop()
203         }
204 /////////////////////// END of example 2 //////////////////////////
205 
206 */
207 
208 //******************************************************************
209 ///////////////////////////////////////////////////////////////////*
210 //WARNING - no need to read past this point, lest confusion ensue. *
211 //Only the curious need explore further - but remember                           *
212 //about that cat!                                                                                                                                        *
213 ///////////////////////////////////////////////////////////////////*
214 //******************************************************************
215 
216 //////////////////////////////
217 // COMPILER BUG WORKAROUNDS:
218 // As of version 4.02 Borland has a code generation bug
219 // returning the result of a call via a ptr-to-function in a template
220 
221 #ifdef __BORLANDC__
222 #define RHCB_BC4_RET_BUG(x) RT(x)
223 #else
224 #define RHCB_BC4_RET_BUG(x) x
225 #endif
226 
227 // MS VC++ 4.2 still has many bugs relating to templates
228 // This version works around them as best I can - however note that
229 // MS will allow 'void (T::*)()const' to bind to a non-const member function
230 // of T. In addition, they do not support overloading template functions
231 // based on constness of ptr-to-mem-funcs.
232 // When _MSC_VER is defined I provide only the const versions,however it is on
233 // the user's head, when calling functor with a const T, to make sure
234 // that the pointed-to member function is also const since MS won't enforce it!
235 
236 // Other than that the port is completely functional under VC++ 4.2
237 
238 // One MS bug you may encounter during _use_ of the callbacks:
239 // If you pass them by reference you can't call op() on the reference
240 // Workaround is to pass by value.
241 
242 /*
243 // MS unable to call operator() on template class reference
244 template <class T>
245 class Functor{
246 public:
247         void operator()(T t)const{};
248 };
249 
250 void foo(const Functor<int> &f)
251         {
252         f(1);   //error C2064: term does not evaluate to a function
253 
254         //works when f is passed by value
255         }
256 */
257 
258 // Note: if you are porting to another compiler that is having trouble you
259 // can try defining some of these flags as well:
260 
261 
262 #if defined(_MSC_VER)
263 #define RHCB_CANT_PASS_MEMFUNC_BY_REFERENCE     //like it says
264 //#define RHCB_CANT_OVERLOAD_ON_CONSTNESS               //of mem funcs
265 #define RHCB_CANT_INIT_REFERENCE_CTOR_STYLE     //int i;int &ir(i); //MS falls down
266 //#define RHCB_WONT_PERFORM_PTR_CONVERSION              //of 0 to ptr-to-any-type
267 #endif
268 
269 
270 // Don't touch this stuff
271 #if defined(RHCB_CANT_PASS_MEMFUNC_BY_REFERENCE)
272 #define RHCB_CONST_REF
273 #else
274 #define RHCB_CONST_REF const &
275 #endif
276 
277 #if defined(RHCB_CANT_INIT_REFERENCE_CTOR_STYLE)
278 #define RHCB_CTOR_STYLE_INIT =
279 #else
280 #define RHCB_CTOR_STYLE_INIT
281 #endif
282 
283 #if defined(RHCB_WONT_PERFORM_PTR_CONVERSION)
284 #define RHCB_DUMMY_INIT int
285 #else
286 #define RHCB_DUMMY_INIT DummyInit *
287 #endif
288 
289 ////////////////////////////// THE CODE //////////////////////////
290 
291 //change these when your compiler gets bool
292 typedef bool    RHCB_BOOL;
293 
294 //#include <string.h> //for memstuff
295 //#include <stddef.h> //for size_t
296 
297 //typeless representation of a function and optional object
298 typedef void (*PtrToFunc)();
299 
300 class FunctorBase {
301 public:
302         //Note: ctors are protected
303 
304         //for evaluation in conditionals - can the functor be called?
RHCB_BOOL()305         operator RHCB_BOOL()const{return callee||func;}
306 
307         //Now you can put them in containers _and_ remove them!
308         //Source for these 3 is in callback.cpp
309         friend bool     operator==(const FunctorBase &lhs,const FunctorBase &rhs);
310         friend bool     operator!=(const FunctorBase &lhs,const FunctorBase &rhs);
311         friend bool     operator<(const FunctorBase &lhs,const FunctorBase &rhs);
312 
313         //The rest below for implementation use only !
314 
315         class DummyInit{
316         };
317 
318         typedef void (FunctorBase::*PMemFunc)();
319         enum {MEM_FUNC_SIZE = sizeof(PMemFunc)};
320 
getFunc()321         PtrToFunc       getFunc() const {return func;}
getCallee()322         void *getCallee() const {return callee;}
getMemFunc()323         const char *getMemFunc() const {return memFunc;}
324 
325         protected:
326                 ////////////////////////////////////////////////////////////////
327                 // Note: this code depends on all ptr-to-mem-funcs being same size
328                 // If that is not the case then make memFunc as large as largest
329                 ////////////////////////////////////////////////////////////////
330         union{
331                 PtrToFunc func;
332                 char memFunc[MEM_FUNC_SIZE*2]; // Make sure we support multiple inheritance.
333         };
334         void *callee;
335 
FunctorBase()336         FunctorBase() : func(0),callee(0) {}
FunctorBase(const void * c,PtrToFunc f,const void * mf,size_t sz)337         FunctorBase(const void *c,PtrToFunc f, const void *mf,size_t sz) : callee((void *)c)
338         {
339                 if (c)  //must be callee/memfunc
340                 {
341                         assert(sz <= MEM_FUNC_SIZE * 2);
342                         memcpy(memFunc,mf,sz);
343                         if(sz<MEM_FUNC_SIZE)    //zero-out the rest, if any, so comparisons work
344                         {
345                                 memset(memFunc+sz,0,MEM_FUNC_SIZE-sz);
346                         }
347                 }
348                 else    //must be ptr-to-func
349                 {
350                         func = f;
351                 }
352         }
353 };
354 
355 
356 /************************* no arg - no return *******************/
357 class Functor0:public FunctorBase{
358 public:
359         Functor0(RHCB_DUMMY_INIT = 0){}
operator()360         void operator()()const
361                 {
362                 thunk(*this);
363                 }
364 protected:
365         typedef void (*Thunk)(const FunctorBase &);
Functor0(Thunk t,const void * c,PtrToFunc f,const void * mf,size_t sz)366         Functor0(Thunk t,const void *c,PtrToFunc f,const void *mf,size_t sz):
367                 FunctorBase(c,f,mf,sz),thunk(t){}
368 private:
369         Thunk thunk;
370 };
371 
372 template <class Callee, class MemFunc>
373 class CBMemberTranslator0:public Functor0{
374 public:
CBMemberTranslator0(Callee & c,const MemFunc & m)375         CBMemberTranslator0(Callee &c,const MemFunc &m):
376                 Functor0(thunk,&c,0,&m,sizeof(MemFunc)){}
thunk(const FunctorBase & ftor)377         static void thunk(const FunctorBase &ftor)
378                 {
379                 Callee *callee = (Callee *)ftor.getCallee();
380                 MemFunc &memFunc RHCB_CTOR_STYLE_INIT
381                         (*(MemFunc*)(void *)(ftor.getMemFunc()));
382                 (callee->*memFunc)();
383                 }
384 };
385 
386 template <class Func>
387 class CBFunctionTranslator0:public Functor0{
388 public:
CBFunctionTranslator0(Func f)389         CBFunctionTranslator0(Func f):Functor0(thunk,0,(PtrToFunc)f,0,0){}
thunk(const FunctorBase & ftor)390         static void thunk(const FunctorBase &ftor)
391                 {
392                 (Func(ftor.getFunc()))();
393                 }
394 };
395 
396 #if !defined(RHCB_CANT_OVERLOAD_ON_CONSTNESS)
397 template <class Callee,class CallType>
398 inline CBMemberTranslator0<Callee,void (CallType::*)()>
functor(Callee & c,void (CallType::* RHCB_CONST_REF f)())399 functor( Callee &c,void (CallType::* RHCB_CONST_REF f)())
400 {
401         typedef void (CallType::*MemFunc)();
402         return CBMemberTranslator0<Callee,MemFunc>(c,f);
403 }
404 #endif
405 
406 template <class Callee,class CallType>
407 inline CBMemberTranslator0<const Callee,void (CallType::*)()const>
functor(const Callee & c,void (CallType::* RHCB_CONST_REF f)()const)408 functor(const Callee &c,void (CallType::* RHCB_CONST_REF f)()const)
409 {
410         typedef void (CallType::*MemFunc)()const;
411         return CBMemberTranslator0<const Callee,MemFunc>(c,f);
412 }
413 
414 inline CBFunctionTranslator0<void (*)()>
functor(void (* f)())415 functor(void (*f)())
416 {
417         return CBFunctionTranslator0<void (*)()>(f);
418 }
419 
420 /************************* no arg - with return *******************/
421 template <class RT>
422 class Functor0wRet:public FunctorBase{
423 public:
424         Functor0wRet(RHCB_DUMMY_INIT = 0){}
operator()425         RT operator()()const
426                 {
427                 return RHCB_BC4_RET_BUG(thunk(*this));
428                 }
429 protected:
430         typedef RT (*Thunk)(const FunctorBase &);
Functor0wRet(Thunk t,const void * c,PtrToFunc f,const void * mf,size_t sz)431         Functor0wRet(Thunk t,const void *c,PtrToFunc f,const void *mf,size_t sz):
432                 FunctorBase(c,f,mf,sz),thunk(t){}
433 private:
434         Thunk thunk;
435 };
436 
437 template <class RT,class Callee, class MemFunc>
438 class CBMemberTranslator0wRet:public Functor0wRet<RT>{
439 public:
CBMemberTranslator0wRet(Callee & c,const MemFunc & m)440         CBMemberTranslator0wRet(Callee &c,const MemFunc &m):
441                         Functor0wRet<RT>(thunk,&c,0,&m,sizeof(MemFunc)){}
thunk(const FunctorBase & ftor)442                         static RT thunk(const FunctorBase &ftor)
443                         {
444                                 Callee *callee = (Callee *)ftor.getCallee();
445                                 MemFunc &memFunc RHCB_CTOR_STYLE_INIT
446                                         (*(MemFunc*)(void *)(ftor.getMemFunc()));
447                                 return RHCB_BC4_RET_BUG((callee->*memFunc)());
448                         }
449 };
450 
451 template <class RT,class Func>
452 class CBFunctionTranslator0wRet:public Functor0wRet<RT>{
453 public:
CBFunctionTranslator0wRet(Func f)454         CBFunctionTranslator0wRet(Func f):Functor0wRet<RT>(thunk,0,(PtrToFunc)f,0,0){}
thunk(const FunctorBase & ftor)455         static RT thunk(const FunctorBase &ftor)
456                 {
457                 return (Func(ftor.getFunc()))();
458                 }
459 };
460 
461 #if !defined(RHCB_CANT_OVERLOAD_ON_CONSTNESS)
462 template <class RT,class Callee,class CallType>
463 inline CBMemberTranslator0wRet<RT,Callee,RT (CallType::*)()>
functor(Callee & c,RT (CallType::* RHCB_CONST_REF f)())464 functor( Callee &c,RT (CallType::* RHCB_CONST_REF f)())
465 {
466         typedef RT (CallType::*MemFunc)();
467         return CBMemberTranslator0wRet<RT,Callee,MemFunc>(c,f);
468 }
469 #endif
470 
471 template <class RT,class Callee,class CallType>
472 inline CBMemberTranslator0wRet<RT,const Callee,RT (CallType::*)()const>
functor(const Callee & c,RT (CallType::* RHCB_CONST_REF f)()const)473 functor( const Callee &c,RT (CallType::* RHCB_CONST_REF f)()const)
474 {
475         typedef RT (CallType::*MemFunc)()const;
476         return CBMemberTranslator0wRet<RT,const Callee,MemFunc>(c,f);
477 }
478 
479 template <class RT>
480 inline CBFunctionTranslator0wRet<RT,RT (*)()>
functor(RT (* f)())481 functor( RT (*f)() )
482 {
483         return CBFunctionTranslator0wRet<RT,RT (*)()>(f);
484 }
485 
486 /************************* one arg - no return *******************/
487 template <class P1>
488 class Functor1:public FunctorBase {
489 public:
490         Functor1(RHCB_DUMMY_INIT = 0){}
operator()491         void operator()(P1 p1)const
492                 {
493                 thunk(*this,p1);
494                 }
495         //for STL
496         typedef P1 argument_type;
497         typedef void result_type;
498 protected:
499         typedef void (*Thunk)(const FunctorBase &,P1);
Functor1(Thunk t,const void * c,PtrToFunc f,const void * mf,size_t sz)500         Functor1(Thunk t,const void *c,PtrToFunc f,const void *mf,size_t sz):
501                 FunctorBase(c,f,mf,sz),thunk(t){}
502 private:
503         Thunk thunk;
504 };
505 
506 template <class P1,class Callee, class MemFunc>
507 class CBMemberTranslator1:public Functor1<P1>{
508 public:
CBMemberTranslator1(Callee & c,const MemFunc & m)509         CBMemberTranslator1(Callee &c,const MemFunc &m):
510                         Functor1<P1>(thunk,&c,0,&m,sizeof(MemFunc)){}
thunk(const FunctorBase & ftor,P1 p1)511                         static void thunk(const FunctorBase &ftor,P1 p1)
512                         {
513                                 Callee *callee = (Callee *)ftor.getCallee();
514                                 MemFunc &memFunc RHCB_CTOR_STYLE_INIT
515                                         (*(MemFunc*)(void *)(ftor.getMemFunc()));
516                                 (callee->*memFunc)(p1);
517                         }
518 };
519 
520 template <class P1,class Func>
521 class CBFunctionTranslator1:public Functor1<P1>{
522 public:
CBFunctionTranslator1(Func f)523         CBFunctionTranslator1(Func f):Functor1<P1>(thunk,0,(PtrToFunc)f,0,0){}
thunk(const FunctorBase & ftor,P1 p1)524         static void thunk(const FunctorBase &ftor,P1 p1)
525                 {
526                 (Func(ftor.getFunc()))(p1);
527                 }
528 };
529 
530 #if !defined(RHCB_CANT_OVERLOAD_ON_CONSTNESS)
531 template <class P1,class Callee,class CallType>
532 inline CBMemberTranslator1<P1,Callee,void (CallType::*)(P1)>
functor(Callee & c,void (CallType::* RHCB_CONST_REF f)(P1))533 functor(Callee &c,void (CallType::* RHCB_CONST_REF f)(P1))
534 {
535         typedef void (CallType::*MemFunc)(P1);
536         return CBMemberTranslator1<P1,Callee,MemFunc>(c,f);
537 }
538 #endif
539 
540 template <class Callee,class CallType,class P1,class RT>
541 inline CBMemberTranslator1<P1,const Callee,RT (CallType::*)(P1)const>
functor(const Callee & c,RT (CallType::* RHCB_CONST_REF f)(P1)const)542 functor(const Callee &c,RT (CallType::* RHCB_CONST_REF f)(P1)const)
543 {
544         typedef RT (CallType::*MemFunc)(P1)const;
545         return CBMemberTranslator1<P1,const Callee,MemFunc>(c,f);
546 }
547 
548 template <class RT,class P1>
549 inline CBFunctionTranslator1<P1,RT (*)(P1)>
functor(RT (* f)(P1))550 functor( RT (*f)(P1) )
551 {
552         return CBFunctionTranslator1<P1,RT (*)(P1)>(f);
553 }
554 
555 template <class P1,class MemFunc>
556 class CBMemberOf1stArgTranslator1:public Functor1<P1>{
557 public:
CBMemberOf1stArgTranslator1(const MemFunc & m)558         CBMemberOf1stArgTranslator1(const MemFunc &m):
559                         Functor1<P1>(thunk,(void *)1,0,&m,sizeof(MemFunc)){}
thunk(const FunctorBase & ftor,P1 p1)560                         static void thunk(const FunctorBase &ftor,P1 p1)
561                         {
562                                 MemFunc &memFunc RHCB_CTOR_STYLE_INIT
563                                         (*(MemFunc*)(void *)(ftor.getMemFunc()));
564                                 (p1.*memFunc)();
565                         }
566 };
567 
568 #if !defined(RHCB_CANT_OVERLOAD_ON_CONSTNESS)
569 template <class RT,class P1,class CallType>
570 inline CBMemberOf1stArgTranslator1<P1,RT (CallType::*)()>
functor(RT (CallType::* RHCB_CONST_REF f)())571 functor( RT (CallType::* RHCB_CONST_REF f)())
572 {
573         typedef RT (CallType::*MemFunc)();
574         return CBMemberOf1stArgTranslator1<P1,MemFunc>(f);
575 }
576 #endif
577 
578 template <class RT,class P1,class CallType>
579 inline CBMemberOf1stArgTranslator1<P1,RT (CallType::*)()const>
functor(RT (CallType::* RHCB_CONST_REF f)()const)580 functor( RT (CallType::* RHCB_CONST_REF f)()const)
581 {
582         typedef RT (CallType::*MemFunc)()const;
583         return CBMemberOf1stArgTranslator1<P1,MemFunc>(f);
584 }
585 /************************* one arg - with return *******************/
586 template <class P1,class RT>
587 class Functor1wRet:public FunctorBase{
588 public:
589         Functor1wRet(RHCB_DUMMY_INIT = 0){}
operator()590         RT operator()(P1 p1)const
591                 {
592                 return RHCB_BC4_RET_BUG(thunk(*this,p1));
593                 }
594         //for STL
595         typedef P1 argument_type;
596         typedef RT result_type;
597 protected:
598         typedef RT (*Thunk)(const FunctorBase &,P1);
Functor1wRet(Thunk t,const void * c,PtrToFunc f,const void * mf,size_t sz)599         Functor1wRet(Thunk t,const void *c,PtrToFunc f,const void *mf,size_t sz):
600                 FunctorBase(c,f,mf,sz),thunk(t){}
601 private:
602         Thunk thunk;
603 };
604 
605 template <class P1,class RT,class Callee, class MemFunc>
606 class CBMemberTranslator1wRet:public Functor1wRet<P1,RT>{
607 public:
CBMemberTranslator1wRet(Callee & c,const MemFunc & m)608         CBMemberTranslator1wRet(Callee &c,const MemFunc &m):
609                         Functor1wRet<P1,RT>(thunk,&c,0,&m,sizeof(MemFunc)){}
thunk(const FunctorBase & ftor,P1 p1)610                         static RT thunk(const FunctorBase &ftor,P1 p1)
611                         {
612                                 Callee *callee = (Callee *)ftor.getCallee();
613                                 MemFunc &memFunc RHCB_CTOR_STYLE_INIT
614                                         (*(MemFunc*)(void *)(ftor.getMemFunc()));
615                                 return RHCB_BC4_RET_BUG((callee->*memFunc)(p1));
616                         }
617 };
618 
619 template <class P1,class RT,class Func>
620 class CBFunctionTranslator1wRet:public Functor1wRet<P1,RT>{
621 public:
CBFunctionTranslator1wRet(Func f)622         CBFunctionTranslator1wRet(Func f):
623                         Functor1wRet<P1,RT>(thunk,0,(PtrToFunc)f,0,0){}
thunk(const FunctorBase & ftor,P1 p1)624                         static RT thunk(const FunctorBase &ftor,P1 p1)
625                         {
626                                 return (Func(ftor.getFunc()))(p1);
627                         }
628 };
629 
630 #if !defined(RHCB_CANT_OVERLOAD_ON_CONSTNESS)
631 template <class Callee,class RT,class CallType,class P1>
632 inline CBMemberTranslator1wRet<P1,RT,Callee,RT (CallType::*)(P1)>
functor_ret(Callee & c,RT (CallType::* RHCB_CONST_REF f)(P1))633 functor_ret( Callee &c,RT (CallType::* RHCB_CONST_REF f)(P1))
634 {
635         typedef RT (CallType::*MemFunc)(P1);
636         return CBMemberTranslator1wRet<P1,RT,Callee,MemFunc>(c,f);
637 }
638 #endif
639 
640 template <class Callee,class RT,class CallType,class P1>
641 inline CBMemberTranslator1wRet<P1,RT,const Callee,RT (CallType::*)(P1)const>
functor_ret(const Callee & c,RT (CallType::* RHCB_CONST_REF f)(P1)const)642 functor_ret( const Callee &c,RT (CallType::* RHCB_CONST_REF f)(P1)const )
643 {
644         typedef RT (CallType::*MemFunc)(P1)const;
645         return CBMemberTranslator1wRet<P1,RT,const Callee,MemFunc>(c,f);
646 }
647 
648 template <class RT,class P1>
649 inline CBFunctionTranslator1wRet<P1,RT,RT (*)(P1)>
functor_ret(RT (* f)(P1))650 functor_ret( RT (*f)(P1) )
651 {
652         return CBFunctionTranslator1wRet<P1,RT,RT (*)(P1)>(f);
653 }
654 
655 template <class P1,class RT,class MemFunc>
656 class CBMemberOf1stArgTranslator1wRet:public Functor1wRet<P1,RT>{
657 public:
CBMemberOf1stArgTranslator1wRet(const MemFunc & m)658         CBMemberOf1stArgTranslator1wRet(const MemFunc &m):
659                         Functor1wRet<P1,RT>(thunk,(void *)1,0,&m,sizeof(MemFunc)){}
thunk(const FunctorBase & ftor,P1 p1)660                         static RT thunk(const FunctorBase &ftor,P1 p1)
661                         {
662                                 MemFunc &memFunc RHCB_CTOR_STYLE_INIT
663                                         (*(MemFunc*)(void *)(ftor.getMemFunc()));
664                                 return RHCB_BC4_RET_BUG((p1.*memFunc)());
665                         }
666 };
667 
668 #if !defined(RHCB_CANT_OVERLOAD_ON_CONSTNESS)
669 template <class P1,class RT,class CallType>
670 inline CBMemberOf1stArgTranslator1wRet<P1,RT,RT (CallType::*)()>
functor_ret(RT (CallType::* RHCB_CONST_REF f)())671 functor_ret( RT (CallType::* RHCB_CONST_REF f )())
672 {
673         typedef RT (CallType::*MemFunc)();
674         return CBMemberOf1stArgTranslator1wRet<P1,RT,MemFunc>(f);
675 }
676 #endif
677 
678 template <class P1,class RT,class CallType>
679 inline CBMemberOf1stArgTranslator1wRet<P1,RT,RT (CallType::*)()const>
functor_ret(RT (CallType::* RHCB_CONST_REF f)()const)680 functor_ret( RT (CallType::* RHCB_CONST_REF f)()const )
681 {
682         typedef RT (CallType::*MemFunc)()const;
683         return CBMemberOf1stArgTranslator1wRet<P1,RT,MemFunc>(f);
684 }
685 
686 /************************* two args - no return *******************/
687 template <class P1,class P2>
688 class Functor2:public FunctorBase{
689 public:
690         Functor2(RHCB_DUMMY_INIT = 0){}
operator()691         void operator()(P1 p1,P2 p2)const
692                 {
693                 thunk(*this,p1,p2);
694                 }
695         //for STL
696         typedef P1 first_argument_type;
697         typedef P2 second_argument_type;
698         typedef void result_type;
699 protected:
700         typedef void (*Thunk)(const FunctorBase &,P1,P2);
Functor2(Thunk t,const void * c,PtrToFunc f,const void * mf,size_t sz)701         Functor2(Thunk t,const void *c,PtrToFunc f,const void *mf,size_t sz):
702                 FunctorBase(c,f,mf,sz),thunk(t){}
703 private:
704         Thunk thunk;
705 };
706 
707 template <class P1,class P2,class Callee, class MemFunc>
708 class CBMemberTranslator2:public Functor2<P1,P2>{
709 public:
CBMemberTranslator2(Callee & c,const MemFunc & m)710         CBMemberTranslator2(Callee &c,const MemFunc &m):
711                         Functor2<P1,P2>(thunk,&c,0,&m,sizeof(MemFunc)){}
thunk(const FunctorBase & ftor,P1 p1,P2 p2)712                         static void thunk(const FunctorBase &ftor,P1 p1,P2 p2)
713                         {
714                                 Callee *callee = (Callee *)ftor.getCallee();
715                                 MemFunc &memFunc RHCB_CTOR_STYLE_INIT
716                                         (*(MemFunc*)(void *)(ftor.getMemFunc()));
717                                 (callee->*memFunc)(p1,p2);
718                         }
719 };
720 
721 template <class P1,class P2,class Func>
722 class CBFunctionTranslator2:public Functor2<P1,P2>{
723 public:
CBFunctionTranslator2(Func f)724         CBFunctionTranslator2(Func f):Functor2<P1,P2>(thunk,0,(PtrToFunc)f,0,0){}
thunk(const FunctorBase & ftor,P1 p1,P2 p2)725         static void thunk(const FunctorBase &ftor,P1 p1,P2 p2)
726                 {
727                 (Func(ftor.getFunc()))(p1,p2);
728                 }
729 };
730 
731 //#if !defined(RHCB_CANT_OVERLOAD_ON_CONSTNESS)
732 //template <class Callee,class RT,class CallType,class P1,class P2>
733 //inline CBMemberTranslator2<P1,P2,Callee,RT (CallType::*)(P1,P2)>
734 //functor( Callee &c,RT (CallType::* RHCB_CONST_REF f)(P1,P2) )
735 //{
736 //        typedef RT (CallType::*MemFunc)(P1,P2);
737 //        return CBMemberTranslator2<P1,P2,Callee,MemFunc>(c,f);
738 //}
739 //#endif
740 
741 template <class Callee,class RT,class CallType,class P1,class P2>
742 inline CBMemberTranslator2<P1,P2,const Callee,
743 RT (CallType::*)(P1,P2)const>
functor(const Callee & c,RT (CallType::* RHCB_CONST_REF f)(P1,P2)const)744 functor( const Callee &c,RT (CallType::* RHCB_CONST_REF f)(P1,P2)const)
745 {
746         typedef RT (CallType::*MemFunc)(P1,P2)const;
747         return CBMemberTranslator2<P1,P2,const Callee,MemFunc>(c,f);
748 }
749 
750 template <class RT,class P1,class P2>
751 inline CBFunctionTranslator2<P1,P2,RT (*)(P1,P2)>
functor(RT (* f)(P1,P2))752 functor( RT (*f)(P1,P2))
753 {
754         return CBFunctionTranslator2<P1,P2,RT (*)(P1,P2)>(f);
755 }
756 
757 template <class P1,class P2,class MemFunc>
758 class CBMemberOf1stArgTranslator2:public Functor2<P1,P2>{
759 public:
CBMemberOf1stArgTranslator2(const MemFunc & m)760         CBMemberOf1stArgTranslator2(const MemFunc &m):
761                         Functor2<P1,P2>(thunk,(void *)1,0,&m,sizeof(MemFunc)){}
thunk(const FunctorBase & ftor,P1 p1,P2 p2)762                         static void thunk(const FunctorBase &ftor,P1 p1,P2 p2)
763                         {
764                                 MemFunc &memFunc RHCB_CTOR_STYLE_INIT
765                                         (*(MemFunc*)(void *)(ftor.getMemFunc()));
766                                 (p1.*memFunc)(p2);
767                         }
768 };
769 
770 #if !defined(RHCB_CANT_OVERLOAD_ON_CONSTNESS)
771 template <class P1,class P2,class RT,class CallType>
772 inline CBMemberOf1stArgTranslator2<P1,P2,RT (CallType::*)(P1)>
functor(RT (CallType::* RHCB_CONST_REF f)(P1))773 functor( RT (CallType::* RHCB_CONST_REF f)(P1))
774 {
775         typedef RT (CallType::*MemFunc)(P1);
776         return CBMemberOf1stArgTranslator2<P1,P2,MemFunc>(f);
777 }
778 #endif
779 
780 template <class P1,class P2,class RT,class CallType>
781 inline CBMemberOf1stArgTranslator2<P1,P2,RT (CallType::*)(P1)const>
functor(RT (CallType::* RHCB_CONST_REF f)(P1)const)782 functor( RT (CallType::* RHCB_CONST_REF f)(P1)const)
783 {
784         typedef RT (CallType::*MemFunc)(P1)const;
785         return CBMemberOf1stArgTranslator2<P1,P2,MemFunc>(f);
786 }
787 
788 
789 /************************* two args - with return *******************/
790 template <class P1,class P2,class RT>
791 class Functor2wRet:public FunctorBase{
792 public:
793         Functor2wRet(RHCB_DUMMY_INIT = 0){}
operator()794         RT operator()(P1 p1,P2 p2)const
795                 {
796                 return RHCB_BC4_RET_BUG(thunk(*this,p1,p2));
797                 }
798         //for STL
799         typedef P1 first_argument_type;
800         typedef P2 second_argument_type;
801         typedef RT result_type;
802 protected:
803         typedef RT (*Thunk)(const FunctorBase &,P1,P2);
Functor2wRet(Thunk t,const void * c,PtrToFunc f,const void * mf,size_t sz)804         Functor2wRet(Thunk t,const void *c,PtrToFunc f,const void *mf,size_t sz):
805                 FunctorBase(c,f,mf,sz),thunk(t){}
806 private:
807         Thunk thunk;
808 };
809 
810 template <class P1,class P2,class RT,class Callee, class MemFunc>
811 class CBMemberTranslator2wRet:public Functor2wRet<P1,P2,RT>{
812 public:
CBMemberTranslator2wRet(Callee & c,const MemFunc & m)813         CBMemberTranslator2wRet(Callee &c,const MemFunc &m):
814                         Functor2wRet<P1,P2,RT>(thunk,&c,0,&m,sizeof(MemFunc)){}
thunk(const FunctorBase & ftor,P1 p1,P2 p2)815                         static RT thunk(const FunctorBase &ftor,P1 p1,P2 p2)
816                         {
817                                 Callee *callee = (Callee *)ftor.getCallee();
818                                 MemFunc &memFunc RHCB_CTOR_STYLE_INIT
819                                         (*(MemFunc*)(void *)(ftor.getMemFunc()));
820                                 return RHCB_BC4_RET_BUG((callee->*memFunc)(p1,p2));
821                         }
822 };
823 
824 template <class P1,class P2,class RT,class Func>
825 class CBFunctionTranslator2wRet:public Functor2wRet<P1,P2,RT>{
826 public:
CBFunctionTranslator2wRet(Func f)827         CBFunctionTranslator2wRet(Func f):
828                         Functor2wRet<P1,P2,RT>(thunk,0,(PtrToFunc)f,0,0){}
thunk(const FunctorBase & ftor,P1 p1,P2 p2)829                         static RT thunk(const FunctorBase &ftor,P1 p1,P2 p2)
830                         {
831                                 return (Func(ftor.getFunc()))(p1,p2);
832                         }
833 };
834 
835 #if !defined(RHCB_CANT_OVERLOAD_ON_CONSTNESS)
836 template <class Callee,class RT,class CallType,class P1,class P2>
837 inline CBMemberTranslator2wRet<P1,P2,RT,Callee,
838 RT (CallType::*)(P1,P2)>
functor_ret(Callee & c,RT (CallType::* RHCB_CONST_REF f)(P1,P2))839 functor_ret( Callee &c,RT (CallType::* RHCB_CONST_REF f)(P1,P2))
840 {
841         typedef RT (CallType::*MemFunc)(P1,P2);
842         return CBMemberTranslator2wRet<P1,P2,RT,Callee,MemFunc>(c,f);
843 }
844 #endif
845 
846 template <class Callee,class RT,class CallType,class P1,class P2>
847 inline CBMemberTranslator2wRet<P1,P2,RT,const Callee,
848 RT (CallType::*)(P1,P2)const>
functor_ret(const Callee & c,RT (CallType::* RHCB_CONST_REF f)(P1,P2)const)849 functor_ret( const Callee &c,RT (CallType::* RHCB_CONST_REF f)(P1,P2)const)
850 {
851         typedef RT (CallType::*MemFunc)(P1,P2)const;
852         return CBMemberTranslator2wRet<P1,P2,RT,const Callee,MemFunc>(c,f);
853 }
854 
855 template <class RT,class P1,class P2>
856 inline CBFunctionTranslator2wRet<P1,P2,RT,RT (*)(P1,P2)>
functor_ret(RT (* f)(P1,P2))857 functor_ret( RT (*f)(P1,P2))
858 {
859         return CBFunctionTranslator2wRet<P1,P2,RT,RT (*)(P1,P2)>(f);
860 }
861 
862 template <class P1,class P2,class RT,class MemFunc>
863 class CBMemberOf1stArgTranslator2wRet:public Functor2wRet<P1,P2,RT>{
864 public:
CBMemberOf1stArgTranslator2wRet(const MemFunc & m)865         CBMemberOf1stArgTranslator2wRet(const MemFunc &m):
866                         Functor2wRet<P1,P2,RT>(thunk,(void *)1,0,&m,sizeof(MemFunc)){}
thunk(const FunctorBase & ftor,P1 p1,P2 p2)867                         static RT thunk(const FunctorBase &ftor,P1 p1,P2 p2)
868                         {
869                                 MemFunc &memFunc RHCB_CTOR_STYLE_INIT
870                                         (*(MemFunc*)(void *)(ftor.getMemFunc()));
871                                 return RHCB_BC4_RET_BUG((p1.*memFunc)(p2));
872                         }
873 };
874 
875 #if !defined(RHCB_CANT_OVERLOAD_ON_CONSTNESS)
876 template <class P1,class P2,class RT,class CallType>
877 inline CBMemberOf1stArgTranslator2wRet<P1,P2,RT,RT (CallType::*)(P1)>
functor_ret(RT (CallType::* RHCB_CONST_REF f)(P1))878 functor_ret( RT (CallType::* RHCB_CONST_REF f)(P1))
879 {
880         typedef RT (CallType::*MemFunc)(P1);
881         return CBMemberOf1stArgTranslator2wRet<P1,P2,RT,MemFunc>(f);
882 }
883 #endif
884 
885 template <class P1,class P2,class RT,class CallType>
886 inline CBMemberOf1stArgTranslator2wRet<P1,P2,RT,RT (CallType::*)(P1)const>
functor_ret(RT (CallType::* RHCB_CONST_REF f)(P1)const)887 functor_ret( RT (CallType::* RHCB_CONST_REF f)(P1)const)
888 {
889         typedef RT (CallType::*MemFunc)(P1)const;
890         return CBMemberOf1stArgTranslator2wRet<P1,P2,RT,MemFunc>(f);
891 }
892 
893 
894 /************************ three args - no return *******************/
895 template <class P1,class P2,class P3>
896 class Functor3:public FunctorBase{
897 public:
898         Functor3(RHCB_DUMMY_INIT = 0){}
operator()899         void operator()(P1 p1,P2 p2,P3 p3)const
900                 {
901                 thunk(*this,p1,p2,p3);
902                 }
903 protected:
904         typedef void (*Thunk)(const FunctorBase &,P1,P2,P3);
Functor3(Thunk t,const void * c,PtrToFunc f,const void * mf,size_t sz)905         Functor3(Thunk t,const void *c,PtrToFunc f,const void *mf,size_t sz):
906                 FunctorBase(c,f,mf,sz),thunk(t){}
907 private:
908         Thunk thunk;
909 };
910 
911 template <class P1,class P2,class P3,class Callee, class MemFunc>
912 class CBMemberTranslator3:public Functor3<P1,P2,P3>{
913 public:
CBMemberTranslator3(Callee & c,const MemFunc & m)914         CBMemberTranslator3(Callee &c,const MemFunc &m):
915                         Functor3<P1,P2,P3>(thunk,&c,0,&m,sizeof(MemFunc)){}
thunk(const FunctorBase & ftor,P1 p1,P2 p2,P3 p3)916                         static void thunk(const FunctorBase &ftor,P1 p1,P2 p2,P3 p3)
917                         {
918                                 Callee *callee = (Callee *)ftor.getCallee();
919                                 MemFunc &memFunc RHCB_CTOR_STYLE_INIT
920                                         (*(MemFunc*)(void *)(ftor.getMemFunc()));
921                                 (callee->*memFunc)(p1,p2,p3);
922                         }
923 };
924 
925 template <class P1,class P2,class P3,class Func>
926 class CBFunctionTranslator3:public Functor3<P1,P2,P3>{
927 public:
CBFunctionTranslator3(Func f)928         CBFunctionTranslator3(Func f):Functor3<P1,P2,P3>(thunk,0,(PtrToFunc)f,0,0){}
thunk(const FunctorBase & ftor,P1 p1,P2 p2,P3 p3)929         static void thunk(const FunctorBase &ftor,P1 p1,P2 p2,P3 p3)
930                 {
931                 (Func(ftor.getFunc()))(p1,p2,p3);
932                 }
933 };
934 
935 #if !defined(RHCB_CANT_OVERLOAD_ON_CONSTNESS)
936 template <class Callee,class RT,class CallType,class P1,class P2,class P3>
937 inline CBMemberTranslator3<P1,P2,P3,Callee,
938 RT (CallType::*)(P1,P2,P3)>
functor(Callee & c,RT (CallType::* RHCB_CONST_REF f)(P1,P2,P3))939 functor( Callee &c,RT (CallType::* RHCB_CONST_REF f)(P1,P2,P3))
940 {
941         typedef RT (CallType::*MemFunc)(P1,P2,P3);
942         return CBMemberTranslator3<P1,P2,P3,Callee,MemFunc>(c,f);
943 }
944 #endif
945 
946 template <class Callee,class RT,class CallType,class P1,class P2,class P3>
947 inline CBMemberTranslator3<P1,P2,P3,const Callee,
948 RT (CallType::*)(P1,P2,P3)const>
functor(const Callee & c,RT (CallType::* RHCB_CONST_REF f)(P1,P2,P3)const)949 functor( const Callee &c,RT (CallType::* RHCB_CONST_REF f)(P1,P2,P3)const)
950 {
951         typedef RT (CallType::*MemFunc)(P1,P2,P3)const;
952         return CBMemberTranslator3<P1,P2,P3,const Callee,MemFunc>(c,f);
953 }
954 
955 template <class RT,class P1,class P2,class P3>
956 inline CBFunctionTranslator3<P1,P2,P3,RT (*)(P1,P2,P3)>
functor(RT (* f)(P1,P2,P3))957 functor( RT (*f)(P1,P2,P3))
958 {
959         return CBFunctionTranslator3<P1,P2,P3,RT (*)(P1,P2,P3)>(f);
960 }
961 
962 template <class P1,class P2,class P3,class MemFunc>
963 class CBMemberOf1stArgTranslator3:public Functor3<P1,P2,P3>{
964 public:
CBMemberOf1stArgTranslator3(const MemFunc & m)965         CBMemberOf1stArgTranslator3(const MemFunc &m):
966                         Functor3<P1,P2,P3>(thunk,(void *)1,0,&m,sizeof(MemFunc)){}
thunk(const FunctorBase & ftor,P1 p1,P2 p2,P3 p3)967                         static void thunk(const FunctorBase &ftor,P1 p1,P2 p2,P3 p3)
968                         {
969                                 MemFunc &memFunc RHCB_CTOR_STYLE_INIT
970                                         (*(MemFunc*)(void *)(ftor.getMemFunc()));
971                                 (p1.*memFunc)(p2,p3);
972                         }
973 };
974 
975 #if !defined(RHCB_CANT_OVERLOAD_ON_CONSTNESS)
976 template <class P1,class P2,class P3,class RT,class CallType>
977 inline CBMemberOf1stArgTranslator3<P1,P2,P3,RT (CallType::*)(P1,P2)>
functor(RT (CallType::* RHCB_CONST_REF f)(P1,P2))978 functor( RT (CallType::* RHCB_CONST_REF f)(P1,P2))
979 {
980         typedef RT (CallType::*MemFunc)(P1,P2);
981         return CBMemberOf1stArgTranslator3<P1,P2,P3,MemFunc>(f);
982 }
983 #endif
984 
985 template <class P1,class P2,class P3,class RT,class CallType>
986 inline CBMemberOf1stArgTranslator3<P1,P2,P3,RT (CallType::*)(P1,P2)const>
functor(RT (CallType::* RHCB_CONST_REF f)(P1,P2)const)987 functor( RT (CallType::* RHCB_CONST_REF f)(P1,P2)const)
988 {
989         typedef RT (CallType::*MemFunc)(P1,P2)const;
990         return CBMemberOf1stArgTranslator3<P1,P2,P3,MemFunc>(f);
991 }
992 
993 
994 /************************* three args - with return *******************/
995 template <class P1,class P2,class P3,class RT>
996 class Functor3wRet:public FunctorBase{
997 public:
998         Functor3wRet(RHCB_DUMMY_INIT = 0){}
operator()999         RT operator()(P1 p1,P2 p2,P3 p3)const
1000                 {
1001                 return RHCB_BC4_RET_BUG(thunk(*this,p1,p2,p3));
1002                 }
1003 protected:
1004         typedef RT (*Thunk)(const FunctorBase &,P1,P2,P3);
Functor3wRet(Thunk t,const void * c,PtrToFunc f,const void * mf,size_t sz)1005         Functor3wRet(Thunk t,const void *c,PtrToFunc f,const void *mf,size_t sz):
1006                 FunctorBase(c,f,mf,sz),thunk(t){}
1007 private:
1008         Thunk thunk;
1009 };
1010 
1011 template <class P1,class P2,class P3,
1012 class RT,class Callee, class MemFunc>
1013 class CBMemberTranslator3wRet:public Functor3wRet<P1,P2,P3,RT>{
1014 public:
CBMemberTranslator3wRet(Callee & c,const MemFunc & m)1015         CBMemberTranslator3wRet(Callee &c,const MemFunc &m):
1016                         Functor3wRet<P1,P2,P3,RT>(thunk,&c,0,&m,sizeof(MemFunc)){}
thunk(const FunctorBase & ftor,P1 p1,P2 p2,P3 p3)1017                         static RT thunk(const FunctorBase &ftor,P1 p1,P2 p2,P3 p3)
1018                         {
1019                                 Callee *callee = (Callee *)ftor.getCallee();
1020                                 MemFunc &memFunc RHCB_CTOR_STYLE_INIT
1021                                         (*(MemFunc*)(void *)(ftor.getMemFunc()));
1022                                 return RHCB_BC4_RET_BUG((callee->*memFunc)(p1,p2,p3));
1023                         }
1024 };
1025 
1026 template <class P1,class P2,class P3,class RT,class Func>
1027 class CBFunctionTranslator3wRet:public Functor3wRet<P1,P2,P3,RT>{
1028 public:
CBFunctionTranslator3wRet(Func f)1029         CBFunctionTranslator3wRet(Func f):
1030                         Functor3wRet<P1,P2,P3,RT>(thunk,0,(PtrToFunc)f,0,0){}
thunk(const FunctorBase & ftor,P1 p1,P2 p2,P3 p3)1031                         static RT thunk(const FunctorBase &ftor,P1 p1,P2 p2,P3 p3)
1032                         {
1033                                 return (Func(ftor.getFunc()))(p1,p2,p3);
1034                         }
1035 };
1036 
1037 #if !defined(RHCB_CANT_OVERLOAD_ON_CONSTNESS)
1038 template <class P1,class P2,class P3,class RT,class Callee,class CallType>
1039 inline CBMemberTranslator3wRet<P1,P2,P3,RT,Callee,
1040 RT (CallType::*)(P1,P2,P3)>
functor(Callee & c,RT (CallType::* RHCB_CONST_REF f)(P1,P2,P3))1041 functor( Callee &c,RT (CallType::* RHCB_CONST_REF f)(P1,P2,P3))
1042 {
1043         typedef RT (CallType::*MemFunc)(P1,P2,P3);
1044         return CBMemberTranslator3wRet<P1,P2,P3,RT,Callee,MemFunc>(c,f);
1045 }
1046 #endif
1047 
1048 template <class Callee,class RT,class CallType,class P1,class P2,class P3>
1049 inline CBMemberTranslator3wRet<P1,P2,P3,RT,const Callee,
1050 RT (CallType::*)(P1,P2,P3)const>
functor(const Callee & c,RT (CallType::* RHCB_CONST_REF f)(P1,P2,P3)const)1051 functor( const Callee &c,RT (CallType::* RHCB_CONST_REF f)(P1,P2,P3)const)
1052 {
1053         typedef RT (CallType::*MemFunc)(P1,P2,P3)const;
1054         return CBMemberTranslator3wRet<P1,P2,P3,RT,const Callee,MemFunc>(c,f);
1055 }
1056 
1057 template <class RT,class P1,class P2,class P3>
1058 inline CBFunctionTranslator3wRet<P1,P2,P3,RT,RT (*)(P1,P2,P3)>
functor(RT (* f)(P1,P2,P3))1059 functor( RT (*f)(P1,P2,P3) )
1060 {
1061         return CBFunctionTranslator3wRet<P1,P2,P3,RT,RT (*)(P1,P2,P3)>(f);
1062 }
1063 
1064 template <class P1,class P2,class P3,class RT,class MemFunc>
1065 class CBMemberOf1stArgTranslator3wRet:public Functor3wRet<P1,P2,P3,RT>{
1066 public:
CBMemberOf1stArgTranslator3wRet(const MemFunc & m)1067         CBMemberOf1stArgTranslator3wRet(const MemFunc &m):
1068                         Functor3wRet<P1,P2,P3,RT>(thunk,(void *)1,0,&m,sizeof(MemFunc)){}
thunk(const FunctorBase & ftor,P1 p1,P2 p2,P3 p3)1069                         static RT thunk(const FunctorBase &ftor,P1 p1,P2 p2,P3 p3)
1070                         {
1071                                 MemFunc &memFunc RHCB_CTOR_STYLE_INIT
1072                                         (*(MemFunc*)(void *)(ftor.getMemFunc()));
1073                                 return RHCB_BC4_RET_BUG((p1.*memFunc)(p2,p3));
1074                         }
1075 };
1076 
1077 #if !defined(RHCB_CANT_OVERLOAD_ON_CONSTNESS)
1078 template <class P1,class P2,class P3,class RT,class CallType>
1079 inline CBMemberOf1stArgTranslator3wRet<P1,P2,P3,RT,RT (CallType::*)(P1,P2)>
functor(RT (CallType::* RHCB_CONST_REF f)(P1,P2))1080 functor( RT (CallType::* RHCB_CONST_REF f)(P1,P2))
1081 {
1082         typedef RT (CallType::*MemFunc)(P1,P2);
1083         return CBMemberOf1stArgTranslator3wRet<P1,P2,P3,RT,MemFunc>(f);
1084 }
1085 #endif
1086 
1087 template <class P1,class P2,class P3,class RT,class CallType>
1088 inline CBMemberOf1stArgTranslator3wRet<P1,P2,P3,RT,
1089 RT (CallType::*)(P1,P2)const>
functor(RT (CallType::* RHCB_CONST_REF f)(P1,P2)const)1090 functor( RT (CallType::* RHCB_CONST_REF f)(P1,P2)const)
1091 {
1092         typedef RT (CallType::*MemFunc)(P1,P2)const;
1093         return CBMemberOf1stArgTranslator3wRet<P1,P2,P3,RT,MemFunc>(f);
1094 }
1095 
1096 
1097 /************************* four args - no return *******************
1098 template <class P1,class P2,class P3,class P4>
1099 class Functor4:public FunctorBase{
1100 public:
1101         Functor4(RHCB_DUMMY_INIT = 0){}
1102         void operator()(P1 p1,P2 p2,P3 p3,P4 p4)const
1103                 {
1104                 thunk(*this,p1,p2,p3,p4);
1105                 }
1106 protected:
1107         typedef void (*Thunk)(const FunctorBase &,P1,P2,P3,P4);
1108         Functor4(Thunk t,const void *c,PtrToFunc f,const void *mf,size_t sz):
1109                 FunctorBase(c,f,mf,sz),thunk(t){}
1110 private:
1111         Thunk thunk;
1112 };
1113 
1114 template <class P1,class P2,class P3,class P4,
1115 class Callee, class MemFunc>
1116 class CBMemberTranslator4:public Functor4<P1,P2,P3,P4>{
1117 public:
1118         CBMemberTranslator4(Callee &c,const MemFunc &m):
1119                         Functor4<P1,P2,P3,P4>(thunk,&c,0,&m,sizeof(MemFunc)){}
1120                         static void thunk(const FunctorBase &ftor,P1 p1,P2 p2,P3 p3,P4 p4)
1121                         {
1122                                 Callee *callee = (Callee *)ftor.getCallee();
1123                                 MemFunc &memFunc RHCB_CTOR_STYLE_INIT
1124                                         (*(MemFunc*)(void *)(ftor.getMemFunc()));
1125                                 (callee->*memFunc)(p1,p2,p3,p4);
1126                         }
1127 };
1128 
1129 template <class P1,class P2,class P3,class P4,class Func>
1130 class CBFunctionTranslator4:public Functor4<P1,P2,P3,P4>{
1131 public:
1132         CBFunctionTranslator4(Func f):
1133                         Functor4<P1,P2,P3,P4>(thunk,0,(PtrToFunc)f,0,0){}
1134                         static void thunk(const FunctorBase &ftor,P1 p1,P2 p2,P3 p3,P4 p4)
1135                         {
1136                                 (Func(ftor.getFunc()))(p1,p2,p3,p4);
1137                         }
1138 };
1139 
1140 #if !defined(RHCB_CANT_OVERLOAD_ON_CONSTNESS)
1141 template <class Callee,class RT,class CallType,class P1,class P2,class P3,class P4>
1142 inline CBMemberTranslator4<P1,P2,P3,P4,Callee,
1143 RT (CallType::*)(P1,P2,P3,P4)>
1144 functor( Callee &c,RT (CallType::* RHCB_CONST_REF f)(P1,P2,P3,P4))
1145 {
1146         typedef RT (CallType::*MemFunc)(P1,P2,P3,P4);
1147         return CBMemberTranslator4<P1,P2,P3,P4,Callee,MemFunc>(c,f);
1148 }
1149 #endif
1150 
1151 template <class Callee,class RT,class CallType,class P1,class P2,class P3,class P4>
1152 inline CBMemberTranslator4<P1,P2,P3,P4,const Callee,
1153 RT (CallType::*)(P1,P2,P3,P4)const>
1154 functor( const Callee &c,RT (CallType::* RHCB_CONST_REF f)(P1,P2,P3,P4)const)
1155 {
1156         typedef RT (CallType::*MemFunc)(P1,P2,P3,P4)const;
1157         return CBMemberTranslator4<P1,P2,P3,P4,const Callee,MemFunc>(c,f);
1158 }
1159 
1160 template <class RT,class P1,class P2,class P3,class P4>
1161 inline CBFunctionTranslator4<P1,P2,P3,P4,RT (*)(P1,P2,P3,P4)>
1162 functor( RT (*f)(P1,P2,P3,P4))
1163 {
1164         return CBFunctionTranslator4<P1,P2,P3,P4,RT (*)(P1,P2,P3,P4)>(f);
1165 }
1166 
1167 template <class P1,class P2,class P3,class P4,class MemFunc>
1168 class CBMemberOf1stArgTranslator4:public Functor4<P1,P2,P3,P4>{
1169 public:
1170         CBMemberOf1stArgTranslator4(const MemFunc &m):
1171                         Functor4<P1,P2,P3,P4>(thunk,(void *)1,0,&m,sizeof(MemFunc)){}
1172                         static void thunk(const FunctorBase &ftor,P1 p1,P2 p2,P3 p3,P4 p4)
1173                         {
1174                                 MemFunc &memFunc RHCB_CTOR_STYLE_INIT
1175                                         (*(MemFunc*)(void *)(ftor.getMemFunc()));
1176                                 (p1.*memFunc)(p2,p3,p4);
1177                         }
1178 };
1179 
1180 #if !defined(RHCB_CANT_OVERLOAD_ON_CONSTNESS)
1181 template <class P1,class P2,class P3,class P4,class RT,class CallType>
1182 inline CBMemberOf1stArgTranslator4<P1,P2,P3,P4,RT (CallType::*)(P1,P2,P3)>
1183 functor( RT (CallType::* RHCB_CONST_REF f)(P1,P2,P3))
1184 {
1185         typedef RT (CallType::*MemFunc)(P1,P2,P3);
1186         return CBMemberOf1stArgTranslator4<P1,P2,P3,P4,MemFunc>(f);
1187 }
1188 #endif
1189 
1190 template <class P1,class P2,class P3,class P4,class RT,class CallType>
1191 inline CBMemberOf1stArgTranslator4<P1,P2,P3,P4,
1192 RT (CallType::*)(P1,P2,P3)const>
1193 functor( RT (CallType::* RHCB_CONST_REF f)(P1,P2,P3)const)
1194 {
1195         typedef RT (CallType::*MemFunc)(P1,P2,P3)const;
1196         return CBMemberOf1stArgTranslator4<P1,P2,P3,P4,MemFunc>(f);
1197 }
1198 
1199 
1200 ************************* four args - with return *******************
1201 template <class P1,class P2,class P3,class P4,class RT>
1202 class Functor4wRet:public FunctorBase{
1203 public:
1204         Functor4wRet(RHCB_DUMMY_INIT = 0){}
1205         RT operator()(P1 p1,P2 p2,P3 p3,P4 p4)const
1206                 {
1207                 return RHCB_BC4_RET_BUG(thunk(*this,p1,p2,p3,p4));
1208                 }
1209 protected:
1210         typedef RT (*Thunk)(const FunctorBase &,P1,P2,P3,P4);
1211         Functor4wRet(Thunk t,const void *c,PtrToFunc f,const void *mf,size_t sz):
1212                 FunctorBase(c,f,mf,sz),thunk(t){}
1213 private:
1214         Thunk thunk;
1215 };
1216 
1217 template <class P1,class P2,class P3,class P4,class RT,class Callee, class MemFunc>
1218 class CBMemberTranslator4wRet:public Functor4wRet<P1,P2,P3,P4,RT>{
1219 public:
1220         CBMemberTranslator4wRet(Callee &c,const MemFunc &m):
1221                         Functor4wRet<P1,P2,P3,P4,RT>(thunk,&c,0,&m,sizeof(MemFunc)){}
1222                         static RT thunk(const FunctorBase &ftor,P1 p1,P2 p2,P3 p3,P4 p4)
1223                         {
1224                                 Callee *callee = (Callee *)ftor.getCallee();
1225                                 MemFunc &memFunc RHCB_CTOR_STYLE_INIT
1226                                         (*(MemFunc*)(void *)(ftor.getMemFunc()));
1227                                 return RHCB_BC4_RET_BUG((callee->*memFunc)(p1,p2,p3,p4));
1228                         }
1229 };
1230 
1231 template <class P1,class P2,class P3,class P4,class RT,class Func>
1232 class CBFunctionTranslator4wRet:public Functor4wRet<P1,P2,P3,P4,RT>{
1233 public:
1234         CBFunctionTranslator4wRet(Func f):
1235                         Functor4wRet<P1,P2,P3,P4,RT>(thunk,0,(PtrToFunc)f,0,0){}
1236                         static RT thunk(const FunctorBase &ftor,P1 p1,P2 p2,P3 p3,P4 p4)
1237                         {
1238                                 return (Func(ftor.getFunc()))(p1,p2,p3,p4);
1239                         }
1240 };
1241 
1242 #if !defined(RHCB_CANT_OVERLOAD_ON_CONSTNESS)
1243 template <class P1,class P2,class P3,class P4,class RT,class Callee,class CallType>
1244 inline CBMemberTranslator4wRet<P1,P2,P3,P4,RT,Callee,
1245 RT (CallType::*)(P1,P2,P3,P4)>
1246 functor( Callee &c,RT (CallType::* RHCB_CONST_REF f)(P1,P2,P3,P4))
1247 {
1248         typedef RT (CallType::*MemFunc)(P1,P2,P3,P4);
1249         return CBMemberTranslator4wRet<P1,P2,P3,P4,RT,Callee,MemFunc>(c,f);
1250 }
1251 #endif
1252 
1253 template <class Callee,class RT,class CallType,class P1,class P2,class P3,class P4>
1254 inline CBMemberTranslator4wRet<P1,P2,P3,P4,RT,const Callee,
1255 RT (CallType::*)(P1,P2,P3,P4)const>
1256 functor( const Callee &c,RT (CallType::* RHCB_CONST_REF f)(P1,P2,P3,P4)const)
1257 {
1258         typedef RT (CallType::*MemFunc)(P1,P2,P3,P4)const;
1259         return CBMemberTranslator4wRet<P1,P2,P3,P4,RT,const Callee,MemFunc>(c,f);
1260 }
1261 
1262 template <class RT,class P1,class P2,class P3,class P4>
1263 inline CBFunctionTranslator4wRet<P1,P2,P3,P4,RT,RT (*)(P1,P2,P3,P4)>
1264 functor( RT (*f)(P1,P2,P3,P4) )
1265 {
1266         return CBFunctionTranslator4wRet
1267                 <P1,P2,P3,P4,RT,RT (*)(P1,P2,P3,P4)>(f);
1268 }
1269 
1270 
1271 template <class P1,class P2,class P3,class P4,class RT,class MemFunc>
1272 class CBMemberOf1stArgTranslator4wRet:public Functor4wRet<P1,P2,P3,P4,RT>{
1273 public:
1274         CBMemberOf1stArgTranslator4wRet(const MemFunc &m):
1275                         Functor4wRet<P1,P2,P3,P4,RT>(thunk,(void *)1,0,&m,sizeof(MemFunc)){}
1276                         static RT thunk(const FunctorBase &ftor,P1 p1,P2 p2,P3 p3,P4 p4)
1277                         {
1278                                 MemFunc &memFunc RHCB_CTOR_STYLE_INIT
1279                                         (*(MemFunc*)(void *)(ftor.getMemFunc()));
1280                                 return RHCB_BC4_RET_BUG((p1.*memFunc)(p2,p3,p4));
1281                         }
1282 };
1283 
1284 #if !defined(RHCB_CANT_OVERLOAD_ON_CONSTNESS)
1285 template <class P1,class P2,class P3,class P4,class RT,class CallType>
1286 inline CBMemberOf1stArgTranslator4wRet<P1,P2,P3,P4,RT,
1287 RT (CallType::*)(P1,P2,P3)>
1288 functor( RT (CallType::* RHCB_CONST_REF f)(P1,P2,P3))
1289 {
1290         typedef RT (CallType::*MemFunc)(P1,P2,P3);
1291         return CBMemberOf1stArgTranslator4wRet<P1,P2,P3,P4,RT,MemFunc>(f);
1292 }
1293 #endif
1294 
1295 template <class P1,class P2,class P3,class P4,class RT,class CallType>
1296 inline CBMemberOf1stArgTranslator4wRet<P1,P2,P3,P4,RT,
1297 RT (CallType::*)(P1,P2,P3)const>
1298 functor( RT (CallType::* RHCB_CONST_REF f)(P1,P2,P3)const)
1299 {
1300         typedef RT (CallType::*MemFunc)(P1,P2,P3)const;
1301         return CBMemberOf1stArgTranslator4wRet<P1,P2,P3,P4,RT,MemFunc>(f);
1302 }
1303 
1304 
1305 
1306 ************************* five args - no return *******************
1307 template <class P1,class P2,class P3,class P4,class P5>
1308 class Functor5:public FunctorBase{
1309 public:
1310         Functor5(RHCB_DUMMY_INIT = 0){}
1311         void operator()(P1 p1,P2 p2,P3 p3,P4 p4,P5 p5)const
1312         {
1313                 thunk(*this,p1,p2,p3,p4,p5);
1314         }
1315 protected:
1316         typedef void (*Thunk)(const FunctorBase &,P1,P2,P3,P4,P5);
1317         Functor5(Thunk t,const void *c,PtrToFunc f,const void *mf,size_t sz):
1318         FunctorBase(c,f,mf,sz),thunk(t){}
1319 private:
1320         Thunk thunk;
1321 };
1322 
1323 template <class P1,class P2,class P3,class P4,class P5,
1324 class Callee, class MemFunc>
1325 class CBMemberTranslator5:public Functor5<P1,P2,P3,P4,P5>{
1326 public:
1327         CBMemberTranslator5(Callee &c,const MemFunc &m):
1328                         Functor5<P1,P2,P3,P4,P5>(thunk,&c,0,&m,sizeof(MemFunc)){}
1329                         static void thunk(const FunctorBase &ftor,P1 p1,P2 p2,P3 p3,P4 p4,P5 p5)
1330                         {
1331                                 Callee *callee = (Callee *)ftor.getCallee();
1332                                 MemFunc &memFunc RHCB_CTOR_STYLE_INIT
1333                                         (*(MemFunc*)(void *)(ftor.getMemFunc()));
1334                                 (callee->*memFunc)(p1,p2,p3,p4,p5);
1335                         }
1336 };
1337 
1338 template <class P1,class P2,class P3,class P4,class P5,class Func>
1339 class CBFunctionTranslator5:public Functor5<P1,P2,P3,P4,P5>{
1340 public:
1341         CBFunctionTranslator5(Func f):
1342                         Functor5<P1,P2,P3,P4,P5>(thunk,0,(PtrToFunc)f,0,0){}
1343                         static void thunk(const FunctorBase &ftor,P1 p1,P2 p2,P3 p3,P4 p4,P5 p5)
1344                         {
1345                                 (Func(ftor.getFunc()))(p1,p2,p3,p4,p5);
1346                         }
1347 };
1348 
1349 #if !defined(RHCB_CANT_OVERLOAD_ON_CONSTNESS)
1350 template <class Callee,class RT,class CallType,class P1,class P2,class P3,class P4,class P5>
1351 inline CBMemberTranslator5<P1,P2,P3,P4,P5,Callee,
1352 RT (CallType::*)(P1,P2,P3,P4,P5)>
1353 functor( Callee &c,RT (CallType::* RHCB_CONST_REF f)(P1,P2,P3,P4,P5))
1354 {
1355         typedef RT (CallType::*MemFunc)(P1,P2,P3,P4,P5);
1356         return CBMemberTranslator5<P1,P2,P3,P4,P5,Callee,MemFunc>(c,f);
1357 }
1358 #endif
1359 
1360 template <class Callee,class RT,class CallType,class P1,class P2,class P3,class P4,class P5>
1361 inline CBMemberTranslator5<P1,P2,P3,P4,P5,const Callee,
1362 RT (CallType::*)(P1,P2,P3,P4,P5)const>
1363 functor( const Callee &c,RT (CallType::* RHCB_CONST_REF f)(P1,P2,P3,P4,P5)const)
1364 {
1365         typedef RT (CallType::*MemFunc)(P1,P2,P3,P4,P5)const;
1366         return CBMemberTranslator5<P1,P2,P3,P4,P5,const Callee,MemFunc>(c,f);
1367 }
1368 
1369 template <class RT,class P1,class P2,class P3,class P4,class P5>
1370 inline CBFunctionTranslator5<P1,P2,P3,P4,P5,RT (*)(P1,P2,P3,P4,P5)>
1371 functor( RT (*f)(P1,P2,P3,P4,P5))
1372 {
1373         return CBFunctionTranslator5<P1,P2,P3,P4,P5,RT (*)(P1,P2,P3,P4,P5)>(f);
1374 }
1375 
1376 template <class P1,class P2,class P3,class P4,class P5,class MemFunc>
1377 class CBMemberOf1stArgTranslator5:public Functor5<P1,P2,P3,P4,P5>{
1378 public:
1379         CBMemberOf1stArgTranslator5(const MemFunc &m):
1380                         Functor5<P1,P2,P3,P4,P5>(thunk,(void *)1,0,&m,sizeof(MemFunc)){}
1381                         static void thunk(const FunctorBase &ftor,P1 p1,P2 p2,P3 p3,P4 p4,P5 p5)
1382                         {
1383                                 MemFunc &memFunc RHCB_CTOR_STYLE_INIT
1384                                         (*(MemFunc*)(void *)(ftor.getMemFunc()));
1385                                 (p1.*memFunc)(p2,p3,p4,p5);
1386                         }
1387 };
1388 
1389 #if !defined(RHCB_CANT_OVERLOAD_ON_CONSTNESS)
1390 template <class P1,class P2,class P3,class P4,class P5,class RT,class CallType>
1391 inline CBMemberOf1stArgTranslator5<P1,P2,P3,P4,P5,RT (CallType::*)(P1,P2,P3,P4)>
1392 functor( RT (CallType::* RHCB_CONST_REF f)(P1,P2,P3,P4))
1393 {
1394         typedef RT (CallType::*MemFunc)(P1,P2,P3,P4);
1395         return CBMemberOf1stArgTranslator5<P1,P2,P3,P4,P5,MemFunc>(f);
1396 }
1397 #endif
1398 
1399 template <class P1,class P2,class P3,class P4,class P5,class RT,class CallType>
1400 inline CBMemberOf1stArgTranslator5<P1,P2,P3,P4,P5,
1401 RT (CallType::*)(P1,P2,P3,P4)const>
1402 functor( RT (CallType::* RHCB_CONST_REF f)(P1,P2,P3,P4)const)
1403 {
1404         typedef RT (CallType::*MemFunc)(P1,P2,P3,P4)const;
1405         return CBMemberOf1stArgTranslator5<P1,P2,P3,P4,P5,MemFunc>(f);
1406 }
1407 */
1408 
1409 ///////////////////////////////////////////////////////////////////////////////
1410 //
1411 // Inlines.
1412 //
1413 ///////////////////////////////////////////////////////////////////////////////
1414 inline bool operator==(const FunctorBase &lhs,const FunctorBase &rhs)
1415 {
1416         if (!lhs.callee)        {
1417                 if (rhs.callee) return false;
1418                 return lhs.func == rhs.func;
1419         }       else {
1420                 if (!rhs.callee) return false;
1421                 return lhs.callee == rhs.callee &&
1422                         !memcmp(lhs.memFunc,rhs.memFunc,FunctorBase::MEM_FUNC_SIZE);
1423                 }
1424 }
1425 
1426 inline bool operator!=(const FunctorBase &lhs,const FunctorBase &rhs)
1427 {
1428         return !(lhs == rhs);
1429 }
1430 
1431 inline bool operator<(const FunctorBase &lhs,const FunctorBase &rhs)
1432 {
1433         //must order across funcs and callee/memfuncs, funcs are first
1434         if(!lhs.callee)
1435                 {
1436                 if(rhs.callee)
1437                         return true;
1438                 else
1439                         return lhs.func < rhs.func;
1440                 }
1441         else
1442                 {
1443                 if(!rhs.callee)
1444                         return false;
1445                 if(lhs.callee != rhs.callee)
1446                         return lhs.callee < rhs.callee;
1447                 else
1448                         return memcmp(lhs.memFunc,rhs.memFunc,FunctorBase::MEM_FUNC_SIZE)<0;
1449                 }
1450 }
1451 
1452 /*
1453 //////////////////////////////////////////////////////////////////////////
1454 template <class FUNCTOR>
1455 class CFunctorsList
1456 {
1457 public:
1458         // Add functor to list.
1459         void Add( const FUNCTOR &f )
1460         {
1461                 m_functors.push_back( f );
1462         }
1463         // Remvoe functor from list.
1464         void Remove( const FUNCTOR &f )
1465         {
1466                 typename Container::iterator it = std::find( m_functors.begin(),m_functors.end(),f );
1467                 if (it != m_functors.end())
1468                 {
1469                         #undef erase
1470                         m_functors.erase( it );
1471                 }
1472         }
1473 
1474         //////////////////////////////////////////////////////////////////////////
1475         // Call all functors in this list.
1476         // Also several template functions for multiple parameters.
1477         //////////////////////////////////////////////////////////////////////////
1478         void Call()
1479         {
1480                 for (typename Container::iterator it = m_functors.begin(); it != m_functors.end(); ++it)
1481                 {
1482                         (*it)();
1483                 }
1484         }
1485 
1486         template <class T1>
1487         void Call( const T1 &param1 )
1488         {
1489                 for (typename Container::iterator it = m_functors.begin(); it != m_functors.end(); ++it)
1490                 {
1491                         (*it)( param1 );
1492                 }
1493         }
1494 
1495         template <class T1,class T2>
1496         void Call( const T1 &param1,const T2 &param2 )
1497         {
1498                 for (typename Container::iterator it = m_functors.begin(); it != m_functors.end(); ++it)
1499                 {
1500                         (*it)( param1,param2 );
1501                 }
1502         }
1503 
1504         template <class T1,class T2,class T3>
1505         void Call( const T1 &param1,const T2 &param2,const T3 &param3 )
1506         {
1507                 for (typename Container::iterator it = m_functors.begin(); it != m_functors.end(); ++it)
1508                 {
1509                         (*it)( param1,param2,param3 );
1510                 }
1511         }
1512 
1513 private:
1514         typedef std::list<FUNCTOR> Container;
1515         Container m_functors;
1516 };
1517 */
1518 #endif // FUNCTOR_H
1519