00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __SMRTPTR_H__
00018 #define __SMRTPTR_H__
00019
00020 #include <string.h>
00021 #include <wx/general/a2dlist.h>
00022
00023
00024
00025 #define __A2DONLYFILE__(fname) (strchr(fname,'\\') ? strrchr(fname,'\\')+1 : fname)
00026 #define __A2DFILE__ __A2DONLYFILE__(__FILE__)
00027
00028
00029 #if defined(_DEBUG) && defined (SMART_POINTER_DEBUG)
00030
00031
00032
00033
00034
00035
00036
00037 A2DGENERALDLLEXP_DATA (extern wxObject *) CurrentSmartPointerOwner;
00038
00039 struct A2DGENERALDLLEXP a2dInitCurrentSmartPointerOwner
00040 {
00041 public:
00042 a2dInitCurrentSmartPointerOwner(wxObject* object)
00043 {
00044 CurrentSmartPointerOwner = object;
00045 }
00046 };
00047 #endif
00048
00049
00050
00051
00052
00053
00054
00055 class A2DGENERALDLLEXP a2dSmrtPtrBase
00056 {
00057 protected:
00058 a2dSmrtPtrBase() {}
00059 private:
00060 a2dSmrtPtrBase( const a2dSmrtPtrBase& );
00061 a2dSmrtPtrBase & operator=( const a2dSmrtPtrBase& );
00062 protected:
00063 template<class T> static void OwnRef( T* pRefObject ) { if( pRefObject ) pRefObject->SmrtPtrOwn(); }
00064 template<class T> static void ReleaseRef( T* pRefObject ) { if( pRefObject ) pRefObject->SmrtPtrRelease(); }
00065 };
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 template<class Clss>
00114 class a2dSmrtPtr : private a2dSmrtPtrBase
00115 {
00116 public:
00117 typedef Clss TType;
00118
00119 a2dSmrtPtr()
00120 {
00121 m_ptr = NULL;
00122 PointerListInit();
00123 }
00124
00125 a2dSmrtPtr( Clss* objc )
00126 {
00127 PointerListInit();
00128 m_ptr = objc;
00129 AddToPointerList();
00130 OwnRef(m_ptr);
00131 }
00132
00133 a2dSmrtPtr( const a2dSmrtPtr &objc )
00134 {
00135 PointerListInit();
00136 m_ptr = &*objc;
00137 AddToPointerList();
00138 OwnRef(m_ptr);
00139 }
00140
00141 ~a2dSmrtPtr()
00142 {
00143
00144
00145 Clss *old = m_ptr;
00146 RmvFromPointerList();
00147 m_ptr = 0;
00148 ReleaseRef(old);
00149 }
00150
00151 void operator=( const a2dSmrtPtr &objc )
00152 {
00153 Clss *ptrold = m_ptr;
00154 RmvFromPointerList();
00155 m_ptr = &*objc;
00156 AddToPointerList();
00157 OwnRef(m_ptr);
00158 ReleaseRef(ptrold);
00159 }
00160
00161 void operator=( Clss *objc )
00162 {
00163 Clss *ptrold = m_ptr;
00164 RmvFromPointerList();
00165 m_ptr = objc;
00166 AddToPointerList();
00167 OwnRef(m_ptr);
00168 ReleaseRef(ptrold);
00169 }
00170
00171 friend inline bool operator==(const a2dSmrtPtr &a, const a2dSmrtPtr &b)
00172 {
00173 return a.m_ptr == b.m_ptr;
00174 }
00175
00176 friend inline bool operator!=(const a2dSmrtPtr &a, const a2dSmrtPtr &b)
00177 {
00178 return a.m_ptr != b.m_ptr;
00179 }
00180
00181
00182
00183 friend inline bool operator==(const a2dSmrtPtr &a, const Clss *b)
00184 {
00185 return a.m_ptr == b;
00186 }
00187
00188 friend inline bool operator!=(const a2dSmrtPtr &a, const Clss *b)
00189 {
00190 return a.m_ptr != b;
00191 }
00192
00193 friend inline bool operator==(const Clss *a, const a2dSmrtPtr &b)
00194 {
00195 return a == b.m_ptr;
00196 }
00197
00198 friend inline bool operator!=(const Clss *a, const a2dSmrtPtr &b)
00199 {
00200 return a != b.m_ptr;
00201 }
00202
00203 friend inline bool operator==(const a2dSmrtPtr &a, Clss *b)
00204 {
00205 return a.m_ptr == b;
00206 }
00207
00208 friend inline bool operator!=(const a2dSmrtPtr &a, Clss *b)
00209 {
00210 return a.m_ptr != b;
00211 }
00212
00213 friend inline bool operator==( Clss *a, const a2dSmrtPtr &b)
00214 {
00215 return a == b.m_ptr;
00216 }
00217
00218 friend inline bool operator!=( Clss *a, const a2dSmrtPtr &b)
00219 {
00220 return a != b.m_ptr;
00221 }
00222
00223 inline operator Clss* () const { return m_ptr; }
00224
00225 inline Clss *Get() const
00226 {
00227 return m_ptr;
00228 }
00229
00230 inline Clss *operator->() const { return m_ptr; }
00231
00232 inline Clss &operator*() const { return *m_ptr; }
00233
00234 private:
00235 Clss* m_ptr;
00236
00237 public:
00238
00239 #if defined(_DEBUG) && defined (SMART_POINTER_DEBUG)
00240 a2dSmrtPtr(const wxChar* filename, int linenum)
00241 {
00242 m_ptr = NULL;
00243 PointerListInit();
00244 m_filename = filename;
00245 m_linenum = linenum;
00246 }
00247 a2dSmrtPtr(const wxChar* filename, int linenum, Clss* objc )
00248 {
00249 PointerListInit();
00250 m_filename = filename;
00251 m_linenum = linenum;
00252 m_ptr = objc;
00253 AddToPointerList();
00254 OwnRef(m_ptr);
00255 }
00256 a2dSmrtPtr(const wxChar* filename, int linenum, const a2dSmrtPtr &objc )
00257 {
00258 PointerListInit();
00259 m_filename = filename;
00260 m_linenum = linenum;
00261 m_ptr = &*objc;
00262 AddToPointerList();
00263 OwnRef(m_ptr);
00264 }
00265
00266
00267
00268 a2dSmrtPtr<Clss> *m_next;
00269 a2dSmrtPtr<Clss> *m_prvs;
00270 wxObject *m_owner;
00271 const wxChar* m_filename;
00272 int m_linenum;
00273 enum
00274 {
00275 owner_none,
00276 owner_wxobject,
00277 owner_smartpointerlist
00278 } m_ownertype;
00279
00280 void PointerListInit()
00281 {
00282
00283
00284 m_next = 0;
00285 m_prvs = 0;
00286 m_filename = 0;
00287 m_linenum = 0;
00288
00289 if( (char*)this - (char*)CurrentSmartPointerOwner < 1024 )
00290 {
00291 m_owner = CurrentSmartPointerOwner;
00292 m_ownertype = owner_wxobject;
00293 }
00294 else
00295 {
00296 m_owner = 0;
00297 m_ownertype = owner_none;
00298 }
00299 }
00300
00301 void AddToPointerList()
00302 {
00303 if( !m_ptr) return;
00304 m_next = (a2dSmrtPtr<Clss>*) m_ptr->m_ownerlist;
00305 if( m_next )
00306 m_next->m_prvs = this;
00307 m_prvs = 0;
00308 m_ptr->m_ownerlist = (typename Clss::TOwnerListClass *) this;
00309 }
00310
00311 void RmvFromPointerList()
00312 {
00313 if( !m_ptr) return;
00314 if( m_prvs )
00315 m_prvs->m_next = m_next;
00316 else
00317 m_ptr->m_ownerlist = (typename Clss::TOwnerListClass *) m_next;
00318 if( m_next )
00319 m_next->m_prvs = m_prvs;
00320 }
00321 #else
00322 void PointerListInit() {}
00323 void AddToPointerList() {}
00324 void RmvFromPointerList() {}
00325 #endif
00326 };
00327
00328 #if defined(_DEBUG) && defined (SMART_POINTER_DEBUG)
00329 #define a2dDECLARE_GLOBAL_VAR(type, var) type var(__FILE__,__LINE__)
00330 #define a2dDECLARE_GLOBAL_ITEM(type, var, item) type var(__FILE__,__LINE__,item)
00331 #define a2dDECLARE_LOCAL_ITEM(type, var, item) CurrentSmartPointerOwner = this;\
00332 type var(__FILE__,__LINE__,item)
00333 #else
00334 #define a2dDECLARE_GLOBAL_VAR(type, var) type var
00335 #define a2dDECLARE_GLOBAL_ITEM(type, var, item) type var(item)
00336 #define a2dDECLARE_LOCAL_ITEM(type, var, item) type var(item)
00337 #endif
00338
00339
00340
00341
00342
00343
00344
00345
00346 template<class Clss>
00347 class a2dAutoZeroPtr
00348 {
00349 public:
00350 typedef Clss TType;
00351
00352 a2dAutoZeroPtr()
00353 {
00354 m_ptr = NULL;
00355 PointerListInit();
00356 }
00357
00358 a2dAutoZeroPtr( Clss* objc )
00359 {
00360 PointerListInit();
00361 m_ptr = objc;
00362 AddToPointerList();
00363 }
00364
00365 a2dAutoZeroPtr( const a2dAutoZeroPtr &objc )
00366 {
00367 PointerListInit();
00368 m_ptr = &*objc;
00369 AddToPointerList();
00370 }
00371
00372 ~a2dAutoZeroPtr()
00373 {
00374 RmvFromPointerList();
00375 }
00376
00377
00378
00379 void TargetDestructing()
00380 {
00381 a2dAutoZeroPtr<Clss> *next, *crnt;
00382 for( crnt = this; crnt; crnt = next )
00383 {
00384 next = crnt->m_next;
00385 crnt->m_ptr = 0;
00386 crnt->m_next = 0;
00387 crnt->m_prvs = 0;
00388 }
00389 }
00390
00391 void operator=( const a2dAutoZeroPtr &objc )
00392 {
00393 RmvFromPointerList();
00394 m_ptr = &*objc;
00395 AddToPointerList();
00396 }
00397
00398 void operator=( Clss *objc )
00399 {
00400 RmvFromPointerList();
00401 m_ptr = objc;
00402 AddToPointerList();
00403 }
00404
00405 friend inline bool operator==(const a2dAutoZeroPtr &a, const a2dAutoZeroPtr &b)
00406 {
00407 return a.m_ptr == b.m_ptr;
00408 }
00409
00410 friend inline bool operator!=(const a2dAutoZeroPtr &a, const a2dAutoZeroPtr &b)
00411 {
00412 return a.m_ptr != b.m_ptr;
00413 }
00414
00415
00416
00417 friend inline bool operator==(const a2dAutoZeroPtr &a, const Clss *b)
00418 {
00419 return a.m_ptr == b;
00420 }
00421
00422 friend inline bool operator!=(const a2dAutoZeroPtr &a, const Clss *b)
00423 {
00424 return a.m_ptr != b;
00425 }
00426
00427 friend inline bool operator==(const Clss *a, const a2dAutoZeroPtr &b)
00428 {
00429 return a == b.m_ptr;
00430 }
00431
00432 friend inline bool operator!=(const Clss *a, const a2dAutoZeroPtr &b)
00433 {
00434 return a != b.m_ptr;
00435 }
00436
00437 friend inline bool operator==(const a2dAutoZeroPtr &a, Clss *b)
00438 {
00439 return a.m_ptr == b;
00440 }
00441
00442 friend inline bool operator!=(const a2dAutoZeroPtr &a, Clss *b)
00443 {
00444 return a.m_ptr != b;
00445 }
00446
00447 friend inline bool operator==( Clss *a, const a2dAutoZeroPtr &b)
00448 {
00449 return a == b.m_ptr;
00450 }
00451
00452 friend inline bool operator!=( Clss *a, const a2dAutoZeroPtr &b)
00453 {
00454 return a != b.m_ptr;
00455 }
00456
00457 inline operator Clss* () const { return m_ptr; }
00458
00459 inline Clss *Get() const
00460 {
00461 return m_ptr;
00462 }
00463
00464 inline Clss *operator->() const { return m_ptr; }
00465
00466 inline Clss &operator*() const { return *m_ptr; }
00467
00468 private:
00469
00470 void PointerListInit()
00471 {
00472 m_next = 0;
00473 m_prvs = 0;
00474
00475 }
00476
00477 void AddToPointerList()
00478 {
00479 if( !m_ptr) return;
00480 a2dAutoZeroPtr<Clss> **ownerlist = (a2dAutoZeroPtr<Clss>**) m_ptr->GetAutoZeroPtrList();
00481 m_next = *ownerlist;
00482 if( m_next )
00483 m_next->m_prvs = this;
00484 m_prvs = 0;
00485 *ownerlist = (a2dAutoZeroPtr<Clss>*) this;
00486 }
00487
00488 void RmvFromPointerList()
00489 {
00490 if( !m_ptr) return;
00491 if( m_prvs )
00492 {
00493 m_prvs->m_next = m_next;
00494 }
00495 else
00496 {
00497 a2dAutoZeroPtr<Clss> **ownerlist = (a2dAutoZeroPtr<Clss>**) m_ptr->GetAutoZeroPtrList();
00498 *ownerlist = (a2dAutoZeroPtr<Clss>*) m_next;
00499 }
00500 if( m_next )
00501 m_next->m_prvs = m_prvs;
00502 }
00503
00504 private:
00505 Clss* m_ptr;
00506
00507
00508
00509 a2dAutoZeroPtr<Clss> *m_next;
00510 a2dAutoZeroPtr<Clss> *m_prvs;
00511 };
00512
00513
00514
00515
00516
00517 template<class Clss>
00518 class a2dDumbPtr
00519 {
00520 public:
00521 typedef Clss TType;
00522
00523 a2dDumbPtr()
00524 {
00525 m_ptr = NULL;
00526 }
00527
00528 a2dDumbPtr( Clss* objc )
00529 {
00530 m_ptr = objc;
00531 }
00532
00533 a2dDumbPtr( const a2dDumbPtr &objc )
00534 {
00535 m_ptr = &*objc;
00536 }
00537
00538 void operator=( const a2dDumbPtr &objc )
00539 {
00540 m_ptr = &*objc;
00541 }
00542
00543 inline int operator==(const a2dDumbPtr &objc) const
00544 {
00545 return objc.m_ptr == m_ptr;
00546 }
00547
00548 inline int operator!=(const a2dDumbPtr &objc) const
00549 {
00550 return objc.m_ptr != m_ptr;
00551 }
00552
00553 inline operator Clss* () const { return m_ptr; }
00554
00555 ~a2dDumbPtr()
00556 {
00557 }
00558
00559 inline Clss *Get() const
00560 {
00561 return m_ptr;
00562 }
00563
00564 inline Clss *operator->() const { return m_ptr; }
00565
00566 inline Clss &operator*() const { return *m_ptr; }
00567
00568 private:
00569 Clss* m_ptr;
00570 };
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581 template<class T>
00582 class a2dSmrtPtrList: public a2dlist< a2dSmrtPtr< T > >
00583 {
00584
00585 public:
00586
00587 typedef typename a2dlist< a2dSmrtPtr< T > >::iterator itSmart;
00588 typedef typename a2dlist< a2dSmrtPtr< T > >::const_iterator const_itSmart;
00589
00590
00591 itSmart Find( T *object );
00592
00593
00594 const_itSmart Find( T *object ) const;
00595
00596
00597 int IndexOf(T *object) const;
00598
00599
00600 bool ReleaseObject( T *object );
00601
00602 };
00603
00604 #if defined(WXDOCVIEW_USINGDLL)
00605 #include "wx/general/smrtptr.inl"
00606 #endif
00607
00608 #endif // __SMRTPTR_H__