00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef FXROLLBACK_H
00023 #define FXROLLBACK_H
00024
00025 #include "fxdefs.h"
00026
00027 namespace FX {
00028
00029 class QMutex;
00030
00156 class FXAPI FXRollbackBase
00157 {
00158 friend class FXRollbackGroup;
00159 protected:
00160 mutable bool dismissed;
00161 typedef void (FXRollbackBase::*calladdrtype)();
00162 calladdrtype calladdr;
00163 mutable QMutex *mutex;
00164 virtual FXRollbackBase *copy() const=0;
00165 public:
00166 FXRollbackBase(calladdrtype addr) : dismissed(false), calladdr(addr), mutex(0) { }
00167 ~FXRollbackBase() { if(!dismissed) makeCall(); }
00168 FXRollbackBase(const FXRollbackBase &o) : dismissed(o.dismissed), calladdr(o.calladdr), mutex(o.mutex) { o.dismiss(); }
00170 void dismiss() const throw() { dismissed=true; }
00172 void setMutex(QMutex *m) const throw() { mutex=m; }
00174 void setMutex(QMutex &m) const throw() { mutex=&m; }
00175 private:
00176 void makeCall();
00177
00178
00179 FXRollbackBase &operator=(const FXRollbackBase &);
00180 };
00181 typedef const FXRollbackBase &FXRBOp;
00186 class FXRollbackGroup
00187 {
00188 void *list;
00189 public:
00190 FXRollbackGroup();
00191 ~FXRollbackGroup();
00193 void add(FXRollbackBase &item);
00195 void dismiss() const throw();
00196 };
00197
00198 template<typename par1> class FXRBNewI : public FXRollbackBase
00199 {
00200 par1 &mypar1;
00201 void call() { delete mypar1; mypar1=0; }
00202 virtual FXRollbackBase *copy() const { return new FXRBNewI<par1>(*this); }
00203 public:
00204 FXRBNewI(par1 &_par1) : mypar1(_par1), FXRollbackBase((calladdrtype) &FXRBNewI<par1>::call) { }
00205 };
00206 template<typename par1> FXRBNewI<par1> FXRBNew(par1 &_par1)
00207 {
00208 return FXRBNewI<par1>(_par1);
00209 }
00210
00211 template<typename par1> class FXRBNewAI : public FXRollbackBase
00212 {
00213 par1 &mypar1;
00214 void call() { delete[] mypar1; mypar1=0; }
00215 virtual FXRollbackBase *copy() const { return new FXRBNewAI<par1>(*this); }
00216 public:
00217 FXRBNewAI(par1 &_par1) : mypar1(_par1), FXRollbackBase((calladdrtype) &FXRBNewAI<par1>::call) { }
00218 };
00219 template<typename par1> FXRBNewAI<par1> FXRBNewA(par1 &_par1)
00220 {
00221 return FXRBNewAI<par1>(_par1);
00222 }
00223
00224 template<typename par1> class FXRBAllocI : public FXRollbackBase
00225 {
00226 par1 &mypar1;
00227 void call() { if(mypar1) free(mypar1); mypar1=0; }
00228 virtual FXRollbackBase *copy() const { return new FXRBAllocI<par1>(*this); }
00229 public:
00230 FXRBAllocI(par1 &_par1) : mypar1(_par1), FXRollbackBase((calladdrtype)&FXRBAllocI<par1>::call) { }
00231 };
00232 template<typename par1> FXRBAllocI<par1> FXRBAlloc(par1 &_par1)
00233 {
00234 return FXRBAllocI<par1>(_par1);
00235 }
00236
00237 template<class type> class FXRBConstructI : public FXRollbackBase
00238 {
00239 type *obj;
00240 class RedirDelete : public type
00241 {
00242 public:
00243 RedirDelete() { }
00244 void operator delete(void *) throw() { }
00245 };
00246 void call()
00247 {
00248 RedirDelete *_obj=static_cast<RedirDelete *>(obj);
00249 delete _obj;
00250 }
00251 virtual FXRollbackBase *copy() const { return new FXRBConstructI<type>(*this); }
00252 public:
00253 FXRBConstructI(type *_obj) : obj(_obj), FXRollbackBase((calladdrtype) &FXRBConstructI<type>::call) { }
00254 };
00255 template<class type> FXRBConstructI<type> FXRBConstruct(type *obj)
00256 {
00257 return FXRBConstructI<type>(obj);
00258 }
00259
00260 #ifdef DOXYGEN_SHOULD_SKIP_THIS
00261
00264 FXRollbackOp FXRBFunc(function, [, par1 & [, par2 & [, par3 & [, par4 &]]]]);
00268 FXRollbackOp FXRBObj(object, ptrtomethod, [, par1 & [, par2 & [, par3 & [, par4 &]]]]);
00273 FXRollbackOp FXRBNew(ptrtonewedalloc &);
00278 FXRollbackOp FXRBNewA(ptrtonewedalloc &);
00283 FXRollbackOp FXRBAlloc(ptrtomem);
00287 FXRollbackOp FXRBConstruct(thisptr);
00288 #else
00289
00290 template<typename func> class FXRBFuncI0 : public FXRollbackBase
00291 {
00292 func myfunc;
00293 void call() { if(myfunc) (*myfunc)(); }
00294 virtual FXRollbackBase *copy() const { return new FXRBFuncI0<func>(*this); }
00295 public:
00296 FXRBFuncI0(func _myfunc) : myfunc(_myfunc), FXRollbackBase((calladdrtype) &FXRBFuncI0<func>::call) { }
00297 };
00298 template<typename func> FXRBFuncI0<func> FXRBFunc(func _func)
00299 {
00300 return FXRBFuncI0<func>(_func);
00301 }
00302
00303 template<typename func, typename par1> class FXRBFuncI1 : public FXRollbackBase
00304 {
00305 func myfunc;
00306 const par1 &mypar1;
00307 void call() { if(myfunc) myfunc(mypar1); }
00308 virtual FXRollbackBase *copy() const { return new FXRBFuncI1<func, par1>(*this); }
00309 public:
00310 FXRBFuncI1(func _myfunc, const par1 &_par1) : myfunc(_myfunc), mypar1(_par1), FXRollbackBase((calladdrtype) &FXRBFuncI1<func, par1>::call) { }
00311 };
00312 template<typename func, typename par1> FXRBFuncI1<func, par1> FXRBFunc(func _func, const par1 &_par1)
00313 {
00314 return FXRBFuncI1<func, par1>(_func, _par1);
00315 }
00316
00317 template<typename func, typename par1, typename par2> class FXRBFuncI2 : public FXRollbackBase
00318 {
00319 func myfunc;
00320 const par1 &mypar1;
00321 const par2 &mypar2;
00322 void call() { if(myfunc) myfunc(mypar1, mypar2); }
00323 virtual FXRollbackBase *copy() const { return new FXRBFuncI2<func, par1, par2>(*this); }
00324 public:
00325 FXRBFuncI2(func _myfunc, const par1 &_par1, const par2 &_par2) : myfunc(_myfunc), mypar1(_par1), mypar2(_par2), FXRollbackBase((calladdrtype) &FXRBFuncI2<func, par1, par2>::call) { }
00326 };
00327 template<typename func, typename par1, typename par2> FXRBFuncI2<func, par1, par2> FXRBFunc(func _func, const par1 &_par1, const par2 &_par2)
00328 {
00329 return FXRBFuncI2<func, par1, par2>(_func, _par1, _par2);
00330 }
00331
00332 template<typename func, typename par1, typename par2, typename par3> class FXRBFuncI3 : public FXRollbackBase
00333 {
00334 func myfunc;
00335 const par1 &mypar1;
00336 const par2 &mypar2;
00337 const par3 &mypar3;
00338 void call() { if(myfunc) myfunc(mypar1, mypar2, mypar3); }
00339 virtual FXRollbackBase *copy() const { return new FXRBFuncI3<func, par1, par2, par3>(*this); }
00340 public:
00341 FXRBFuncI3(func _myfunc, const par1 &_par1, const par2 &_par2, const par3 &_par3)
00342 : myfunc(_myfunc), mypar1(_par1), mypar2(_par2), mypar3(_par3), FXRollbackBase((calladdrtype) &FXRBFuncI3<func, par1, par2, par3>::call) { }
00343 };
00344 template<typename func, typename par1, typename par2, typename par3> FXRBFuncI3<func, par1, par2, par3> FXRBFunc(func _func, const par1 &_par1, const par2 &_par2, const par3 &_par3)
00345 {
00346 return FXRBFuncI3<func, par1, par2, par3>(_func, _par1, _par2, _par3);
00347 }
00348
00349 template<typename func, typename par1, typename par2, typename par3, typename par4> class FXRBFuncI4 : public FXRollbackBase
00350 {
00351 func myfunc;
00352 const par1 &mypar1;
00353 const par2 &mypar2;
00354 const par3 &mypar3;
00355 const par4 &mypar4;
00356 void call() { if(myfunc) myfunc(mypar1, mypar2, mypar3, mypar4); }
00357 virtual FXRollbackBase *copy() const { return new FXRBFuncI4<func, par1, par2, par3, par4>(*this); }
00358 public:
00359 FXRBFuncI4(func _myfunc, const par1 &_par1, const par2 &_par2, const par3 &_par3, const par4 &_par4)
00360 : myfunc(_myfunc), mypar1(_par1), mypar2(_par2), mypar3(_par3), mypar4(_par4), FXRollbackBase((calladdrtype) &FXRBFuncI4<func, par1, par2, par3, par4>::call) { }
00361 };
00362 template<typename func, typename par1, typename par2, typename par3, typename par4> FXRBFuncI4<func, par1, par2, par3, par4> FXRBFunc(func _func, const par1 &_par1, const par2 &_par2, const par3 &_par3, const par4 &_par4)
00363 {
00364 return FXRBFuncI4<func, par1, par2, par3, par4>(_func, _par1, _par2, _par3, _par4);
00365 }
00366
00367
00368 template<class obj, typename method> class FXRBObjI0 : public FXRollbackBase
00369 {
00370 obj &myobj;
00371 method mymethod;
00372 void call() { if(mymethod) (myobj.*mymethod)(); }
00373 virtual FXRollbackBase *copy() const { return new FXRBObjI0<obj, method>(*this); }
00374 public:
00375 FXRBObjI0(obj &_myobj, method _mymethod)
00376 : myobj(_myobj), mymethod(_mymethod), FXRollbackBase((calladdrtype) &FXRBObjI0<obj, method>::call) { }
00377 };
00378 template<class obj, typename method> FXRBObjI0<obj, method> FXRBObj(obj &_obj, method _method)
00379 {
00380 return FXRBObjI0<obj, method>(_obj, _method);
00381 }
00382
00383 template<class obj, typename method, typename par1> class FXRBObjI1 : public FXRollbackBase
00384 {
00385 obj &myobj;
00386 method mymethod;
00387 const par1 &mypar1;
00388 void call() { if(mymethod) (myobj.*mymethod)(mypar1); }
00389 virtual FXRollbackBase *copy() const { return new FXRBObjI1<obj, method, par1>(*this); }
00390 public:
00391 FXRBObjI1(obj &_myobj, method _mymethod, const par1 &_mypar1)
00392 : myobj(_myobj), mymethod(_mymethod), mypar1(_mypar1), FXRollbackBase((calladdrtype) &FXRBObjI1<obj, method, par1>::call) { }
00393 };
00394 template<class obj, typename method, typename par1> FXRBObjI1<obj, method, par1> FXRBObj(obj &_obj, method _method, const par1 &_par1)
00395 {
00396 return FXRBObjI1<obj, method, par1>(_obj, _method, _par1);
00397 }
00398
00399 template<class obj, typename method, typename par1, typename par2> class FXRBObjI2 : public FXRollbackBase
00400 {
00401 obj &myobj;
00402 method mymethod;
00403 const par1 &mypar1;
00404 const par2 &mypar2;
00405 void call() { if(mymethod) (myobj.*mymethod)(mypar1, mypar2); }
00406 virtual FXRollbackBase *copy() const { return new FXRBObjI2<obj, method, par1, par2>(*this); }
00407 public:
00408 FXRBObjI2(obj &_myobj, method _mymethod, const par1 &_mypar1, const par2 &_mypar2)
00409 : myobj(_myobj), mymethod(_mymethod), mypar1(_mypar1), mypar2(_mypar2), FXRollbackBase((calladdrtype) &FXRBObjI2<obj, method, par1, par2>::call) { }
00410 };
00411 template<class obj, typename method, typename par1, typename par2> FXRBObjI2<obj, method, par1, par2> FXRBObj(obj &_obj, method _method, const par1 &_par1, const par2 &_par2)
00412 {
00413 return FXRBObjI2<obj, method, par1, par2>(_obj, _method, _par1, _par2);
00414 }
00415
00416 template<class obj, typename method, typename par1, typename par2, typename par3> class FXRBObjI3 : public FXRollbackBase
00417 {
00418 obj &myobj;
00419 method mymethod;
00420 const par1 &mypar1;
00421 const par2 &mypar2;
00422 const par3 &mypar3;
00423 void call() { if(mymethod) (myobj.*mymethod)(mypar1, mypar2, mypar3); }
00424 virtual FXRollbackBase *copy() const { return new FXRBObjI3<obj, method, par1, par2, par3>(*this); }
00425 public:
00426 FXRBObjI3(obj &_myobj, method _mymethod, const par1 &_mypar1, const par2 &_mypar2, const par3 &_mypar3)
00427 : myobj(_myobj), mymethod(_mymethod), mypar1(_mypar1), mypar2(_mypar2), mypar3(_mypar3), FXRollbackBase((calladdrtype) &FXRBObjI3<obj, method, par1, par2, par3>::call) { }
00428 };
00429 template<class obj, typename method, typename par1, typename par2, typename par3> FXRBObjI3<obj, method, par1, par2, par3> FXRBObj(obj &_obj, method _method, const par1 &_par1, const par2 &_par2, const par3 &_par3)
00430 {
00431 return FXRBObjI3<obj, method, par1, par2, par3>(_obj, _method, _par1, _par2, _par3);
00432 }
00433
00434 template<class obj, typename method, typename par1, typename par2, typename par3, typename par4> class FXRBObjI4 : public FXRollbackBase
00435 {
00436 obj &myobj;
00437 method mymethod;
00438 const par1 &mypar1;
00439 const par2 &mypar2;
00440 const par3 &mypar3;
00441 const par4 &mypar4;
00442 void call() { if(mymethod) (myobj.*mymethod)(mypar1, mypar2, mypar3, mypar4); }
00443 virtual FXRollbackBase *copy() const { return new FXRBObjI4<obj, method, par1, par2, par3, par4>(*this); }
00444 public:
00445 FXRBObjI4(obj &_myobj, method _mymethod, const par1 &_mypar1, const par2 &_mypar2, const par3 &_mypar3, const par4 &_mypar4)
00446 : myobj(_myobj), mymethod(_mymethod), mypar1(_mypar1), mypar2(_mypar2), mypar3(_mypar3), mypar4(_mypar4), FXRollbackBase((calladdrtype) &FXRBObjI4<obj, method, par1, par2, par3, par4>::call) { }
00447 };
00448 template<class obj, typename method, typename par1, typename par2, typename par3, typename par4> FXRBObjI4<obj, method, par1, par2, par3, par4> FXRBObj(obj &_obj, method _method, const par1 &_par1, const par2 &_par2, const par3 &_par3, const par4 &_par4)
00449 {
00450 return FXRBObjI4<obj, method, par1, par2, par3, par4>(_obj, _method, _par1, _par2, _par3, _par4);
00451 }
00452 #endif
00453
00454 }
00455
00456 #endif