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 ¶m1 )
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 ¶m1,const T2 ¶m2 )
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 ¶m1,const T2 ¶m2,const T3 ¶m3 )
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