00001
00002
00003
00004
00005
00006 #ifndef __WVCALLBACK_H
00007 #define __WVCALLBACK_H
00008
00009 class E;
00010
00011 template<typename R,
00012 typename P1 = E,
00013 typename P2 = E,
00014 typename P3 = E,
00015 typename P4 = E,
00016 typename P5 = E,
00017 typename P6 = E,
00018 typename P7 = E,
00019 typename P8 = E>
00020 class WvCallbackImpl
00021 {
00022 public:
00023 struct FrozenParams
00024 {
00025 FrozenParams(const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4, const P5 &p5, const P6 &p6, const P7 &p7, const P8 &p8)
00026 : p1(p1), p2(p2), p3(p3), p4(p4), p5(p5), p6(p6), p7(p7), p8(p8)
00027 { }
00028
00029 P1 p1;
00030 P2 p2;
00031 P3 p3;
00032 P4 p4;
00033 P5 p5;
00034 P6 p6;
00035 P7 p7;
00036 P8 p8;
00037 };
00038
00039 typedef R(*type)(P1, P2, P3, P4, P5, P6, P7, P8);
00040 R thaw(const FrozenParams &frozen)
00041 { return operator()(frozen.p1, frozen.p2, frozen.p3, frozen.p4, frozen.p5, frozen.p6, frozen.p7, frozen.p8); }
00042 virtual R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) = 0;
00043 virtual WvCallbackImpl* clone() const = 0;
00044 virtual ~WvCallbackImpl()
00045 { }
00046 };
00047
00048 template<typename R,
00049 typename P1,
00050 typename P2,
00051 typename P3,
00052 typename P4,
00053 typename P5,
00054 typename P6,
00055 typename P7>
00056 class WvCallbackImpl<R, P1, P2, P3, P4, P5, P6, P7, E>
00057 {
00058 public:
00059 struct FrozenParams
00060 {
00061 FrozenParams(const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4, const P5 &p5, const P6 &p6, const P7 &p7)
00062 : p1(p1), p2(p2), p3(p3), p4(p4), p5(p5), p6(p6), p7(p7)
00063 { }
00064
00065 P1 p1;
00066 P2 p2;
00067 P3 p3;
00068 P4 p4;
00069 P5 p5;
00070 P6 p6;
00071 P7 p7;
00072 };
00073
00074 typedef R(*type)(P1, P2, P3, P4, P5, P6, P7);
00075 R thaw(const FrozenParams &frozen)
00076 { return operator()(frozen.p1, frozen.p2, frozen.p3, frozen.p4, frozen.p5, frozen.p6, frozen.p7); }
00077 virtual R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) = 0;
00078 virtual WvCallbackImpl* clone() const = 0;
00079 virtual ~WvCallbackImpl()
00080 { }
00081 };
00082
00083 template<typename R,
00084 typename P1,
00085 typename P2,
00086 typename P3,
00087 typename P4,
00088 typename P5,
00089 typename P6>
00090 class WvCallbackImpl<R, P1, P2, P3, P4, P5, P6, E, E>
00091 {
00092 public:
00093 struct FrozenParams
00094 {
00095 FrozenParams(const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4, const P5 &p5, const P6 &p6)
00096 : p1(p1), p2(p2), p3(p3), p4(p4), p5(p5), p6(p6)
00097 { }
00098
00099 P1 p1;
00100 P2 p2;
00101 P3 p3;
00102 P4 p4;
00103 P5 p5;
00104 P6 p6;
00105 };
00106
00107 typedef R(*type)(P1, P2, P3, P4, P5, P6);
00108 R thaw(const FrozenParams &frozen)
00109 { return operator()(frozen.p1, frozen.p2, frozen.p3, frozen.p4, frozen.p5, frozen.p6); }
00110 virtual R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) = 0;
00111 virtual WvCallbackImpl* clone() const = 0;
00112 virtual ~WvCallbackImpl()
00113 { }
00114 };
00115
00116 template<typename R,
00117 typename P1,
00118 typename P2,
00119 typename P3,
00120 typename P4,
00121 typename P5>
00122 class WvCallbackImpl<R, P1, P2, P3, P4, P5, E, E, E>
00123 {
00124 public:
00125 struct FrozenParams
00126 {
00127 FrozenParams(const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4, const P5 &p5)
00128 : p1(p1), p2(p2), p3(p3), p4(p4), p5(p5)
00129 { }
00130
00131 P1 p1;
00132 P2 p2;
00133 P3 p3;
00134 P4 p4;
00135 P5 p5;
00136 };
00137
00138 typedef R(*type)(P1, P2, P3, P4, P5);
00139 R thaw(const FrozenParams &frozen)
00140 { return operator()(frozen.p1, frozen.p2, frozen.p3, frozen.p4, frozen.p5); }
00141 virtual R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) = 0;
00142 virtual WvCallbackImpl* clone() const = 0;
00143 virtual ~WvCallbackImpl()
00144 { }
00145 };
00146
00147 template<typename R,
00148 typename P1,
00149 typename P2,
00150 typename P3,
00151 typename P4>
00152 class WvCallbackImpl<R, P1, P2, P3, P4, E, E, E, E>
00153 {
00154 public:
00155 struct FrozenParams
00156 {
00157 FrozenParams(const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4)
00158 : p1(p1), p2(p2), p3(p3), p4(p4)
00159 { }
00160
00161 P1 p1;
00162 P2 p2;
00163 P3 p3;
00164 P4 p4;
00165 };
00166
00167 typedef R(*type)(P1, P2, P3, P4);
00168 R thaw(const FrozenParams &frozen)
00169 { return operator()(frozen.p1, frozen.p2, frozen.p3, frozen.p4); }
00170 virtual R operator()(P1 p1, P2 p2, P3 p3, P4 p4) = 0;
00171 virtual WvCallbackImpl* clone() const = 0;
00172 virtual ~WvCallbackImpl()
00173 { }
00174 };
00175
00176 template<typename R,
00177 typename P1,
00178 typename P2,
00179 typename P3>
00180 class WvCallbackImpl<R, P1, P2, P3, E, E, E, E, E>
00181 {
00182 public:
00183 struct FrozenParams
00184 {
00185 FrozenParams(const P1 &p1, const P2 &p2, const P3 &p3)
00186 : p1(p1), p2(p2), p3(p3)
00187 { }
00188
00189 P1 p1;
00190 P2 p2;
00191 P3 p3;
00192 };
00193
00194 typedef R(*type)(P1, P2, P3);
00195 R thaw(const FrozenParams &frozen)
00196 { return operator()(frozen.p1, frozen.p2, frozen.p3); }
00197 virtual R operator()(P1 p1, P2 p2, P3 p3) = 0;
00198 virtual WvCallbackImpl* clone() const = 0;
00199 virtual ~WvCallbackImpl()
00200 { }
00201 };
00202
00203 template<typename R,
00204 typename P1,
00205 typename P2>
00206 class WvCallbackImpl<R, P1, P2, E, E, E, E, E, E>
00207 {
00208 public:
00209 struct FrozenParams
00210 {
00211 FrozenParams(const P1 &p1, const P2 &p2)
00212 : p1(p1), p2(p2)
00213 { }
00214
00215 P1 p1;
00216 P2 p2;
00217 };
00218
00219 typedef R(*type)(P1, P2);
00220 R thaw(const FrozenParams &frozen)
00221 { return operator()(frozen.p1, frozen.p2); }
00222 virtual R operator()(P1 p1, P2 p2) = 0;
00223 virtual WvCallbackImpl* clone() const = 0;
00224 virtual ~WvCallbackImpl()
00225 { }
00226 };
00227
00228 template<typename R,
00229 typename P1>
00230 class WvCallbackImpl<R, P1, E, E, E, E, E, E, E>
00231 {
00232 public:
00233 struct FrozenParams
00234 {
00235 FrozenParams(const P1 &p1)
00236 : p1(p1)
00237 { }
00238
00239 P1 p1;
00240 };
00241
00242 typedef R(*type)(P1);
00243 R thaw(const FrozenParams &frozen)
00244 { return operator()(frozen.p1); }
00245 virtual R operator()(P1 p1) = 0;
00246 virtual WvCallbackImpl* clone() const = 0;
00247 virtual ~WvCallbackImpl()
00248 { }
00249 };
00250
00251 template<typename R>
00252 class WvCallbackImpl<R, E, E, E, E, E, E, E, E>
00253 {
00254 public:
00255 struct FrozenParams
00256 {
00257 };
00258
00259 typedef R(*type)();
00260 R thaw(const FrozenParams &frozen)
00261 { return operator()(); }
00262 virtual R operator()() = 0;
00263 virtual WvCallbackImpl* clone() const = 0;
00264 virtual ~WvCallbackImpl()
00265 { }
00266 };
00267
00268 template<class ParentCallback,
00269 typename Functor>
00270 class WvCallbackFunctor
00271 : public WvCallbackImpl<typename ParentCallback::ReturnType,
00272 typename ParentCallback::Parm1,
00273 typename ParentCallback::Parm2,
00274 typename ParentCallback::Parm3,
00275 typename ParentCallback::Parm4,
00276 typename ParentCallback::Parm5,
00277 typename ParentCallback::Parm6,
00278 typename ParentCallback::Parm7,
00279 typename ParentCallback::Parm8>
00280 {
00281 typedef typename ParentCallback::ReturnType R;
00282 typedef typename ParentCallback::Parm1 P1;
00283 typedef typename ParentCallback::Parm2 P2;
00284 typedef typename ParentCallback::Parm3 P3;
00285 typedef typename ParentCallback::Parm4 P4;
00286 typedef typename ParentCallback::Parm5 P5;
00287 typedef typename ParentCallback::Parm6 P6;
00288 typedef typename ParentCallback::Parm7 P7;
00289 typedef typename ParentCallback::Parm8 P8;
00290 Functor func;
00291 public:
00292 WvCallbackFunctor(const Functor& _func): func(_func)
00293 { }
00294 WvCallbackFunctor* clone() const
00295 { return new WvCallbackFunctor(*this); }
00296 R operator()()
00297 { return func(); }
00298 R operator()(P1 p1)
00299 { return func(p1); }
00300 R operator()(P1 p1, P2 p2)
00301 { return func(p1, p2); }
00302 R operator()(P1 p1, P2 p2, P3 p3)
00303 { return func(p1, p2, p3); }
00304 R operator()(P1 p1, P2 p2, P3 p3, P4 p4)
00305 { return func(p1, p2, p3, p4); }
00306 R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)
00307 { return func(p1, p2, p3, p4, p5); }
00308 R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6)
00309 { return func(p1, p2, p3, p4, p5, p6); }
00310 R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7)
00311 { return func(p1, p2, p3, p4, p5, p6, p7); }
00312 R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8)
00313 { return func(p1, p2, p3, p4, p5, p6, p7, p8); }
00314 };
00315
00316 template<class ParentCallback,
00317 typename PtrToObject,
00318 typename PtrToMember>
00319 class WvCallbackMember
00320 : public WvCallbackImpl<typename ParentCallback::ReturnType,
00321 typename ParentCallback::Parm1,
00322 typename ParentCallback::Parm2,
00323 typename ParentCallback::Parm3,
00324 typename ParentCallback::Parm4,
00325 typename ParentCallback::Parm5,
00326 typename ParentCallback::Parm6,
00327 typename ParentCallback::Parm7,
00328 typename ParentCallback::Parm8>
00329 {
00330 typedef typename ParentCallback::ReturnType R;
00331 typedef typename ParentCallback::Parm1 P1;
00332 typedef typename ParentCallback::Parm2 P2;
00333 typedef typename ParentCallback::Parm3 P3;
00334 typedef typename ParentCallback::Parm4 P4;
00335 typedef typename ParentCallback::Parm5 P5;
00336 typedef typename ParentCallback::Parm6 P6;
00337 typedef typename ParentCallback::Parm7 P7;
00338 typedef typename ParentCallback::Parm8 P8;
00339 PtrToObject obj;
00340 PtrToMember member;
00341 public:
00342 WvCallbackMember(PtrToObject _obj, PtrToMember _member)
00343 : obj(_obj), member(_member)
00344 { }
00345 WvCallbackMember* clone() const
00346 { return new WvCallbackMember(*this); }
00347 R operator()()
00348 { return ((*obj).*member)(); }
00349 R operator()(P1 p1)
00350 { return ((*obj).*member)(p1); }
00351 R operator()(P1 p1, P2 p2)
00352 { return ((*obj).*member)(p1, p2); }
00353 R operator()(P1 p1, P2 p2, P3 p3)
00354 { return ((*obj).*member)(p1, p2, p3); }
00355 R operator()(P1 p1, P2 p2, P3 p3, P4 p4)
00356 { return ((*obj).*member)(p1, p2, p3, p4); }
00357 R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)
00358 { return ((*obj).*member)(p1, p2, p3, p4, p5); }
00359 R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6)
00360 { return ((*obj).*member)(p1, p2, p3, p4, p5, p6); }
00361 R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7)
00362 { return ((*obj).*member)(p1, p2, p3, p4, p5, p6, p7); }
00363 R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8)
00364 { return ((*obj).*member)(p1, p2, p3, p4, p5, p6, p7, p8); }
00365 };
00366
00367 template<typename R = void,
00368 typename P1 = E,
00369 typename P2 = E,
00370 typename P3 = E,
00371 typename P4 = E,
00372 typename P5 = E,
00373 typename P6 = E,
00374 typename P7 = E,
00375 typename P8 = E>
00376 class WvCallback
00377 {
00378 private:
00379 typedef WvCallbackImpl<R, P1, P2, P3, P4, P5, P6, P7, P8> Impl;
00380 Impl *impl;
00381 public:
00382 typedef typename Impl::FrozenParams FrozenParams;
00383 typedef R ReturnType;
00384 typedef P1 Parm1;
00385 typedef P2 Parm2;
00386 typedef P3 Parm3;
00387 typedef P4 Parm4;
00388 typedef P5 Parm5;
00389 typedef P6 Parm6;
00390 typedef P7 Parm7;
00391 typedef P8 Parm8;
00392 WvCallback() : impl(0)
00393 { }
00394 WvCallback(int) : impl(0)
00395 { }
00396 WvCallback(const WvCallback& cb): impl(0)
00397 { if(cb.impl) impl = cb.impl->clone(); }
00398 template<typename Functor>
00399 WvCallback(const Functor& func)
00400 { impl = new WvCallbackFunctor<WvCallback, Functor>(func); }
00401 WvCallback(const typename WvCallbackImpl<R, P1, P2, P3, P4, P5, P6, P7, P8>::type func)
00402 { impl = new WvCallbackFunctor<WvCallback,
00403 typename WvCallbackImpl<R, P1, P2, P3, P4, P5, P6, P7, P8>
00404 ::type>(func); }
00405 template<typename PtrToObject, typename PtrToMember>
00406 WvCallback(PtrToObject obj, PtrToMember member)
00407 { impl = new WvCallbackMember<WvCallback, PtrToObject, PtrToMember>
00408 (obj, member); }
00409 ~WvCallback()
00410 { delete impl; }
00411
00412 WvCallback& operator=(const WvCallback& cb)
00413 {
00414 if (this != &cb)
00415 {
00416 Impl *oldimp = impl;
00417 impl = 0;
00418 if (oldimp != 0)
00419 delete oldimp;
00420 if (cb.impl)
00421 impl = cb.impl->clone();
00422 else
00423 impl = 0;
00424 }
00425 return *this;
00426 }
00427
00428 operator bool() const
00429 { return impl != 0; }
00430 R operator()() const
00431 { return (*impl)(); }
00432 R operator()(P1 p1) const
00433 { return (*impl)(p1); }
00434 R operator()(P1 p1, P2 p2) const
00435 { return (*impl)(p1, p2); }
00436 R operator()(P1 p1, P2 p2, P3 p3) const
00437 { return (*impl)(p1, p2, p3); }
00438 R operator()(P1 p1, P2 p2, P3 p3, P4 p4) const
00439 { return (*impl)(p1, p2, p3, p4); }
00440 R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const
00441 { return (*impl)(p1, p2, p3, p4, p5); }
00442 R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) const
00443 { return (*impl)(p1, p2, p3, p4, p5, p6); }
00444 R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) const
00445 { return (*impl)(p1, p2, p3, p4, p5, p6, p7); }
00446 R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) const
00447 { return (*impl)(p1, p2, p3, p4, p5, p6, p7, p8); }
00448 R thaw(const FrozenParams &frozen) const
00449 { return impl->thaw(frozen); }
00450
00451 protected:
00452
00453
00454 bool operator== (const WvCallback& cb);
00455 };
00456
00457
00458 template<class InnerCallback, typename B>
00459 class WvBoundCallback
00460 {
00461 private:
00462 typedef typename InnerCallback::ReturnType R;
00463 typedef typename InnerCallback::Parm1 P1;
00464 typedef typename InnerCallback::Parm2 P2;
00465 typedef typename InnerCallback::Parm3 P3;
00466 typedef typename InnerCallback::Parm4 P4;
00467 typedef typename InnerCallback::Parm5 P5;
00468 typedef typename InnerCallback::Parm6 P6;
00469 typedef typename InnerCallback::Parm7 P7;
00470 typedef WvCallback<R, B, P1, P2, P3, P4, P5, P6, P7> ComposedCallback;
00471 ComposedCallback cb;
00472 B param;
00473 public:
00474 typedef typename ComposedCallback::FrozenParams FrozenParams;
00475 template<typename PtrToObject, typename PtrToMember>
00476 WvBoundCallback(PtrToObject obj, PtrToMember member, B _param)
00477 : cb(ComposedCallback(obj, member)),
00478 param(_param)
00479 { }
00480 template<typename Functor>
00481 WvBoundCallback(const Functor& func, B _param)
00482 : cb(ComposedCallback(func)),
00483 param(_param)
00484 { }
00485 R operator()() const
00486 { return cb(param); }
00487 R operator()(P1 p1) const
00488 { return cb(param, p1); }
00489 R operator()(P1 p1, P2 p2) const
00490 { return cb(param, p1, p2); }
00491 R operator()(P1 p1, P2 p2, P3 p3) const
00492 { return cb(param, p1, p2, p3); }
00493 R operator()(P1 p1, P2 p2, P3 p3, P4 p4) const
00494 { return cb(param, p1, p2, p3, p4); }
00495 R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const
00496 { return cb(param, p1, p2, p3, p4, p5); }
00497 R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) const
00498 { return cb(param, p1, p2, p3, p4, p5, p6); }
00499 R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) const
00500 { return cb(param, p1, p2, p3, p4, p5, p6, p7); }
00501 R thaw(const FrozenParams &frozen) const
00502 { return cb.thaw(frozen); }
00503 };
00504
00505 #endif