Header.h 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212
  1. #pragma once
  2. /* callback.h
  3. * This is Rich Hickey's callback library...
  4. * http://www.tutok.sk/fastgl/callback.html
  5. *
  6. * I've just renamed it to callback.h as all my header files use
  7. * h for extension.
  8. */
  9. //**************** callback.hpp **********************
  10. // Copyright 1994 Rich Hickey
  11. /* Permission to use, copy, modify, distribute and sell this software
  12. * for any purpose is hereby granted without fee,
  13. * provided that the above copyright notice appear in all copies and
  14. * that both that copyright notice and this permission notice appear
  15. * in supporting documentation. Rich Hickey makes no
  16. * representations about the suitability of this software for any
  17. * purpose. It is provided "as is" without express or implied warranty.
  18. */
  19. // 06/12/94 Rich Hickey
  20. // 3rd major revision
  21. // Now functors are concrete classes, and should be held by value
  22. // Virtual function mechanism removed
  23. // Generic makeFunctor() mechanism added for building functors
  24. // from both stand-alone functions and object/ptr-to-mem-func pairs
  25. #ifndef CALLBACK_HPP
  26. #define CALLBACK_HPP
  27. /*
  28. To use:
  29. If you wish to build a component that provides/needs a callback, simply
  30. specify and hold a CBFunctor of the type corresponding to the args
  31. you wish to pass and the return value you need. There are 10 Functors
  32. from which to choose:
  33. CBFunctor0
  34. CBFunctor1<P1>
  35. CBFunctor2<P1,P2>
  36. CBFunctor3<P1,P2,P3>
  37. CBFunctor4<P1,P2,P3,P4>
  38. CBFunctor0wRet<RT>
  39. CBFunctor1wRet<P1,RT>
  40. CBFunctor2wRet<P1,P2,RT>
  41. CBFunctor3wRet<P1,P2,P3,RT>
  42. CBFunctor4wRet<P1,P2,P3,P4,RT>
  43. These are parameterized by their args and return value if any. Each has
  44. a default ctor and an operator() with the corresponding signature.
  45. They can be treated and used just like ptr-to-functions.
  46. If you want to be a client of a component that uses callbacks, you
  47. create a CBFunctor by calling makeFunctor().
  48. There are three flavors of makeFunctor - you can create a functor from:
  49. a ptr-to-stand-alone function
  50. an object and a pointer-to-member function.
  51. a pointer-to-member function (which will be called on first arg of functor)
  52. The current iteration of this library requires you pass makeFunctor()
  53. a dummy first argument of type ptr-to-the-Functor-type-you-want-to-create.
  54. Simply cast 0 to provide this argument:
  55. makeFunctor((target-functor*)0,ptr-to-function)
  56. makeFunctor((target-functor*)0,reference-to-object,ptr-to-member-function)
  57. makeFunctor((target-functor*)0,ptr-to-member-function)
  58. Future versions will drop this requirement once member templates are
  59. available.
  60. The functor system is 100% type safe. It is also type flexible. You can
  61. build a functor out of a function that is 'type compatible' with the
  62. target functor - it need not have an exactly matching signature. By
  63. type compatible I mean a function with the same number of arguments, of
  64. types reachable from the functor's argument types by implicit conversion.
  65. The return type of the function must be implicitly convertible to the
  66. return type of the functor. A functor with no return can be built from a
  67. function with a return - the return value is simply ignored.
  68. (See ethel example below)
  69. All the correct virtual function behavior is preserved. (see ricky
  70. example below).
  71. If you somehow try to create something in violation
  72. of the type system you will get a compile-time or template-instantiation-
  73. time error.
  74. The CBFunctor base class and translator
  75. classes are artifacts of this implementation. You should not write
  76. code that relies upon their existence. Nor should you rely on the return
  77. value of makeFunctor being anything in particular.
  78. All that is guaranteed is that the Functor classes have a default ctor,
  79. an operator() with the requested argument types and return type, an
  80. operator that will allow it to be evaluated in a conditional (with
  81. 'true' meaning the functor is set, 'false' meaning it is not), and that
  82. Functors can be constructed from the result of makeFunctor(), given
  83. you've passed something compatible to makeFunctor().
  84. /////////////////////// BEGIN Example 1 //////////////////////////
  85. #include <iostream.h>
  86. #include "callback.hpp"
  87. //do5Times() is a function that takes a functor and invokes it 5 times
  88. void do5Times(const CBFunctor1<int> &doIt)
  89. {
  90. for(int i=0;i<5;i++)
  91. doIt(i);
  92. }
  93. //Here are some standalone functions
  94. void fred(int i){cout << "fred: " << i<<endl;}
  95. int ethel(long l){cout << "ethel: " << l<<endl;return l;}
  96. //Here is a class with a virtual function, and a derived class
  97. class B{
  98. public:
  99. virtual void ricky(int i)
  100. {cout << "B::ricky: " << i<<endl;}
  101. };
  102. class D:public B{
  103. public:
  104. void ricky(int i)
  105. {cout << "D::ricky: " << i<<endl;}
  106. };
  107. void main()
  108. {
  109. //create a typedef of the functor type to simplify dummy argument
  110. typedef CBFunctor1<int> *FtorType;
  111. CBFunctor1<int> ftor; //a functor variable
  112. //make a functor from ptr-to-function
  113. ftor = makeFunctor((FtorType)0,fred);
  114. do5Times(ftor);
  115. //note ethel is not an exact match - ok, is compatible
  116. ftor = makeFunctor((FtorType)0,ethel);
  117. do5Times(ftor);
  118. //create a D object to be a callback target
  119. D myD;
  120. //make functor from object and ptr-to-member-func
  121. ftor = makeFunctor((FtorType)0,myD,&B::ricky);
  122. do5Times(ftor);
  123. }
  124. /////////////////////// END of example 1 //////////////////////////
  125. /////////////////////// BEGIN Example 2 //////////////////////////
  126. #include <iostream.h>
  127. #include "callback.hpp"
  128. //Button is a component that provides a functor-based
  129. //callback mechanism, so you can wire it up to whatever you wish
  130. class Button{
  131. public:
  132. //ctor takes a functor and stores it away in a member
  133. Button(const CBFunctor0 &uponClickDoThis):notify(uponClickDoThis)
  134. {}
  135. void click()
  136. {
  137. //invoke the functor, thus calling back client
  138. notify();
  139. }
  140. private:
  141. //note this is a data member with a verb for a name - matches its
  142. //function-like usage
  143. CBFunctor0 notify;
  144. };
  145. class CDPlayer{
  146. public:
  147. void play()
  148. {cout << "Playing"<<endl;}
  149. void stop()
  150. {cout << "Stopped"<<endl;}
  151. };
  152. void main()
  153. {
  154. CDPlayer myCD;
  155. Button playButton(makeFunctor((CBFunctor0*)0,myCD,&CDPlayer::play));
  156. Button stopButton(makeFunctor((CBFunctor0*)0,myCD,&CDPlayer::stop));
  157. playButton.click(); //calls myCD.play()
  158. stopButton.click(); //calls myCD.stop()
  159. }
  160. /////////////////////// END of example 2 //////////////////////////
  161. */
  162. //******************************************************************
  163. ///////////////////////////////////////////////////////////////////*
  164. //WARNING - no need to read past this point, lest confusion ensue. *
  165. //Only the curious need explore further - but remember *
  166. //about that cat! *
  167. ///////////////////////////////////////////////////////////////////*
  168. //******************************************************************
  169. //////////////////////////////
  170. // COMPILER BUG WORKAROUNDS:
  171. // As of version 4.02 Borland has a code generation bug
  172. // returning the result of a call via a ptr-to-function in a template
  173. #define BC4_RET_BUG(x) x
  174. //////////////////////////////
  175. #include <string.h> //for memcpy
  176. #include <stddef.h> //for size_t
  177. //typeless representation of a function and optional object
  178. class CBFunctorBase {
  179. public:
  180. typedef void (CBFunctorBase::* _MemFunc)();
  181. typedef void (*_Func)();
  182. CBFunctorBase() :callee(0), func(0) {}
  183. CBFunctorBase(const void* c, const void* f, size_t sz)
  184. {
  185. if (c) //must be callee/memfunc
  186. {
  187. callee = (void*)c;
  188. memcpy(memFunc, f, sz);
  189. }
  190. else //must be ptr-to-func
  191. {
  192. func = f;
  193. }
  194. }
  195. //for evaluation in conditionals
  196. operator int()const { return func || callee; }
  197. class DummyInit {
  198. };
  199. ////////////////////////////////////////////////////////////////
  200. // Note: this code depends on all ptr-to-mem-funcs being same size
  201. // If that is not the case then make memFunc as large as largest
  202. ////////////////////////////////////////////////////////////////
  203. union {
  204. const void* func;
  205. char memFunc[sizeof(_MemFunc)];
  206. };
  207. void* callee;
  208. };
  209. /************************* no arg - no return *******************/
  210. class CBFunctor0 :protected CBFunctorBase {
  211. public:
  212. CBFunctor0(DummyInit* = 0) {}
  213. void operator()()const
  214. {
  215. thunk(*this);
  216. }
  217. CBFunctorBase::operator int;
  218. protected:
  219. typedef void (*Thunk)(const CBFunctorBase&);
  220. CBFunctor0(Thunk t, const void* c, const void* f, size_t sz) :
  221. CBFunctorBase(c, f, sz), thunk(t) {}
  222. private:
  223. Thunk thunk;
  224. };
  225. template <class Callee, class MemFunc>
  226. class CBMemberTranslator0 :public CBFunctor0 {
  227. public:
  228. CBMemberTranslator0(Callee& c, const MemFunc& m) :
  229. CBFunctor0(thunk, &c, &m, sizeof(MemFunc)) {}
  230. static void thunk(const CBFunctorBase& ftor)
  231. {
  232. Callee* callee = (Callee*)ftor.callee;
  233. MemFunc& memFunc(*(MemFunc*)(void*)(ftor.memFunc));
  234. (callee->*memFunc)();
  235. }
  236. };
  237. template <class Func>
  238. class CBFunctionTranslator0 :public CBFunctor0 {
  239. public:
  240. CBFunctionTranslator0(Func f) :CBFunctor0(thunk, 0, f, 0) {}
  241. static void thunk(const CBFunctorBase& ftor)
  242. {
  243. (Func(ftor.func))();
  244. }
  245. };
  246. template <class Callee, class TRT, class CallType>
  247. inline CBMemberTranslator0<Callee, TRT(CallType::*)()>
  248. makeFunctor(CBFunctor0*, Callee& c, TRT(CallType::* const& f)())
  249. {
  250. typedef TRT(CallType::* MemFunc)();
  251. return CBMemberTranslator0<Callee, MemFunc>(c, f);
  252. }
  253. template <class Callee, class TRT, class CallType>
  254. inline CBMemberTranslator0<const Callee, TRT(CallType::*)()const>
  255. makeFunctor(CBFunctor0*, const Callee& c, TRT(CallType::* const& f)()const)
  256. {
  257. typedef TRT(CallType::* MemFunc)()const;
  258. return CBMemberTranslator0<const Callee, MemFunc>(c, f);
  259. }
  260. template <class TRT>
  261. inline CBFunctionTranslator0<TRT(*)()>
  262. makeFunctor(CBFunctor0*, TRT(*f)())
  263. {
  264. return CBFunctionTranslator0<TRT(*)()>(f);
  265. }
  266. /************************* no arg - with return *******************/
  267. template <class RT>
  268. class CBFunctor0wRet :protected CBFunctorBase {
  269. public:
  270. CBFunctor0wRet(DummyInit* = 0) {}
  271. RT operator()()const
  272. {
  273. return BC4_RET_BUG(thunk(*this));
  274. }
  275. CBFunctorBase::operator int;
  276. protected:
  277. typedef RT(*Thunk)(const CBFunctorBase&);
  278. CBFunctor0wRet(Thunk t, const void* c, const void* f, size_t sz) :
  279. CBFunctorBase(c, f, sz), thunk(t) {}
  280. private:
  281. Thunk thunk;
  282. };
  283. template <class RT, class Callee, class MemFunc>
  284. class CBMemberTranslator0wRet :public CBFunctor0wRet<RT> {
  285. public:
  286. CBMemberTranslator0wRet(Callee& c, const MemFunc& m) :
  287. CBFunctor0wRet<RT>(thunk, &c, &m, sizeof(MemFunc)) {}
  288. static RT thunk(const CBFunctorBase& ftor)
  289. {
  290. Callee* callee = (Callee*)ftor.callee;
  291. MemFunc& memFunc(*(MemFunc*)(void*)(ftor.memFunc));
  292. return BC4_RET_BUG((callee->*memFunc)());
  293. }
  294. };
  295. template <class RT, class Func>
  296. class CBFunctionTranslator0wRet :public CBFunctor0wRet<RT> {
  297. public:
  298. CBFunctionTranslator0wRet(Func f) :CBFunctor0wRet<RT>(thunk, 0, f, 0) {}
  299. static RT thunk(const CBFunctorBase& ftor)
  300. {
  301. return (Func(ftor.func))();
  302. }
  303. };
  304. template <class RT, class Callee, class TRT, class CallType>
  305. inline CBMemberTranslator0wRet<RT, Callee, TRT(CallType::*)()>
  306. makeFunctor(CBFunctor0wRet<RT>*, Callee& c, TRT(CallType::* const& f)())
  307. {
  308. typedef TRT(CallType::* MemFunc)();
  309. return CBMemberTranslator0wRet<RT, Callee, MemFunc>(c, f);
  310. }
  311. template <class RT, class Callee, class TRT, class CallType>
  312. inline CBMemberTranslator0wRet<RT, const Callee, TRT(CallType::*)()const>
  313. makeFunctor(CBFunctor0wRet<RT>*, const Callee& c, TRT(CallType::* const& f)()const)
  314. {
  315. typedef TRT(CallType::* MemFunc)()const;
  316. return CBMemberTranslator0wRet<RT, const Callee, MemFunc>(c, f);
  317. }
  318. template <class RT, class TRT>
  319. inline CBFunctionTranslator0wRet<RT, TRT(*)()>
  320. makeFunctor(CBFunctor0wRet<RT>*, TRT(*f)())
  321. {
  322. return CBFunctionTranslator0wRet<RT, TRT(*)()>(f);
  323. }
  324. /************************* one arg - no return *******************/
  325. template <class P1>
  326. class CBFunctor1 :protected CBFunctorBase {
  327. public:
  328. CBFunctor1(DummyInit* = 0) {}
  329. void operator()(P1 p1)const
  330. {
  331. thunk(*this, p1);
  332. }
  333. CBFunctorBase::operator int;
  334. //for STL
  335. typedef P1 argument_type;
  336. typedef void result_type;
  337. protected:
  338. typedef void (*Thunk)(const CBFunctorBase&, P1);
  339. CBFunctor1(Thunk t, const void* c, const void* f, size_t sz) :
  340. CBFunctorBase(c, f, sz), thunk(t) {}
  341. private:
  342. Thunk thunk;
  343. };
  344. template <class P1, class Callee, class MemFunc>
  345. class CBMemberTranslator1 :public CBFunctor1<P1> {
  346. public:
  347. CBMemberTranslator1(Callee& c, const MemFunc& m) :
  348. CBFunctor1<P1>(thunk, &c, &m, sizeof(MemFunc)) {}
  349. static void thunk(const CBFunctorBase& ftor, P1 p1)
  350. {
  351. Callee* callee = (Callee*)ftor.callee;
  352. MemFunc& memFunc(*(MemFunc*)(void*)(ftor.memFunc));
  353. (callee->*memFunc)(p1);
  354. }
  355. };
  356. template <class P1, class Func>
  357. class CBFunctionTranslator1 :public CBFunctor1<P1> {
  358. public:
  359. CBFunctionTranslator1(Func f) :CBFunctor1<P1>(thunk, 0, f, 0) {}
  360. static void thunk(const CBFunctorBase& ftor, P1 p1)
  361. {
  362. (Func(ftor.func))(p1);
  363. }
  364. };
  365. template <class P1, class Callee, class TRT, class CallType, class TP1>
  366. inline CBMemberTranslator1<P1, Callee, TRT(CallType::*)(TP1)>
  367. makeFunctor(CBFunctor1<P1>*, Callee& c, TRT(CallType::* const& f)(TP1))
  368. {
  369. typedef TRT(CallType::* MemFunc)(TP1);
  370. return CBMemberTranslator1<P1, Callee, MemFunc>(c, f);
  371. }
  372. template <class P1, class Callee, class TRT, class CallType, class TP1>
  373. inline CBMemberTranslator1<P1, const Callee, TRT(CallType::*)(TP1)const>
  374. makeFunctor(CBFunctor1<P1>*, const Callee& c, TRT(CallType::* const& f)(TP1)const)
  375. {
  376. typedef TRT(CallType::* MemFunc)(TP1)const;
  377. return CBMemberTranslator1<P1, const Callee, MemFunc>(c, f);
  378. }
  379. template <class P1, class TRT, class TP1>
  380. inline CBFunctionTranslator1<P1, TRT(*)(TP1)>
  381. makeFunctor(CBFunctor1<P1>*, TRT(*f)(TP1))
  382. {
  383. return CBFunctionTranslator1<P1, TRT(*)(TP1)>(f);
  384. }
  385. template <class P1, class MemFunc>
  386. class CBMemberOf1stArgTranslator1 :public CBFunctor1<P1> {
  387. public:
  388. CBMemberOf1stArgTranslator1(const MemFunc& m) :
  389. CBFunctor1<P1>(thunk, (void*)1, &m, sizeof(MemFunc)) {}
  390. static void thunk(const CBFunctorBase& ftor, P1 p1)
  391. {
  392. MemFunc& memFunc(*(MemFunc*)(void*)(ftor.memFunc));
  393. (p1.*memFunc)();
  394. }
  395. };
  396. template <class P1, class TRT, class CallType>
  397. inline CBMemberOf1stArgTranslator1<P1, TRT(CallType::*)()>
  398. makeFunctor(CBFunctor1<P1>*, TRT(CallType::* const& f)())
  399. {
  400. typedef TRT(CallType::* MemFunc)();
  401. return CBMemberOf1stArgTranslator1<P1, MemFunc>(f);
  402. }
  403. template <class P1, class TRT, class CallType>
  404. inline CBMemberOf1stArgTranslator1<P1, TRT(CallType::*)()const>
  405. makeFunctor(CBFunctor1<P1>*, TRT(CallType::* const& f)()const)
  406. {
  407. typedef TRT(CallType::* MemFunc)()const;
  408. return CBMemberOf1stArgTranslator1<P1, MemFunc>(f);
  409. }
  410. /************************* one arg - with return *******************/
  411. template <class P1, class RT>
  412. class CBFunctor1wRet :protected CBFunctorBase {
  413. public:
  414. CBFunctor1wRet(DummyInit* = 0) {}
  415. RT operator()(P1 p1)const
  416. {
  417. return BC4_RET_BUG(thunk(*this, p1));
  418. }
  419. CBFunctorBase::operator int;
  420. //for STL
  421. typedef P1 argument_type;
  422. typedef RT result_type;
  423. protected:
  424. typedef RT(*Thunk)(const CBFunctorBase&, P1);
  425. CBFunctor1wRet(Thunk t, const void* c, const void* f, size_t sz) :
  426. CBFunctorBase(c, f, sz), thunk(t) {}
  427. private:
  428. Thunk thunk;
  429. };
  430. template <class P1, class RT, class Callee, class MemFunc>
  431. class CBMemberTranslator1wRet :public CBFunctor1wRet<P1, RT> {
  432. public:
  433. CBMemberTranslator1wRet(Callee& c, const MemFunc& m) :
  434. CBFunctor1wRet<P1, RT>(thunk, &c, &m, sizeof(MemFunc)) {}
  435. static RT thunk(const CBFunctorBase& ftor, P1 p1)
  436. {
  437. Callee* callee = (Callee*)ftor.callee;
  438. MemFunc& memFunc(*(MemFunc*)(void*)(ftor.memFunc));
  439. return BC4_RET_BUG((callee->*memFunc)(p1));
  440. }
  441. };
  442. template <class P1, class RT, class Func>
  443. class CBFunctionTranslator1wRet :public CBFunctor1wRet<P1, RT> {
  444. public:
  445. // CBFunctionTranslator1wRet(Func f):CBFunctor1wRet<P1,RT>(thunk,0,f,0){}
  446. // EBR
  447. CBFunctionTranslator1wRet(Func f) :CBFunctor1wRet<P1, RT>(thunk, 0, (void*)f, 0) {}
  448. static RT thunk(const CBFunctorBase& ftor, P1 p1)
  449. {
  450. return (Func(ftor.func))(p1);
  451. }
  452. };
  453. template <class P1, class RT,
  454. class Callee, class TRT, class CallType, class TP1>
  455. inline CBMemberTranslator1wRet<P1, RT, Callee, TRT(CallType::*)(TP1)>
  456. makeFunctor(CBFunctor1wRet<P1, RT>*, Callee& c, TRT(CallType::* const& f)(TP1))
  457. {
  458. typedef TRT(CallType::* MemFunc)(TP1);
  459. return CBMemberTranslator1wRet<P1, RT, Callee, MemFunc>(c, f);
  460. }
  461. template <class P1, class RT,
  462. class Callee, class TRT, class CallType, class TP1>
  463. inline CBMemberTranslator1wRet<P1, RT,
  464. const Callee, TRT(CallType::*)(TP1)const>
  465. makeFunctor(CBFunctor1wRet<P1, RT>*,
  466. const Callee& c, TRT(CallType::* const& f)(TP1)const)
  467. {
  468. typedef TRT(CallType::* MemFunc)(TP1)const;
  469. return CBMemberTranslator1wRet<P1, RT, const Callee, MemFunc>(c, f);
  470. }
  471. template <class P1, class RT, class TRT, class TP1>
  472. inline CBFunctionTranslator1wRet<P1, RT, TRT(*)(TP1)>
  473. makeFunctor(CBFunctor1wRet<P1, RT>*, TRT(*f)(TP1))
  474. {
  475. return CBFunctionTranslator1wRet<P1, RT, TRT(*)(TP1)>(f);
  476. }
  477. template <class P1, class RT, class MemFunc>
  478. class CBMemberOf1stArgTranslator1wRet :public CBFunctor1wRet<P1, RT> {
  479. public:
  480. CBMemberOf1stArgTranslator1wRet(const MemFunc& m) :
  481. CBFunctor1wRet<P1, RT>(thunk, (void*)1, &m, sizeof(MemFunc)) {}
  482. static RT thunk(const CBFunctorBase& ftor, P1 p1)
  483. {
  484. MemFunc& memFunc(*(MemFunc*)(void*)(ftor.memFunc));
  485. return BC4_RET_BUG((p1.*memFunc)());
  486. }
  487. };
  488. template <class P1, class RT, class TRT, class CallType>
  489. inline CBMemberOf1stArgTranslator1wRet<P1, RT, TRT(CallType::*)()>
  490. makeFunctor(CBFunctor1wRet<P1, RT>*, TRT(CallType::* const& f)())
  491. {
  492. typedef TRT(CallType::* MemFunc)();
  493. return CBMemberOf1stArgTranslator1wRet<P1, RT, MemFunc>(f);
  494. }
  495. template <class P1, class RT, class TRT, class CallType>
  496. inline CBMemberOf1stArgTranslator1wRet<P1, RT, TRT(CallType::*)()const>
  497. makeFunctor(CBFunctor1wRet<P1, RT>*, TRT(CallType::* const& f)()const)
  498. {
  499. typedef TRT(CallType::* MemFunc)()const;
  500. return CBMemberOf1stArgTranslator1wRet<P1, RT, MemFunc>(f);
  501. }
  502. /************************* two args - no return *******************/
  503. template <class P1, class P2>
  504. class CBFunctor2 :protected CBFunctorBase {
  505. public:
  506. CBFunctor2(DummyInit* = 0) {}
  507. void operator()(P1 p1, P2 p2)const
  508. {
  509. thunk(*this, p1, p2);
  510. }
  511. CBFunctorBase::operator int;
  512. //for STL
  513. typedef P1 first_argument_type;
  514. typedef P2 second_argument_type;
  515. typedef void result_type;
  516. protected:
  517. typedef void (*Thunk)(const CBFunctorBase&, P1, P2);
  518. CBFunctor2(Thunk t, const void* c, const void* f, size_t sz) :
  519. CBFunctorBase(c, f, sz), thunk(t) {}
  520. private:
  521. Thunk thunk;
  522. };
  523. template <class P1, class P2, class Callee, class MemFunc>
  524. class CBMemberTranslator2 :public CBFunctor2<P1, P2> {
  525. public:
  526. CBMemberTranslator2(Callee& c, const MemFunc& m) :
  527. CBFunctor2<P1, P2>(thunk, &c, &m, sizeof(MemFunc)) {}
  528. static void thunk(const CBFunctorBase& ftor, P1 p1, P2 p2)
  529. {
  530. Callee* callee = (Callee*)ftor.callee;
  531. MemFunc& memFunc(*(MemFunc*)(void*)(ftor.memFunc));
  532. (callee->*memFunc)(p1, p2);
  533. }
  534. };
  535. template <class P1, class P2, class Func>
  536. class CBFunctionTranslator2 :public CBFunctor2<P1, P2> {
  537. public:
  538. CBFunctionTranslator2(Func f) :CBFunctor2<P1, P2>(thunk, 0, f, 0) {}
  539. static void thunk(const CBFunctorBase& ftor, P1 p1, P2 p2)
  540. {
  541. (Func(ftor.func))(p1, p2);
  542. }
  543. };
  544. template <class P1, class P2, class Callee,
  545. class TRT, class CallType, class TP1, class TP2>
  546. inline CBMemberTranslator2<P1, P2, Callee, TRT(CallType::*)(TP1, TP2)>
  547. makeFunctor(CBFunctor2<P1, P2>*, Callee& c, TRT(CallType::* const& f)(TP1, TP2))
  548. {
  549. typedef TRT(CallType::* MemFunc)(TP1, TP2);
  550. return CBMemberTranslator2<P1, P2, Callee, MemFunc>(c, f);
  551. }
  552. template <class P1, class P2, class Callee,
  553. class TRT, class CallType, class TP1, class TP2>
  554. inline CBMemberTranslator2<P1, P2, const Callee,
  555. TRT(CallType::*)(TP1, TP2)const>
  556. makeFunctor(CBFunctor2<P1, P2>*, const Callee& c,
  557. TRT(CallType::* const& f)(TP1, TP2)const)
  558. {
  559. typedef TRT(CallType::* MemFunc)(TP1, TP2)const;
  560. return CBMemberTranslator2<P1, P2, const Callee, MemFunc>(c, f);
  561. }
  562. template <class P1, class P2, class TRT, class TP1, class TP2>
  563. inline CBFunctionTranslator2<P1, P2, TRT(*)(TP1, TP2)>
  564. makeFunctor(CBFunctor2<P1, P2>*, TRT(*f)(TP1, TP2))
  565. {
  566. return CBFunctionTranslator2<P1, P2, TRT(*)(TP1, TP2)>(f);
  567. }
  568. template <class P1, class P2, class MemFunc>
  569. class CBMemberOf1stArgTranslator2 :public CBFunctor2<P1, P2> {
  570. public:
  571. CBMemberOf1stArgTranslator2(const MemFunc& m) :
  572. CBFunctor2<P1, P2>(thunk, (void*)1, &m, sizeof(MemFunc)) {}
  573. static void thunk(const CBFunctorBase& ftor, P1 p1, P2 p2)
  574. {
  575. MemFunc& memFunc(*(MemFunc*)(void*)(ftor.memFunc));
  576. (p1.*memFunc)(p2);
  577. }
  578. };
  579. template <class P1, class P2, class TRT, class CallType, class TP1>
  580. inline CBMemberOf1stArgTranslator2<P1, P2, TRT(CallType::*)(TP1)>
  581. makeFunctor(CBFunctor2<P1, P2>*, TRT(CallType::* const& f)(TP1))
  582. {
  583. typedef TRT(CallType::* MemFunc)(TP1);
  584. return CBMemberOf1stArgTranslator2<P1, P2, MemFunc>(f);
  585. }
  586. template <class P1, class P2, class TRT, class CallType, class TP1>
  587. inline CBMemberOf1stArgTranslator2<P1, P2, TRT(CallType::*)(TP1)const>
  588. makeFunctor(CBFunctor2<P1, P2>*, TRT(CallType::* const& f)(TP1)const)
  589. {
  590. typedef TRT(CallType::* MemFunc)(TP1)const;
  591. return CBMemberOf1stArgTranslator2<P1, P2, MemFunc>(f);
  592. }
  593. /************************* two args - with return *******************/
  594. template <class P1, class P2, class RT>
  595. class CBFunctor2wRet :protected CBFunctorBase {
  596. public:
  597. CBFunctor2wRet(DummyInit* = 0) {}
  598. RT operator()(P1 p1, P2 p2)const
  599. {
  600. return BC4_RET_BUG(thunk(*this, p1, p2));
  601. }
  602. CBFunctorBase::operator int;
  603. //for STL
  604. typedef P1 first_argument_type;
  605. typedef P2 second_argument_type;
  606. typedef RT result_type;
  607. protected:
  608. typedef RT(*Thunk)(const CBFunctorBase&, P1, P2);
  609. CBFunctor2wRet(Thunk t, const void* c, const void* f, size_t sz) :
  610. CBFunctorBase(c, f, sz), thunk(t) {}
  611. private:
  612. Thunk thunk;
  613. };
  614. template <class P1, class P2, class RT, class Callee, class MemFunc>
  615. class CBMemberTranslator2wRet :public CBFunctor2wRet<P1, P2, RT> {
  616. public:
  617. CBMemberTranslator2wRet(Callee& c, const MemFunc& m) :
  618. CBFunctor2wRet<P1, P2, RT>(thunk, &c, &m, sizeof(MemFunc)) {}
  619. static RT thunk(const CBFunctorBase& ftor, P1 p1, P2 p2)
  620. {
  621. Callee* callee = (Callee*)ftor.callee;
  622. MemFunc& memFunc(*(MemFunc*)(void*)(ftor.memFunc));
  623. return BC4_RET_BUG((callee->*memFunc)(p1, p2));
  624. }
  625. };
  626. template <class P1, class P2, class RT, class Func>
  627. class CBFunctionTranslator2wRet :public CBFunctor2wRet<P1, P2, RT> {
  628. public:
  629. // CBFunctionTranslator2wRet(Func f):CBFunctor2wRet<P1,P2,RT>(thunk,0,f,0){}
  630. // EBR
  631. CBFunctionTranslator2wRet(Func f) :CBFunctor2wRet<P1, P2, RT>(thunk, 0, (void*)f, 0) {}
  632. static RT thunk(const CBFunctorBase& ftor, P1 p1, P2 p2)
  633. {
  634. return (Func(ftor.func))(p1, p2);
  635. }
  636. };
  637. template <class P1, class P2, class RT, class Callee,
  638. class TRT, class CallType, class TP1, class TP2>
  639. inline CBMemberTranslator2wRet<P1, P2, RT, Callee,
  640. TRT(CallType::*)(TP1, TP2)>
  641. makeFunctor(CBFunctor2wRet<P1, P2, RT>*, Callee& c, TRT(CallType::* const& f)(TP1, TP2))
  642. {
  643. typedef TRT(CallType::* MemFunc)(TP1, TP2);
  644. return CBMemberTranslator2wRet<P1, P2, RT, Callee, MemFunc>(c, f);
  645. }
  646. template <class P1, class P2, class RT, class Callee,
  647. class TRT, class CallType, class TP1, class TP2>
  648. inline CBMemberTranslator2wRet<P1, P2, RT, const Callee,
  649. TRT(CallType::*)(TP1, TP2)const>
  650. makeFunctor(CBFunctor2wRet<P1, P2, RT>*, const Callee& c,
  651. TRT(CallType::* const& f)(TP1, TP2)const)
  652. {
  653. typedef TRT(CallType::* MemFunc)(TP1, TP2)const;
  654. return CBMemberTranslator2wRet<P1, P2, RT, const Callee, MemFunc>(c, f);
  655. }
  656. template <class P1, class P2, class RT, class TRT, class TP1, class TP2>
  657. inline CBFunctionTranslator2wRet<P1, P2, RT, TRT(*)(TP1, TP2)>
  658. makeFunctor(CBFunctor2wRet<P1, P2, RT>*, TRT(*f)(TP1, TP2))
  659. {
  660. return CBFunctionTranslator2wRet<P1, P2, RT, TRT(*)(TP1, TP2)>(f);
  661. }
  662. template <class P1, class P2, class RT, class MemFunc>
  663. class CBMemberOf1stArgTranslator2wRet :public CBFunctor2wRet<P1, P2, RT> {
  664. public:
  665. CBMemberOf1stArgTranslator2wRet(const MemFunc& m) :
  666. CBFunctor2wRet<P1, P2, RT>(thunk, (void*)1, &m, sizeof(MemFunc)) {}
  667. static RT thunk(const CBFunctorBase& ftor, P1 p1, P2 p2)
  668. {
  669. MemFunc& memFunc(*(MemFunc*)(void*)(ftor.memFunc));
  670. return BC4_RET_BUG((p1.*memFunc)(p2));
  671. }
  672. };
  673. template <class P1, class P2, class RT, class TRT, class CallType, class TP1>
  674. inline CBMemberOf1stArgTranslator2wRet<P1, P2, RT, TRT(CallType::*)(TP1)>
  675. makeFunctor(CBFunctor2wRet<P1, P2, RT>*, TRT(CallType::* const& f)(TP1))
  676. {
  677. typedef TRT(CallType::* MemFunc)(TP1);
  678. return CBMemberOf1stArgTranslator2wRet<P1, P2, RT, MemFunc>(f);
  679. }
  680. template <class P1, class P2, class RT, class TRT, class CallType, class TP1>
  681. inline CBMemberOf1stArgTranslator2wRet<P1, P2, RT, TRT(CallType::*)(TP1)const>
  682. makeFunctor(CBFunctor2wRet<P1, P2, RT>*, TRT(CallType::* const& f)(TP1)const)
  683. {
  684. typedef TRT(CallType::* MemFunc)(TP1)const;
  685. return CBMemberOf1stArgTranslator2wRet<P1, P2, RT, MemFunc>(f);
  686. }
  687. /************************* three args - no return *******************/
  688. template <class P1, class P2, class P3>
  689. class CBFunctor3 :protected CBFunctorBase {
  690. public:
  691. CBFunctor3(DummyInit* = 0) {}
  692. void operator()(P1 p1, P2 p2, P3 p3)const
  693. {
  694. thunk(*this, p1, p2, p3);
  695. }
  696. CBFunctorBase::operator int;
  697. protected:
  698. typedef void (*Thunk)(const CBFunctorBase&, P1, P2, P3);
  699. CBFunctor3(Thunk t, const void* c, const void* f, size_t sz) :
  700. CBFunctorBase(c, f, sz), thunk(t) {}
  701. private:
  702. Thunk thunk;
  703. };
  704. template <class P1, class P2, class P3, class Callee, class MemFunc>
  705. class CBMemberTranslator3 :public CBFunctor3<P1, P2, P3> {
  706. public:
  707. CBMemberTranslator3(Callee& c, const MemFunc& m) :
  708. CBFunctor3<P1, P2, P3>(thunk, &c, &m, sizeof(MemFunc)) {}
  709. static void thunk(const CBFunctorBase& ftor, P1 p1, P2 p2, P3 p3)
  710. {
  711. Callee* callee = (Callee*)ftor.callee;
  712. MemFunc& memFunc(*(MemFunc*)(void*)(ftor.memFunc));
  713. (callee->*memFunc)(p1, p2, p3);
  714. }
  715. };
  716. template <class P1, class P2, class P3, class Func>
  717. class CBFunctionTranslator3 :public CBFunctor3<P1, P2, P3> {
  718. public:
  719. CBFunctionTranslator3(Func f) :CBFunctor3<P1, P2, P3>(thunk, 0, f, 0) {}
  720. static void thunk(const CBFunctorBase& ftor, P1 p1, P2 p2, P3 p3)
  721. {
  722. (Func(ftor.func))(p1, p2, p3);
  723. }
  724. };
  725. template <class P1, class P2, class P3, class Callee,
  726. class TRT, class CallType, class TP1, class TP2, class TP3>
  727. inline CBMemberTranslator3<P1, P2, P3, Callee,
  728. TRT(CallType::*)(TP1, TP2, TP3)>
  729. makeFunctor(CBFunctor3<P1, P2, P3>*, Callee& c,
  730. TRT(CallType::* const& f)(TP1, TP2, TP3))
  731. {
  732. typedef TRT(CallType::* MemFunc)(TP1, TP2, TP3);
  733. return CBMemberTranslator3<P1, P2, P3, Callee, MemFunc>(c, f);
  734. }
  735. template <class P1, class P2, class P3, class Callee,
  736. class TRT, class CallType, class TP1, class TP2, class TP3>
  737. inline CBMemberTranslator3<P1, P2, P3, const Callee,
  738. TRT(CallType::*)(TP1, TP2, TP3)const>
  739. makeFunctor(CBFunctor3<P1, P2, P3>*, const Callee& c,
  740. TRT(CallType::* const& f)(TP1, TP2, TP3)const)
  741. {
  742. typedef TRT(CallType::* MemFunc)(TP1, TP2, TP3)const;
  743. return CBMemberTranslator3<P1, P2, P3, const Callee, MemFunc>(c, f);
  744. }
  745. template <class P1, class P2, class P3,
  746. class TRT, class TP1, class TP2, class TP3>
  747. inline CBFunctionTranslator3<P1, P2, P3, TRT(*)(TP1, TP2, TP3)>
  748. makeFunctor(CBFunctor3<P1, P2, P3>*, TRT(*f)(TP1, TP2, TP3))
  749. {
  750. return CBFunctionTranslator3<P1, P2, P3, TRT(*)(TP1, TP2, TP3)>(f);
  751. }
  752. template <class P1, class P2, class P3, class MemFunc>
  753. class CBMemberOf1stArgTranslator3 :public CBFunctor3<P1, P2, P3> {
  754. public:
  755. CBMemberOf1stArgTranslator3(const MemFunc& m) :
  756. CBFunctor3<P1, P2, P3>(thunk, (void*)1, &m, sizeof(MemFunc)) {}
  757. static void thunk(const CBFunctorBase& ftor, P1 p1, P2 p2, P3 p3)
  758. {
  759. MemFunc& memFunc(*(MemFunc*)(void*)(ftor.memFunc));
  760. (p1.*memFunc)(p2, p3);
  761. }
  762. };
  763. template <class P1, class P2, class P3, class TRT, class CallType,
  764. class TP1, class TP2>
  765. inline CBMemberOf1stArgTranslator3<P1, P2, P3, TRT(CallType::*)(TP1, TP2)>
  766. makeFunctor(CBFunctor3<P1, P2, P3>*, TRT(CallType::* const& f)(TP1, TP2))
  767. {
  768. typedef TRT(CallType::* MemFunc)(TP1, TP2);
  769. return CBMemberOf1stArgTranslator3<P1, P2, P3, MemFunc>(f);
  770. }
  771. template <class P1, class P2, class P3, class TRT, class CallType,
  772. class TP1, class TP2>
  773. inline CBMemberOf1stArgTranslator3<P1, P2, P3, TRT(CallType::*)(TP1, TP2)const>
  774. makeFunctor(CBFunctor3<P1, P2, P3>*, TRT(CallType::* const& f)(TP1, TP2)const)
  775. {
  776. typedef TRT(CallType::* MemFunc)(TP1, TP2)const;
  777. return CBMemberOf1stArgTranslator3<P1, P2, P3, MemFunc>(f);
  778. }
  779. /************************* three args - with return *******************/
  780. template <class P1, class P2, class P3, class RT>
  781. class CBFunctor3wRet :protected CBFunctorBase {
  782. public:
  783. CBFunctor3wRet(DummyInit* = 0) {}
  784. RT operator()(P1 p1, P2 p2, P3 p3)const
  785. {
  786. return BC4_RET_BUG(thunk(*this, p1, p2, p3));
  787. }
  788. CBFunctorBase::operator int;
  789. protected:
  790. typedef RT(*Thunk)(const CBFunctorBase&, P1, P2, P3);
  791. CBFunctor3wRet(Thunk t, const void* c, const void* f, size_t sz) :
  792. CBFunctorBase(c, f, sz), thunk(t) {}
  793. private:
  794. Thunk thunk;
  795. };
  796. template <class P1, class P2, class P3,
  797. class RT, class Callee, class MemFunc>
  798. class CBMemberTranslator3wRet :public CBFunctor3wRet<P1, P2, P3, RT> {
  799. public:
  800. CBMemberTranslator3wRet(Callee& c, const MemFunc& m) :
  801. CBFunctor3wRet<P1, P2, P3, RT>(thunk, &c, &m, sizeof(MemFunc)) {}
  802. static RT thunk(const CBFunctorBase& ftor, P1 p1, P2 p2, P3 p3)
  803. {
  804. Callee* callee = (Callee*)ftor.callee;
  805. MemFunc& memFunc(*(MemFunc*)(void*)(ftor.memFunc));
  806. return BC4_RET_BUG((callee->*memFunc)(p1, p2, p3));
  807. }
  808. };
  809. template <class P1, class P2, class P3, class RT, class Func>
  810. class CBFunctionTranslator3wRet :public CBFunctor3wRet<P1, P2, P3, RT> {
  811. public:
  812. CBFunctionTranslator3wRet(Func f) :
  813. CBFunctor3wRet<P1, P2, P3, RT>(thunk, 0, f, 0) {}
  814. static RT thunk(const CBFunctorBase& ftor, P1 p1, P2 p2, P3 p3)
  815. {
  816. return (Func(ftor.func))(p1, p2, p3);
  817. }
  818. };
  819. template <class P1, class P2, class P3, class RT, class Callee,
  820. class TRT, class CallType, class TP1, class TP2, class TP3>
  821. inline CBMemberTranslator3wRet<P1, P2, P3, RT, Callee,
  822. TRT(CallType::*)(TP1, TP2, TP3)>
  823. makeFunctor(CBFunctor3wRet<P1, P2, P3, RT>*, Callee& c,
  824. TRT(CallType::* const& f)(TP1, TP2, TP3))
  825. {
  826. typedef TRT(CallType::* MemFunc)(TP1, TP2, TP3);
  827. return CBMemberTranslator3wRet<P1, P2, P3, RT, Callee, MemFunc>(c, f);
  828. }
  829. template <class P1, class P2, class P3, class RT, class Callee,
  830. class TRT, class CallType, class TP1, class TP2, class TP3>
  831. inline CBMemberTranslator3wRet<P1, P2, P3, RT, const Callee,
  832. TRT(CallType::*)(TP1, TP2, TP3)const>
  833. makeFunctor(CBFunctor3wRet<P1, P2, P3, RT>*, const Callee& c,
  834. TRT(CallType::* const& f)(TP1, TP2, TP3)const)
  835. {
  836. typedef TRT(CallType::* MemFunc)(TP1, TP2, TP3)const;
  837. return CBMemberTranslator3wRet<P1, P2, P3, RT, const Callee, MemFunc>(c, f);
  838. }
  839. template <class P1, class P2, class P3, class RT,
  840. class TRT, class TP1, class TP2, class TP3>
  841. inline CBFunctionTranslator3wRet<P1, P2, P3, RT, TRT(*)(TP1, TP2, TP3)>
  842. makeFunctor(CBFunctor3wRet<P1, P2, P3, RT>*, TRT(*f)(TP1, TP2, TP3))
  843. {
  844. return CBFunctionTranslator3wRet<P1, P2, P3, RT, TRT(*)(TP1, TP2, TP3)>(f);
  845. }
  846. template <class P1, class P2, class P3, class RT, class MemFunc>
  847. class CBMemberOf1stArgTranslator3wRet :public CBFunctor3wRet<P1, P2, P3, RT> {
  848. public:
  849. CBMemberOf1stArgTranslator3wRet(const MemFunc& m) :
  850. CBFunctor3wRet<P1, P2, P3, RT>(thunk, (void*)1, &m, sizeof(MemFunc)) {}
  851. static RT thunk(const CBFunctorBase& ftor, P1 p1, P2 p2, P3 p3)
  852. {
  853. MemFunc& memFunc(*(MemFunc*)(void*)(ftor.memFunc));
  854. return BC4_RET_BUG((p1.*memFunc)(p2, p3));
  855. }
  856. };
  857. template <class P1, class P2, class P3, class RT, class TRT, class CallType,
  858. class TP1, class TP2>
  859. inline CBMemberOf1stArgTranslator3wRet<P1, P2, P3, RT, TRT(CallType::*)(TP1, TP2)>
  860. makeFunctor(CBFunctor3wRet<P1, P2, P3, RT>*, TRT(CallType::* const& f)(TP1, TP2))
  861. {
  862. typedef TRT(CallType::* MemFunc)(TP1, TP2);
  863. return CBMemberOf1stArgTranslator3wRet<P1, P2, P3, RT, MemFunc>(f);
  864. }
  865. template <class P1, class P2, class P3, class RT, class TRT, class CallType,
  866. class TP1, class TP2>
  867. inline CBMemberOf1stArgTranslator3wRet<P1, P2, P3, RT,
  868. TRT(CallType::*)(TP1, TP2)const>
  869. makeFunctor(CBFunctor3wRet<P1, P2, P3, RT>*,
  870. TRT(CallType::* const& f)(TP1, TP2)const)
  871. {
  872. typedef TRT(CallType::* MemFunc)(TP1, TP2)const;
  873. return CBMemberOf1stArgTranslator3wRet<P1, P2, P3, RT, MemFunc>(f);
  874. }
  875. /************************* four args - no return *******************/
  876. template <class P1, class P2, class P3, class P4>
  877. class CBFunctor4 :protected CBFunctorBase {
  878. public:
  879. CBFunctor4(DummyInit* = 0) {}
  880. void operator()(P1 p1, P2 p2, P3 p3, P4 p4)const
  881. {
  882. thunk(*this, p1, p2, p3, p4);
  883. }
  884. CBFunctorBase::operator int;
  885. protected:
  886. typedef void (*Thunk)(const CBFunctorBase&, P1, P2, P3, P4);
  887. CBFunctor4(Thunk t, const void* c, const void* f, size_t sz) :
  888. CBFunctorBase(c, f, sz), thunk(t) {}
  889. private:
  890. Thunk thunk;
  891. };
  892. template <class P1, class P2, class P3, class P4,
  893. class Callee, class MemFunc>
  894. class CBMemberTranslator4 :public CBFunctor4<P1, P2, P3, P4> {
  895. public:
  896. CBMemberTranslator4(Callee& c, const MemFunc& m) :
  897. CBFunctor4<P1, P2, P3, P4>(thunk, &c, &m, sizeof(MemFunc)) {}
  898. static void thunk(const CBFunctorBase& ftor, P1 p1, P2 p2, P3 p3, P4 p4)
  899. {
  900. Callee* callee = (Callee*)ftor.callee;
  901. MemFunc& memFunc(*(MemFunc*)(void*)(ftor.memFunc));
  902. (callee->*memFunc)(p1, p2, p3, p4);
  903. }
  904. };
  905. template <class P1, class P2, class P3, class P4, class Func>
  906. class CBFunctionTranslator4 :public CBFunctor4<P1, P2, P3, P4> {
  907. public:
  908. // CBFunctionTranslator4(Func f):CBFunctor4<P1,P2,P3,P4>(thunk,0,f,0){}
  909. //EBR
  910. CBFunctionTranslator4(Func f) :CBFunctor4<P1, P2, P3, P4>(thunk, 0, (void*)f, 0) {}
  911. static void thunk(const CBFunctorBase& ftor, P1 p1, P2 p2, P3 p3, P4 p4)
  912. {
  913. (Func(ftor.func))(p1, p2, p3, p4);
  914. }
  915. };
  916. template <class P1, class P2, class P3, class P4, class Callee,
  917. class TRT, class CallType, class TP1, class TP2, class TP3, class TP4>
  918. inline CBMemberTranslator4<P1, P2, P3, P4, Callee,
  919. TRT(CallType::*)(TP1, TP2, TP3, TP4)>
  920. makeFunctor(CBFunctor4<P1, P2, P3, P4>*, Callee& c,
  921. TRT(CallType::* const& f)(TP1, TP2, TP3, TP4))
  922. {
  923. typedef TRT(CallType::* MemFunc)(TP1, TP2, TP3, TP4);
  924. return CBMemberTranslator4<P1, P2, P3, P4, Callee, MemFunc>(c, f);
  925. }
  926. template <class P1, class P2, class P3, class P4, class Callee,
  927. class TRT, class CallType, class TP1, class TP2, class TP3, class TP4>
  928. inline CBMemberTranslator4<P1, P2, P3, P4, const Callee,
  929. TRT(CallType::*)(TP1, TP2, TP3, TP4)const>
  930. makeFunctor(CBFunctor4<P1, P2, P3, P4>*, const Callee& c,
  931. TRT(CallType::* const& f)(TP1, TP2, TP3, TP4)const)
  932. {
  933. typedef TRT(CallType::* MemFunc)(TP1, TP2, TP3, TP4)const;
  934. return CBMemberTranslator4<P1, P2, P3, P4, const Callee, MemFunc>(c, f);
  935. }
  936. template <class P1, class P2, class P3, class P4,
  937. class TRT, class TP1, class TP2, class TP3, class TP4>
  938. inline CBFunctionTranslator4<P1, P2, P3, P4, TRT(*)(TP1, TP2, TP3, TP4)>
  939. makeFunctor(CBFunctor4<P1, P2, P3, P4>*, TRT(*f)(TP1, TP2, TP3, TP4))
  940. {
  941. return CBFunctionTranslator4<P1, P2, P3, P4, TRT(*)(TP1, TP2, TP3, TP4)>(f);
  942. }
  943. template <class P1, class P2, class P3, class P4, class MemFunc>
  944. class CBMemberOf1stArgTranslator4 :public CBFunctor4<P1, P2, P3, P4> {
  945. public:
  946. CBMemberOf1stArgTranslator4(const MemFunc& m) :
  947. CBFunctor4<P1, P2, P3, P4>(thunk, (void*)1, &m, sizeof(MemFunc)) {}
  948. static void thunk(const CBFunctorBase& ftor, P1 p1, P2 p2, P3 p3, P4 p4)
  949. {
  950. MemFunc& memFunc(*(MemFunc*)(void*)(ftor.memFunc));
  951. (p1.*memFunc)(p2, p3, p4);
  952. }
  953. };
  954. template <class P1, class P2, class P3, class P4, class TRT, class CallType,
  955. class TP1, class TP2, class TP3>
  956. inline CBMemberOf1stArgTranslator4<P1, P2, P3, P4, TRT(CallType::*)(TP1, TP2, TP3)>
  957. makeFunctor(CBFunctor4<P1, P2, P3, P4>*, TRT(CallType::* const& f)(TP1, TP2, TP3))
  958. {
  959. typedef TRT(CallType::* MemFunc)(TP1, TP2, TP3);
  960. return CBMemberOf1stArgTranslator4<P1, P2, P3, P4, MemFunc>(f);
  961. }
  962. template <class P1, class P2, class P3, class P4, class TRT, class CallType,
  963. class TP1, class TP2, class TP3>
  964. inline CBMemberOf1stArgTranslator4<P1, P2, P3, P4,
  965. TRT(CallType::*)(TP1, TP2, TP3)const>
  966. makeFunctor(CBFunctor4<P1, P2, P3, P4>*,
  967. TRT(CallType::* const& f)(TP1, TP2, TP3)const)
  968. {
  969. typedef TRT(CallType::* MemFunc)(TP1, TP2, TP3)const;
  970. return CBMemberOf1stArgTranslator4<P1, P2, P3, P4, MemFunc>(f);
  971. }
  972. /************************* four args - with return *******************/
  973. template <class P1, class P2, class P3, class P4, class RT>
  974. class CBFunctor4wRet :protected CBFunctorBase {
  975. public:
  976. CBFunctor4wRet(DummyInit* = 0) {}
  977. RT operator()(P1 p1, P2 p2, P3 p3, P4 p4)const
  978. {
  979. return BC4_RET_BUG(thunk(*this, p1, p2, p3, p4));
  980. }
  981. CBFunctorBase::operator int;
  982. protected:
  983. typedef RT(*Thunk)(const CBFunctorBase&, P1, P2, P3, P4);
  984. CBFunctor4wRet(Thunk t, const void* c, const void* f, size_t sz) :
  985. CBFunctorBase(c, f, sz), thunk(t) {}
  986. private:
  987. Thunk thunk;
  988. };
  989. template <class P1, class P2, class P3, class P4, class RT,
  990. class Callee, class MemFunc>
  991. class CBMemberTranslator4wRet :public CBFunctor4wRet<P1, P2, P3, P4, RT> {
  992. public:
  993. CBMemberTranslator4wRet(Callee& c, const MemFunc& m) :
  994. CBFunctor4wRet<P1, P2, P3, P4, RT>(thunk, &c, &m, sizeof(MemFunc)) {}
  995. static RT thunk(const CBFunctorBase& ftor, P1 p1, P2 p2, P3 p3, P4 p4)
  996. {
  997. Callee* callee = (Callee*)ftor.callee;
  998. MemFunc& memFunc(*(MemFunc*)(void*)(ftor.memFunc));
  999. return BC4_RET_BUG((callee->*memFunc)(p1, p2, p3, p4));
  1000. }
  1001. };
  1002. template <class P1, class P2, class P3, class P4, class RT, class Func>
  1003. class CBFunctionTranslator4wRet :public CBFunctor4wRet<P1, P2, P3, P4, RT> {
  1004. public:
  1005. CBFunctionTranslator4wRet(Func f) :
  1006. CBFunctor4wRet<P1, P2, P3, P4, RT>(thunk, 0, f, 0) {}
  1007. static RT thunk(const CBFunctorBase& ftor, P1 p1, P2 p2, P3 p3, P4 p4)
  1008. {
  1009. return (Func(ftor.func))(p1, p2, p3, p4);
  1010. }
  1011. };
  1012. template <class P1, class P2, class P3, class P4, class RT, class Callee,
  1013. class TRT, class CallType, class TP1, class TP2, class TP3, class TP4>
  1014. inline CBMemberTranslator4wRet<P1, P2, P3, P4, RT, Callee,
  1015. TRT(CallType::*)(TP1, TP2, TP3, TP4)>
  1016. makeFunctor(CBFunctor4wRet<P1, P2, P3, P4, RT>*, Callee& c,
  1017. TRT(CallType::* const& f)(TP1, TP2, TP3, TP4))
  1018. {
  1019. typedef TRT(CallType::* MemFunc)(TP1, TP2, TP3, TP4);
  1020. return CBMemberTranslator4wRet<P1, P2, P3, P4, RT, Callee, MemFunc>(c, f);
  1021. }
  1022. template <class P1, class P2, class P3, class P4, class RT, class Callee,
  1023. class TRT, class CallType, class TP1, class TP2, class TP3, class TP4>
  1024. inline CBMemberTranslator4wRet<P1, P2, P3, P4, RT, const Callee,
  1025. TRT(CallType::*)(TP1, TP2, TP3, TP4)const>
  1026. makeFunctor(CBFunctor4wRet<P1, P2, P3, P4, RT>*, const Callee& c,
  1027. TRT(CallType::* const& f)(TP1, TP2, TP3, TP4)const)
  1028. {
  1029. typedef TRT(CallType::* MemFunc)(TP1, TP2, TP3, TP4)const;
  1030. return CBMemberTranslator4wRet<P1, P2, P3, P4, RT, const Callee, MemFunc>(c, f);
  1031. }
  1032. template <class P1, class P2, class P3, class P4, class RT,
  1033. class TRT, class TP1, class TP2, class TP3, class TP4>
  1034. inline CBFunctionTranslator4wRet<P1, P2, P3, P4, RT, TRT(*)(TP1, TP2, TP3, TP4)>
  1035. makeFunctor(CBFunctor4wRet<P1, P2, P3, P4, RT>*, TRT(*f)(TP1, TP2, TP3, TP4))
  1036. {
  1037. return CBFunctionTranslator4wRet
  1038. <P1, P2, P3, P4, RT, TRT(*)(TP1, TP2, TP3, TP4)>(f);
  1039. }
  1040. template <class P1, class P2, class P3, class P4, class RT, class MemFunc>
  1041. class CBMemberOf1stArgTranslator4wRet :public CBFunctor4wRet<P1, P2, P3, P4, RT> {
  1042. public:
  1043. CBMemberOf1stArgTranslator4wRet(const MemFunc& m) :
  1044. CBFunctor4wRet<P1, P2, P3, P4, RT>(thunk, (void*)1, &m, sizeof(MemFunc)) {}
  1045. static RT thunk(const CBFunctorBase& ftor, P1 p1, P2 p2, P3 p3, P4 p4)
  1046. {
  1047. MemFunc& memFunc(*(MemFunc*)(void*)(ftor.memFunc));
  1048. return BC4_RET_BUG((p1.*memFunc)(p2, p3, p4));
  1049. }
  1050. };
  1051. template <class P1, class P2, class P3, class P4, class RT, class TRT,
  1052. class CallType, class TP1, class TP2, class TP3>
  1053. inline CBMemberOf1stArgTranslator4wRet<P1, P2, P3, P4, RT,
  1054. TRT(CallType::*)(TP1, TP2, TP3)>
  1055. makeFunctor(CBFunctor4wRet<P1, P2, P3, P4, RT>*,
  1056. TRT(CallType::* const& f)(TP1, TP2, TP3))
  1057. {
  1058. typedef TRT(CallType::* MemFunc)(TP1, TP2, TP3);
  1059. return CBMemberOf1stArgTranslator4wRet<P1, P2, P3, P4, RT, MemFunc>(f);
  1060. }
  1061. template <class P1, class P2, class P3, class P4, class RT, class TRT,
  1062. class CallType, class TP1, class TP2, class TP3>
  1063. inline CBMemberOf1stArgTranslator4wRet<P1, P2, P3, P4, RT,
  1064. TRT(CallType::*)(TP1, TP2, TP3)const>
  1065. makeFunctor(CBFunctor4wRet<P1, P2, P3, P4, RT>*,
  1066. TRT(CallType::* const& f)(TP1, TP2, TP3)const)
  1067. {
  1068. typedef TRT(CallType::* MemFunc)(TP1, TP2, TP3)const;
  1069. return CBMemberOf1stArgTranslator4wRet<P1, P2, P3, P4, RT, MemFunc>(f);
  1070. }
  1071. #endif //CALLBACK_HPP