00001 #ifndef CLASSLIB_HOOK_H
00002 # define CLASSLIB_HOOK_H
00003
00004
00005
00006 # include "classlib/sysapi/system.h"
00007
00008 namespace lat {
00009
00010
00011
00012
00013
00014
00015
00016 template <class R>
00017 class HookRep
00018 {
00019 public:
00020 HookRep (void) : m_refs (0) { }
00021 virtual ~HookRep (void) { }
00022
00023 virtual R call (void) = 0;
00024
00025 void ref (void) { ++m_refs; }
00026 void unref (void) { if (--m_refs == 0) delete this; }
00027
00028 private:
00029 int m_refs;
00030 };
00031
00032 template <class R>
00033 class Hook
00034 {
00035 public:
00036 Hook (HookRep<R> *implementation = 0);
00037 Hook (const Hook &x);
00038 ~Hook (void);
00039 Hook & operator= (const Hook &x);
00040
00041
00042 operator bool (void) const;
00043 R operator() (void) const;
00044
00045 private:
00046 HookRep<R> *m_rep;
00047 };
00048
00050 template <class R, class T1>
00051 class Hook1Rep
00052 {
00053 public:
00054 Hook1Rep (void) : m_refs (0) { }
00055 virtual ~Hook1Rep (void) { }
00056
00057 virtual R call (T1) = 0;
00058 void ref (void) { ++m_refs; }
00059 void unref (void) { if (--m_refs == 0) delete this; }
00060
00061 private:
00062 int m_refs;
00063 };
00064
00065 template <class R, class T1>
00066 class Hook1
00067 {
00068 public:
00069 Hook1 (Hook1Rep<R,T1> *implementation = 0);
00070 Hook1 (const Hook1 &x);
00071 ~Hook1 (void);
00072 Hook1 & operator= (const Hook1 &x);
00073
00074
00075 operator bool (void) const;
00076 R operator() (T1) const;
00077
00078 private:
00079 Hook1Rep<R,T1> *m_rep;
00080 };
00081
00083 template <class R, class T1, class T2>
00084 class Hook2Rep
00085 {
00086 public:
00087 Hook2Rep (void) : m_refs (0) { }
00088 virtual ~Hook2Rep (void) { }
00089
00090 virtual R call (T1, T2) = 0;
00091 void ref (void) { ++m_refs; }
00092 void unref (void) { if (--m_refs == 0) delete this; }
00093
00094 private:
00095 int m_refs;
00096 };
00097
00098 template <class R, class T1, class T2>
00099 class Hook2
00100 {
00101 public:
00102 Hook2 (Hook2Rep<R,T1,T2> *implementation = 0);
00103 Hook2 (const Hook2 &x);
00104 ~Hook2 (void);
00105 Hook2 & operator= (const Hook2 &x);
00106
00107
00108 operator bool (void) const;
00109 R operator() (T1, T2) const;
00110
00111 private:
00112 Hook2Rep<R,T1,T2> *m_rep;
00113 };
00114
00118 template <class R>
00119 class HookImpF00 : public HookRep<R>
00120 {
00121 public:
00122 HookImpF00 (R (*function) (void))
00123 : m_function (function)
00124 { }
00125
00126 virtual R call (void)
00127 { return (*m_function) (); }
00128
00129 private:
00130 R (*m_function) (void);
00131 };
00132
00134 template <class C, class R>
00135 class HookImpC00 : public HookRep<R>
00136 {
00137 public:
00138 HookImpC00 (C *object, R (C::*function) (void))
00139 : m_object (object),
00140 m_function (function)
00141 { }
00142
00143 virtual R call (void)
00144 { return (m_object->*m_function) (); }
00145
00146 private:
00147 C *m_object;
00148 R (C::*m_function) (void);
00149 };
00150
00152 template <class R, class T1>
00153 class HookImpF01 : public HookRep<R>
00154 {
00155 public:
00156 HookImpF01 (R (*function) (T1), const T1 &fill_1)
00157 : m_function (function),
00158 m_fill_1 (fill_1)
00159 { }
00160
00161 virtual R call (void)
00162 { return (*m_function) (m_fill_1); }
00163
00164 private:
00165 R (*m_function) (T1);
00166 T1 m_fill_1;
00167 };
00168
00170 template <class C, class R, class T1>
00171 class HookImpC01 : public HookRep<R>
00172 {
00173 public:
00174 HookImpC01 (C *object, R (C::*function) (T1), const T1 &fill_1)
00175 : m_object (object),
00176 m_function (function),
00177 m_fill_1 (fill_1)
00178 { }
00179
00180 virtual R call (void)
00181 { return (m_object->*m_function) (m_fill_1); }
00182
00183 private:
00184 C *m_object;
00185 R (C::*m_function) (T1);
00186 T1 m_fill_1;
00187 };
00188
00190 template <class R, class T1, class T2>
00191 class HookImpF02 : public HookRep<R>
00192 {
00193 public:
00194 HookImpF02 (R (*function) (T1, T2), const T1 &fill_1, const T2 &fill_2)
00195 : m_function (function),
00196 m_fill_1 (fill_1),
00197 m_fill_2 (fill_2)
00198 { }
00199
00200 virtual R call (void)
00201 { return (*m_function) (m_fill_1, m_fill_2); }
00202
00203 private:
00204 R (*m_function) (T1, T2);
00205 T1 m_fill_1;
00206 T2 m_fill_2;
00207 };
00208
00210 template <class C, class R, class T1, class T2>
00211 class HookImpC02 : public HookRep<R>
00212 {
00213 public:
00214 HookImpC02 (C *object, R (C::*function) (T1,T2), const T1 &fill_1, const T2 &fill_2)
00215 : m_object (object),
00216 m_function (function),
00217 m_fill_1 (fill_1),
00218 m_fill_2 (fill_2)
00219 { }
00220
00221 virtual R call (void)
00222 { return (m_object->*m_function) (m_fill_1, m_fill_2); }
00223
00224 private:
00225 C *m_object;
00226 R (C::*m_function) (T1);
00227 T1 m_fill_1;
00228 T2 m_fill_2;
00229 };
00230
00232 template <class R, class T1>
00233 class HookImpF10 : public Hook1Rep<R,T1>
00234 {
00235 public:
00236 HookImpF10 (R (*function) (T1))
00237 : m_function (function)
00238 { }
00239
00240 virtual R call (T1 a)
00241 { return (*m_function) (a); }
00242
00243 private:
00244 R (*m_function) (T1);
00245 };
00246
00248 template <class C, class R, class T1>
00249 class HookImpC10 : public Hook1Rep<R,T1>
00250 {
00251 public:
00252 HookImpC10 (C *object, R (C::*function) (T1))
00253 : m_object (object),
00254 m_function (function)
00255 { }
00256
00257 virtual R call (T1 a)
00258 { return (m_object->*m_function) (a); }
00259
00260 private:
00261 C *m_object;
00262 R (C::*m_function) (T1);
00263 };
00264
00266 template <class R, class T1, class T2>
00267 class HookImpF11 : public Hook1Rep<R,T1>
00268 {
00269 public:
00270 HookImpF11 (R (*function) (T1, T2), const T2 &fill_2)
00271 : m_function (function),
00272 m_fill_2 (fill_2)
00273 { }
00274
00275 virtual R call (T1 a)
00276 { return (*m_function) (a, m_fill_2); }
00277
00278 private:
00279 R (*m_function) (T1, T2);
00280 T2 m_fill_2;
00281 };
00282
00284 template <class C, class R, class T1, class T2>
00285 class HookImpC11 : public Hook1Rep<R,T1>
00286 {
00287 public:
00288 HookImpC11 (C *object, R (C::*function) (T1, T2), const T2 &fill_2)
00289 : m_object (object),
00290 m_function (function),
00291 m_fill_2 (fill_2)
00292 { }
00293
00294 virtual R call (T1 a)
00295 { return (m_object->*m_function) (a, m_fill_2); }
00296
00297 private:
00298 C *m_object;
00299 R (C::*m_function) (T1, T2);
00300 T2 m_fill_2;
00301 };
00302
00304 template <class R, class T1, class T2, class T3>
00305 class HookImpF12 : public Hook1Rep<R,T1>
00306 {
00307 public:
00308 HookImpF12 (R (*function) (T1, T2, T3), const T2 &fill_2, const T3 &fill_3)
00309 : m_function (function),
00310 m_fill_2 (fill_2),
00311 m_fill_3 (fill_3)
00312 { }
00313
00314 virtual R call (T1 a)
00315 { return (*m_function) (a, m_fill_2, m_fill_3); }
00316
00317 private:
00318 R (*m_function) (T1, T2, T3);
00319 T2 m_fill_2;
00320 T3 m_fill_3;
00321 };
00322
00324 template <class C, class R, class T1, class T2, class T3>
00325 class HookImpC12 : public Hook1Rep<R,T1>
00326 {
00327 public:
00328 HookImpC12 (C *object, R (C::*function) (T1, T2, T3), const T2 &fill_2, const T3 &fill_3)
00329 : m_object (object),
00330 m_function (function),
00331 m_fill_2 (fill_2),
00332 m_fill_3 (fill_3)
00333 { }
00334
00335 virtual R call (T1 a)
00336 { return (m_object->*m_function) (a, m_fill_2, m_fill_3); }
00337
00338 private:
00339 C *m_object;
00340 R (C::*m_function) (T1, T2, T3);
00341 T2 m_fill_2;
00342 T3 m_fill_3;
00343 };
00344
00346 template <class R, class T1, class T2>
00347 class HookImpF20 : public Hook2Rep<R,T1,T2>
00348 {
00349 public:
00350 HookImpF20 (R (*function) (T1, T2))
00351 : m_function (function)
00352 { }
00353
00354 virtual R call (T1 a, T2 b)
00355 { return (*m_function) (a, b); }
00356
00357 private:
00358 R (*m_function) (T1, T2);
00359 };
00360
00362 template <class C, class R, class T1, class T2>
00363 class HookImpC20 : public Hook2Rep<R,T1,T2>
00364 {
00365 public:
00366 HookImpC20 (C *object, R (C::*function) (T1, T2))
00367 : m_object (object),
00368 m_function (function)
00369 { }
00370
00371 virtual R call (T1 a, T2 b)
00372 { return (m_object->*m_function) (a, b); }
00373
00374 private:
00375 C *m_object;
00376 R (C::*m_function) (T1, T2);
00377 };
00378
00380 template <class R, class T1, class T2, class T3>
00381 class HookImpF21 : public Hook2Rep<R,T1,T2>
00382 {
00383 public:
00384 HookImpF21 (R (*function) (T1, T2, T3), const T3 &fill_3)
00385 : m_function (function),
00386 m_fill_3 (fill_3)
00387 { }
00388
00389 virtual R call (T1 a, T2 b)
00390 { return (*m_function) (a, b, m_fill_3); }
00391
00392 private:
00393 R (*m_function) (T1, T2, T3);
00394 T3 m_fill_3;
00395 };
00396
00398 template <class C, class R, class T1, class T2, class T3>
00399 class HookImpC21 : public Hook2Rep<R,T1,T2>
00400 {
00401 public:
00402 HookImpC21 (C *object, R (C::*function) (T1, T2, T3), const T3 &fill_3)
00403 : m_object (object),
00404 m_function (function),
00405 m_fill_3 (fill_3)
00406 { }
00407
00408 virtual R call (T1 a, T2 b)
00409 { return (m_object->*m_function) (a, b, m_fill_3); }
00410
00411 private:
00412 C *m_object;
00413 R (C::*m_function) (T1, T2, T3);
00414 T3 m_fill_3;
00415 };
00416
00418 template <class R, class T1, class T2, class T3, class T4>
00419 class HookImpF22 : public Hook2Rep<R,T1,T2>
00420 {
00421 public:
00422 HookImpF22 (R (*function) (T1, T2, T3, T4), const T3 &fill_3, const T4 &fill_4)
00423 : m_function (function),
00424 m_fill_3 (fill_3),
00425 m_fill_4 (fill_4)
00426 { }
00427
00428 virtual R call (T1 a, T2 b)
00429 { return (*m_function) (a, b, m_fill_3, m_fill_4); }
00430
00431 private:
00432 R (*m_function) (T1, T2, T3, T4);
00433 T3 m_fill_3;
00434 T4 m_fill_4;
00435 };
00436
00438 template <class C, class R, class T1, class T2, class T3, class T4>
00439 class HookImpC22 : public Hook2Rep<R,T1,T2>
00440 {
00441 public:
00442 HookImpC22 (C *object, R (C::*function) (T1, T2, T3, T4), const T3 &fill_3, const T4 &fill_4)
00443 : m_object (object),
00444 m_function (function),
00445 m_fill_3 (fill_3),
00446 m_fill_4 (fill_4)
00447 { }
00448
00449 virtual R call (T1 a, T2 b)
00450 { return (m_object->*m_function) (a, b, m_fill_3, m_fill_4); }
00451
00452 private:
00453 C *m_object;
00454 R (C::*m_function) (T1, T2, T3, T4);
00455 T3 m_fill_3;
00456 T4 m_fill_4;
00457 };
00458
00460
00461
00462
00463 template <class R>
00464 inline HookRep<R> *
00465 CreateHook (R (*function) (void))
00466 { return new HookImpF00<R> (function); }
00467
00468 template <class C, class R>
00469 inline HookRep<R> *
00470 CreateHook (C *object, R (C::*function) (void))
00471 { return new HookImpC00<C,R> (object, function); }
00472
00473 template <class R, class T1>
00474 inline HookRep<R> *
00475 CreateHook (R (*function) (T1),
00476 const T1 &fill_1)
00477 { return new HookImpF01<R,T1> (function, fill_1); }
00478
00479 template <class C, class R, class T1>
00480 inline HookRep<R> *
00481 CreateHook (C *object, R (C::*function) (T1),
00482 const T1 &fill_1)
00483 { return new HookImpC01<C,R,T1> (object, function, fill_1); }
00484
00485 template <class R, class T1, class T2>
00486 inline HookRep<R> *
00487 CreateHook (R (*function) (T1, T2),
00488 const T1 &fill_1, const T2 &fill_2)
00489 { return new HookImpF02<R,T1,T2> (function, fill_1, fill_2); }
00490
00491 template <class C, class R, class T1, class T2>
00492 inline HookRep<R> *
00493 CreateHook (C *object, R (C::*function) (T1,T2),
00494 const T1 &fill_1, const T2 &fill_2)
00495 { return new HookImpC20<C,R,T1,T2> (object, function, fill_1, fill_2); }
00496
00497 template <class R, class T1>
00498 inline Hook1Rep<R,T1> *
00499 CreateHook (R (*function) (T1))
00500 { return new HookImpF10<R,T1> (function); }
00501
00502 template <class C, class R, class T1>
00503 inline Hook1Rep<R,T1> *
00504 CreateHook (C *object, R (C::*function) (T1))
00505 { return new HookImpC10<C,R,T1> (object, function); }
00506
00507 template <class R, class T1, class T2>
00508 inline Hook1Rep<R,T1> *
00509 CreateHook (R (*function) (T1, T2),
00510 const T2 &fill_2)
00511 { return new HookImpF11<R,T1,T2> (function, fill_2); }
00512
00513 template <class C, class R, class T1, class T2>
00514 inline Hook1Rep<R,T1> *
00515 CreateHook (C *object, R (C::*function) (T1, T2),
00516 const T2 &fill_2)
00517 { return new HookImpC11<C,R,T1,T2> (object, function, fill_2); }
00518
00519 template <class R, class T1, class T2, class T3>
00520 inline Hook1Rep<R,T1> *
00521 CreateHook (R (*function) (T1, T2, T3),
00522 const T2 &fill_2, const T3 &fill_3)
00523 { return new HookImpF12<R,T1,T2,T3> (function, fill_2, fill_3); }
00524
00525 template <class C, class R, class T1, class T2, class T3>
00526 inline Hook1Rep<R,T1> *
00527 CreateHook (C *object, R (C::*function) (T1, T2, T3),
00528 const T2 &fill_2, const T3 &fill_3)
00529 { return new HookImpC12<C,R,T1,T2,T3> (object, function, fill_2, fill_3); }
00530
00531 template <class R, class T1, class T2>
00532 inline Hook2Rep<R,T1,T2> *
00533 CreateHook (R (*function) (T1, T2))
00534 { return new HookImpF20<R,T1,T2> (function); }
00535
00536 template <class C, class R, class T1, class T2>
00537 inline Hook2Rep<R,T1,T2> *
00538 CreateHook (C *object, R (C::*function) (T1, T2))
00539 { return new HookImpC20<C,R,T1,T2> (object, function); }
00540
00541 template <class R, class T1, class T2, class T3>
00542 inline Hook2Rep<R,T1,T2> *
00543 CreateHook (R (*function) (T1, T2, T3),
00544 const T3 &fill_3)
00545 { return new HookImpF21<R,T1,T2,T3> (function, fill_3); }
00546
00547 template <class C, class R, class T1, class T2, class T3>
00548 inline Hook2Rep<R,T1,T2> *
00549 CreateHook (C *object, R (C::*function) (T1, T2, T3),
00550 const T3 &fill_3)
00551 { return new HookImpC21<C,R,T1,T2,T3> (object, function, fill_3); }
00552
00553 template <class R, class T1, class T2, class T3, class T4>
00554 inline Hook2Rep<R,T1,T2> *
00555 CreateHook (R (*function) (T1, T2, T3, T4),
00556 const T3 &fill_3, const T4 &fill_4)
00557 { return new HookImpF22<R,T1,T2,T3,T4> (function, fill_3, fill_4); }
00558
00559 template <class C, class R, class T1, class T2, class T3, class T4>
00560 inline Hook2Rep<R,T1,T2> *
00561 CreateHook (C *object, R (C::*function) (T1, T2, T3, T4),
00562 const T3 &fill_3, const T4 &fill_4)
00563 { return new HookImpC22<C,R,T1,T2,T3,T4> (object, function, fill_3, fill_4); }
00564
00565
00566
00567 template <class R>
00568 inline
00569 Hook<R>::Hook (HookRep<R> *implementation )
00570 : m_rep (implementation)
00571 { if (m_rep) m_rep->ref (); }
00572
00573 template <class R>
00574 inline
00575 Hook<R>::Hook (const Hook<R> &x)
00576 : m_rep (x.m_rep)
00577 { if (m_rep) m_rep->ref (); }
00578
00579 template <class R>
00580 inline
00581 Hook<R>::~Hook (void)
00582 { if (m_rep) m_rep->unref (); }
00583
00584 template <class R>
00585 inline Hook<R> &
00586 Hook<R>::operator= (const Hook<R> &x)
00587 {
00588 if (m_rep != x.m_rep)
00589 {
00590 if (m_rep) m_rep->unref ();
00591 m_rep = x.m_rep;
00592 if (m_rep) m_rep->ref ();
00593 }
00594 return *this;
00595 }
00596
00597 template <class R>
00598 inline
00599 Hook<R>::operator bool (void) const
00600 { return m_rep != 0; }
00601
00602 template <class R>
00603 inline R
00604 Hook<R>::operator() (void) const
00605 { return m_rep->call (); }
00606
00610 template <class R, class T1>
00611 inline
00612 Hook1<R,T1>::Hook1 (Hook1Rep<R,T1> *implementation )
00613 : m_rep (implementation)
00614 { if (m_rep) m_rep->ref (); }
00615
00616 template <class R, class T1>
00617 inline
00618 Hook1<R,T1>::Hook1 (const Hook1<R,T1> &x)
00619 : m_rep (x.m_rep)
00620 { if (m_rep) m_rep->ref (); }
00621
00622 template <class R, class T1>
00623 inline
00624 Hook1<R,T1>::~Hook1 (void)
00625 { if (m_rep) m_rep->unref (); }
00626
00627 template <class R, class T1>
00628 inline Hook1<R,T1> &
00629 Hook1<R,T1>::operator= (const Hook1<R,T1> &x)
00630 {
00631 if (m_rep != x.m_rep)
00632 {
00633 if (m_rep) m_rep->unref ();
00634 m_rep = x.m_rep;
00635 if (m_rep) m_rep->ref ();
00636 }
00637 return *this;
00638 }
00639
00640 template <class R, class T1>
00641 inline
00642 Hook1<R,T1>::operator bool (void) const
00643 { return m_rep != 0; }
00644
00645 template <class R, class T1>
00646 inline R
00647 Hook1<R,T1>::operator() (T1 a) const
00648 { return m_rep->call (a); }
00649
00653 template <class R, class T1, class T2>
00654 inline
00655 Hook2<R,T1,T2>::Hook2 (Hook2Rep<R,T1,T2> *implementation )
00656 : m_rep (implementation)
00657 { if (m_rep) m_rep->ref (); }
00658
00659 template <class R, class T1, class T2>
00660 inline
00661 Hook2<R,T1,T2>::Hook2 (const Hook2<R,T1,T2> &x)
00662 : m_rep (x.m_rep)
00663 { if (m_rep) m_rep->ref (); }
00664
00665 template <class R, class T1, class T2>
00666 inline
00667 Hook2<R,T1,T2>::~Hook2 (void)
00668 { if (m_rep) m_rep->unref (); }
00669
00670 template <class R, class T1, class T2>
00671 inline Hook2<R,T1,T2> &
00672 Hook2<R,T1,T2>::operator= (const Hook2<R,T1,T2> &x)
00673 {
00674 if (m_rep != x.m_rep)
00675 {
00676 if (m_rep) m_rep->unref ();
00677 m_rep = x.m_rep;
00678 if (m_rep) m_rep->ref ();
00679 }
00680 return *this;
00681 }
00682
00683 template <class R, class T1, class T2>
00684 inline
00685 Hook2<R,T1,T2>::operator bool (void) const
00686 { return m_rep != 0; }
00687
00688 template <class R, class T1, class T2>
00689 inline R
00690 Hook2<R,T1,T2>::operator() (T1 a, T2 b) const
00691 { return m_rep->call (a, b); }
00692
00693 }
00694 #endif // CLASSLIB_HOOK_H