00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef _SUPPORT_ATOM_H
00014 #define _SUPPORT_ATOM_H
00015
00023 #include <support/SupportDefs.h>
00024 #include <new>
00025 #include <typeinfo>
00026
00027 #if _SUPPORTS_NAMESPACE || _REQUIRES_NAMESPACE
00028 namespace std {
00029 #endif
00030 struct nothrow_t;
00031 #if _SUPPORTS_NAMESPACE || _REQUIRES_NAMESPACE
00032 }
00033 #endif
00034
00035 #if _SUPPORTS_NAMESPACE
00036 namespace palmos {
00037 namespace osp {
00038 #endif
00039 struct atom_debug;
00040 #if _SUPPORTS_NAMESPACE
00041 } }
00042 #endif
00043
00044 #if _SUPPORTS_NAMESPACE
00045 namespace palmos {
00046 namespace support {
00047 #endif
00048
00055
00056 class ITextOutput;
00057 class SAtomTracker;
00058 template <class TYPE> class sptr;
00059 template <class TYPE> class wptr;
00060
00061 class SString;
00062 template <class TYPE> class SVector;
00063 template <class TYPE> class SSortedVector;
00064
00065
00066
00068 enum {
00069 B_ATOM_REPORT_FORCE_LONG = 0x0001,
00070 B_ATOM_REPORT_FORCE_SHORT = 0x0002,
00071 B_ATOM_REPORT_FORCE_SUMMARY = 0x0003,
00072 B_ATOM_REPORT_FORCE_MASK = 0x000f,
00073
00074 B_ATOM_REPORT_REMOVE_HEADER = 0x0010
00075 };
00076
00078 enum {
00079 B_ATOM_FIRST_STRONG = 0x0001,
00080 };
00081
00082 class SAtom;
00083 class SLightAtom;
00084
00086
00166 class SAtom
00167 {
00168 public:
00169
00174 void* operator new(size_t size);
00175 void operator delete(void* ptr, size_t size);
00176 void* operator new(size_t size, const B_SNS(std::)nothrow_t&) throw();
00178
00179 protected:
00180
00184
00186 SAtom();
00188 virtual ~SAtom();
00189
00191 virtual void InitAtom();
00192
00193 enum {
00194 FINISH_ATOM_ASYNC = 0x0001,
00195 };
00196
00198 virtual status_t FinishAtom(const void* id);
00199
00201 virtual status_t IncStrongAttempted(uint32_t flags, const void* id);
00202
00204 virtual status_t DeleteAtom(const void* id);
00205
00207
00208 public:
00209
00213
00215 int32_t IncStrong(const void* id) const;
00216
00218 int32_t DecStrong(const void* id) const;
00219
00221 void IncStrongFast() const;
00223 void DecStrongFast() const;
00224
00226
00234 struct weak_atom_ptr
00235 {
00237 void Increment(const void* id);
00239 void Decrement(const void* id);
00240
00241 int32_t ref_count;
00242 SAtom* atom;
00243 void* cookie;
00244 };
00245
00247 weak_atom_ptr* CreateWeak(const void* cookie) const;
00248
00250 int32_t IncWeak(const void* id) const;
00251
00253 int32_t DecWeak(const void* id) const;
00254
00256 void IncWeakFast() const;
00258 void DecWeakFast() const;
00259
00261 bool AttemptIncStrong(const void* id) const;
00263 bool AttemptIncStrongFast() const;
00264
00266 bool AttemptDecStrong(const void* id) const;
00267
00269 int32_t ForceIncStrong(const void* id) const;
00271 void ForceIncStrongFast() const;
00272
00274 bool AttemptIncWeak(const void* id) const;
00276 bool AttemptIncWeakFast() const;
00277
00279 status_t AttachAtom(SAtom* target);
00280
00282 inline int32_t Acquire(const void* id) const { return IncStrong(id); }
00284 inline int32_t Release(const void* id) const { return DecStrong(id); }
00286 inline int32_t IncRefs(const void* id) const { return IncWeak(id); }
00288 inline int32_t DecRefs(const void* id) const { return DecWeak(id); }
00290 inline bool AttemptAcquire(const void* id) const { return AttemptIncStrong(id); }
00292 inline bool AttemptRelease(const void* id) const { return AttemptDecStrong(id); }
00294 inline int32_t ForceAcquire(const void* id) const { return ForceIncStrong(id); }
00295
00297
00298
00303
00305 bool HasStrongPointers() const;
00306
00308 bool HasManyStrongPointers() const;
00309
00311 bool HasWeakPointers() const;
00312
00314 bool HasManyWeakPointers() const;
00315
00317
00318
00327
00329 void RenameOwnerID(const void* newID, const void* oldID) const;
00330
00332 static void MovePointersBefore(SAtom** newPtr, SAtom** oldPtr, size_t num = 1);
00333
00335 static void MovePointersAfter(SAtom** newPtr, SAtom** oldPtr, size_t num = 1);
00336
00338
00339
00347
00349 int32_t StrongCount() const;
00350
00352 int32_t WeakCount() const;
00353
00355 void Report(const sptr<ITextOutput>& io, uint32_t flags=0) const;
00356
00358 static int32_t MarkLeakReport();
00359
00361 static void LeakReport( const sptr<ITextOutput>& io, int32_t mark=0, int32_t last=-1,
00362 uint32_t flags=0);
00364 static void LeakReport( int32_t mark=0, int32_t last=-1,
00365 uint32_t flags=0);
00366
00368 static bool ExistsAndIncStrong(SAtom* atom);
00370 static bool ExistsAndIncWeak(SAtom* atom);
00371
00373 static void GetActiveTypeNames(SSortedVector<SString>* outNames);
00374
00376 static void GetAllWithTypeName( const char* typeName,
00377 SVector<wptr<SAtom> >* outAtoms = NULL,
00378 SVector<sptr<SLightAtom> >* outLightAtoms = NULL);
00379
00381 static void StartWatching(const B_SNS(std::) type_info* type);
00383 static void StopWatching(const B_SNS(std::) type_info* type);
00384
00386 size_t AtomObjectSize() const;
00387
00389
00390 private:
00391 friend class SAtomTracker;
00392 friend class SLightAtom;
00393 class AsyncDestructor;
00394 friend class AsyncDestructor;
00395
00396 SAtom(const SAtom&);
00397
00398 void destructor_impl();
00399 void delete_impl(size_t size);
00400
00401 bool attempt_inc_strong(const void* id, bool useid) const;
00402
00403
00404
00405
00406
00407
00408
00409 static void move_pointers(SAtom** newPtr, SAtom** oldPtr, size_t num);
00410
00411 void init_atom();
00412 void term_atom();
00413
00414 void lock_atom() const;
00415 void unlock_atom() const;
00416
00417 int32_t* strong_addr() const;
00418 int32_t* weak_addr() const;
00419
00420 int32_t strong_count() const;
00421 int32_t weak_count() const;
00422
00423 void watch_action(const char* description) const;
00424 void do_report(const sptr<class ITextOutput>& io, uint32_t flags) const;
00425
00426 void add_incstrong(const void* id, int32_t cnt) const;
00427 void add_decstrong(const void* id) const;
00428 void add_incweak(const void* id) const;
00429 void add_decweak(const void* id) const;
00430
00431 void add_incstrong_raw(const void* id, int32_t cnt) const;
00432 void add_decstrong_raw(const void* id) const;
00433 void add_incweak_raw(const void* id) const;
00434 void add_decweak_raw(const void* id) const;
00435
00436 void transfer_refs(SAtom* from);
00437
00438 void schedule_async_destructor(const void* id);
00439 void do_async_destructor(const void* id);
00440
00441 struct base_data;
00442 base_data* m_base;
00443 };
00444
00445
00446
00448
00462 class SLightAtom
00463 {
00464 protected:
00465
00469
00471 SLightAtom();
00473 virtual ~SLightAtom();
00474
00476 virtual void InitAtom();
00477
00479
00480 public:
00481
00485
00487 int32_t IncStrong(const void* id) const;
00488
00490 int32_t DecStrong(const void* id) const;
00491
00493 void IncStrongFast() const;
00495 void DecStrongFast() const;
00496
00498
00499
00504
00505 int32_t IncStrong(const void* id);
00506 int32_t DecStrong(const void* id);
00507 void IncStrongFast();
00508 void DecStrongFast();
00509 int32_t ConstCount() const;
00510
00512
00513
00522
00524 bool HasManyStrongPointers() const;
00525
00527 void RenameOwnerID(const void* newID, const void* oldID) const;
00528
00530 static void MovePointersBefore(SLightAtom** newPtr, SLightAtom** oldPtr, size_t num = 1);
00531
00533 static void MovePointersAfter(SLightAtom** newPtr, SLightAtom** oldPtr, size_t num = 1);
00534
00536
00537
00548
00550 int32_t StrongCount() const;
00551
00553 void Report(const sptr<ITextOutput>& io, uint32_t flags=0) const;
00554
00556 static bool ExistsAndIncStrong(SLightAtom* atom);
00557
00559
00560 private:
00561 friend class SAtomTracker;
00562
00563 SLightAtom(const SLightAtom&);
00564
00565
00566
00567 static void move_pointers(SLightAtom** newPtr, SLightAtom** oldPtr, size_t num);
00568
00569 void init_atom();
00570 void term_atom();
00571
00572 void lock_atom() const;
00573 void unlock_atom() const;
00574
00575 int32_t* strong_addr() const;
00576
00577 int32_t strong_count() const;
00578
00579 void watch_action(const char* description) const;
00580 void do_report(const sptr<class ITextOutput>& io, uint32_t flags) const;
00581
00582 void add_incstrong(const void* id, int32_t cnt) const;
00583 void add_decstrong(const void* id) const;
00584
00585 void add_incstrong_raw(const void* id, int32_t cnt) const;
00586 void add_decstrong_raw(const void* id) const;
00587
00588 union {
00589 mutable int32_t m_strongCount;
00590 mutable BNS(::palmos::osp::) atom_debug* m_debugPtr;
00591 };
00592
00593 mutable int32_t m_constCount;
00594 };
00595
00596
00597
00599
00613 template <class T>
00614 class SLimAtom
00615 {
00616 public:
00618 inline SLimAtom() : m_strongCount(0) { }
00619
00621 inline void IncStrongFast() const { SysAtomicInc32(&m_strongCount); }
00622
00624 inline void DecStrongFast() const { if (SysAtomicDec32(&m_strongCount) == 1) { delete static_cast<const T*>(this); } }
00625
00627 inline void IncStrong(const void *) const { IncStrongFast(); }
00628
00630 inline void DecStrong(const void *) const { DecStrongFast(); }
00631
00632 typedef T type;
00633 protected:
00634
00636 inline ~SLimAtom() { }
00637
00638 private:
00639 mutable volatile int32_t m_strongCount;
00640 };
00641
00642
00643
00644
00652 #if BUILD_TYPE == BUILD_TYPE_DEBUG
00653 #define B_INC_STRONG(atom, who) atom->IncStrong(who)
00654 #define B_ATTEMPT_INC_STRONG(atom, who) atom->AttemptIncStrong(who)
00655 #define B_FORCE_INC_STRONG(atom, who) atom->ForceIncStrong(who)
00656 #define B_DEC_STRONG(atom, who) atom->DecStrong(who)
00657 #define B_INC_WEAK(atom, who) atom->IncWeak(who)
00658 #define B_ATTEMPT_INC_WEAK(atom, who) atom->AttemptIncWeak(who)
00659 #define B_DEC_WEAK(atom, who) atom->DecWeak(who)
00660 #else
00661 #define B_INC_STRONG(atom, who) atom->IncStrongFast()
00662 #define B_ATTEMPT_INC_STRONG(atom, who) atom->AttemptIncStrongFast()
00663 #define B_FORCE_INC_STRONG(atom, who) atom->ForceIncStrongFast()
00664 #define B_DEC_STRONG(atom, who) atom->DecStrongFast()
00665 #define B_INC_WEAK(atom, who) atom->IncWeakFast()
00666 #define B_ATTEMPT_INC_WEAK(atom, who) atom->AttemptIncWeakFast()
00667 #define B_DEC_WEAK(atom, who) atom->DecWeakFast()
00668 #endif
00669
00670
00671
00672
00674
00683 template <class TYPE>
00684 class sptr
00685 {
00686 public:
00688 sptr();
00690 sptr(TYPE* p);
00691
00693 sptr<TYPE>& operator =(TYPE* p);
00694
00696 sptr(const sptr<TYPE>& p);
00698 sptr<TYPE>& operator =(const sptr<TYPE>& p);
00700 template <class NEWTYPE> sptr(const sptr<NEWTYPE>& p);
00702 template <class NEWTYPE> sptr<TYPE>& operator =(const sptr<NEWTYPE>& p);
00703
00705 ~sptr();
00706
00708 TYPE& operator *() const;
00710 TYPE* operator ->() const;
00711
00713
00715 TYPE* ptr() const;
00717
00718 TYPE* detach();
00720
00724 bool is_null() const;
00725
00727
00731 TYPE* edit();
00733 TYPE* edit(size_t size);
00734
00735
00736 #define COMPARE_FRIEND(op) \
00737 bool operator op (const TYPE* p2) const; \
00738 bool operator op (const sptr<TYPE>& p2) const; \
00739 bool operator op (const wptr<TYPE>& p2) const; \
00740
00741 COMPARE_FRIEND(==)
00742 COMPARE_FRIEND(!=)
00743 COMPARE_FRIEND(<=)
00744 COMPARE_FRIEND(<)
00745 COMPARE_FRIEND(>)
00746 COMPARE_FRIEND(>=)
00747
00748 #undef COMPARE_FRIEND
00749
00750 private:
00751 friend class wptr<TYPE>;
00752
00753
00754 sptr(SAtom::weak_atom_ptr* weak, bool);
00755
00756 TYPE *m_ptr;
00757 };
00758
00759
00760
00762
00768 template <class TYPE>
00769 class wptr
00770 {
00771 public:
00773 wptr();
00775 wptr(TYPE* p);
00776
00778 wptr<TYPE>& operator =(TYPE* p);
00779
00781 wptr(const wptr<TYPE>& p);
00783 wptr(const sptr<TYPE>& p);
00785 wptr<TYPE>& operator =(const wptr<TYPE>& p);
00787 wptr<TYPE>& operator =(const sptr<TYPE>& p);
00789 template <class NEWTYPE> wptr(const wptr<NEWTYPE>& p);
00791 template <class NEWTYPE> wptr(const sptr<NEWTYPE>& p);
00793 template <class NEWTYPE> wptr<TYPE>& operator =(const sptr<NEWTYPE>& p);
00795 template <class NEWTYPE> wptr<TYPE>& operator =(const wptr<NEWTYPE>& p);
00796
00798 ~wptr();
00799
00801
00805 TYPE* unsafe_ptr_access() const;
00806
00808
00809 const sptr<TYPE> promote() const;
00810
00811 #define COMPARE_FRIEND(op) \
00812 bool operator op (const TYPE* p2) const; \
00813 bool operator op (const sptr<TYPE>& p2) const; \
00814 bool operator op (const wptr<TYPE>& p2) const; \
00815
00816 COMPARE_FRIEND(==)
00817 COMPARE_FRIEND(!=)
00818 COMPARE_FRIEND(<=)
00819 COMPARE_FRIEND(<)
00820 COMPARE_FRIEND(>)
00821 COMPARE_FRIEND(>=)
00822
00823 #undef COMPARE_FRIEND
00824
00826
00832 void inc_weak(const void* id) const;
00834
00840 void dec_weak(const void* id) const;
00841
00843
00844 SAtom::weak_atom_ptr* get_weak_atom_ptr() const;
00846
00847 void set_weak_atom_ptr(SAtom::weak_atom_ptr* weak);
00848
00849 private:
00850 friend class sptr<TYPE>;
00851 SAtom::weak_atom_ptr* m_ptr;
00852 };
00853
00854
00855
00857 template <class FROM, class TO>
00858 class TypeConversion
00859 {
00860 static char Test(const TO&);
00861 static FROM* t;
00862 public:
00863 static void Assert() { (void)sizeof(Test(*t)); }
00864 };
00865
00866
00868 template<class NEWTYPE, class TYPE> inline
00869 sptr<NEWTYPE>&
00870 sptr_reinterpret_cast(const sptr<TYPE>& v)
00871 {
00872 return *(sptr<NEWTYPE> *)( &v );
00873 }
00874
00876 template<class NEWTYPE, class TYPE> inline
00877 wptr<NEWTYPE>&
00878 wptr_reinterpret_cast(const wptr<TYPE>& v)
00879 {
00880 return *(wptr<NEWTYPE> *)( &v );
00881 }
00882
00883
00884
00885
00886
00887 #define COMPARE(op) \
00888 template<class TYPE> inline \
00889 bool sptr<TYPE>::operator op (const TYPE* p2) const \
00890 { return ptr() op p2; } \
00891 template<class TYPE> inline \
00892 bool sptr<TYPE>::operator op (const sptr<TYPE>& p2) const \
00893 { return ptr() op p2.ptr(); } \
00894 template<class TYPE> inline \
00895 bool sptr<TYPE>::operator op (const wptr<TYPE>& p2) const \
00896 { return ptr() op p2.unsafe_ptr_access(); } \
00897 template<class TYPE> inline \
00898 bool wptr<TYPE>::operator op (const TYPE* p2) const \
00899 { return unsafe_ptr_access() op p2; } \
00900 template<class TYPE> inline \
00901 bool wptr<TYPE>::operator op (const sptr<TYPE>& p2) const \
00902 { return unsafe_ptr_access() op p2.ptr(); } \
00903 template<class TYPE> inline \
00904 bool wptr<TYPE>::operator op (const wptr<TYPE>& p2) const \
00905 { return unsafe_ptr_access() op p2.unsafe_ptr_access(); } \
00906
00907 COMPARE(==)
00908 COMPARE(!=)
00909 COMPARE(<=)
00910 COMPARE(<)
00911 COMPARE(>)
00912 COMPARE(>=)
00913
00914 #undef COMPARE
00915
00918
00919
00920
00921
00922
00923 template<class TYPE> inline
00924 sptr<TYPE>::sptr() { m_ptr = NULL; }
00925 template<class TYPE> inline
00926 sptr<TYPE>::sptr(TYPE* p) { if ((m_ptr=p) != NULL) B_INC_STRONG(p, this); }
00927
00928 template<class TYPE> inline
00929 sptr<TYPE>& sptr<TYPE>::operator =(TYPE* p)
00930 {
00931 if (p) B_INC_STRONG(p, this);
00932 if (m_ptr) B_DEC_STRONG(m_ptr, this);
00933 m_ptr = p;
00934 return *this;
00935 }
00936
00937 template<class TYPE> inline
00938 sptr<TYPE>::sptr(const sptr<TYPE>& p) { if ((m_ptr=p.m_ptr) != NULL) B_INC_STRONG(m_ptr, this); }
00939 template<class TYPE> inline
00940 sptr<TYPE>& sptr<TYPE>::operator =(const sptr<TYPE>& p)
00941 {
00942 if (p.ptr()) B_INC_STRONG(p, this);
00943 if (m_ptr) B_DEC_STRONG(m_ptr, this);
00944 m_ptr = p.ptr();
00945 return *this;
00946 }
00947 template<class TYPE> template<class NEWTYPE> inline
00948 sptr<TYPE>::sptr(const sptr<NEWTYPE>& p)
00949 {
00950 TypeConversion<NEWTYPE, TYPE>::Assert();
00951 if ((m_ptr=p.ptr()) != NULL) B_INC_STRONG(m_ptr, this);
00952 }
00953 template<class TYPE> template<class NEWTYPE> inline
00954 sptr<TYPE>& sptr<TYPE>::operator =(const sptr<NEWTYPE>& p)
00955 {
00956 TypeConversion<NEWTYPE, TYPE>::Assert();
00957 if (p.ptr()) B_INC_STRONG(p, this);
00958 if (m_ptr) B_DEC_STRONG(m_ptr, this);
00959 m_ptr = p.ptr();
00960 return *this;
00961 }
00962
00963 template<class TYPE> inline
00964 sptr<TYPE>::~sptr() { if (m_ptr) B_DEC_STRONG(m_ptr, this); }
00965
00966 template<class TYPE> inline
00967 sptr<TYPE>::sptr(SAtom::weak_atom_ptr* p, bool)
00968 {
00969 m_ptr = (p && B_ATTEMPT_INC_STRONG(p->atom, this)) ? reinterpret_cast<TYPE*>(p->cookie) : NULL;
00970
00971 }
00972
00973 template<class TYPE> inline
00974 TYPE & sptr<TYPE>::operator *() const { return *m_ptr; }
00975 template<class TYPE> inline
00976 TYPE * sptr<TYPE>::operator ->() const { return m_ptr; }
00977 template<class TYPE> inline
00978 TYPE * sptr<TYPE>::ptr() const { return m_ptr; }
00979 template<class TYPE> inline
00980 TYPE * sptr<TYPE>::detach() { TYPE* p = m_ptr; m_ptr = NULL; return p; }
00981 template<class TYPE> inline
00982 bool sptr<TYPE>::is_null() const { return m_ptr == NULL; }
00983
00984 template<class TYPE> inline
00985 TYPE * sptr<TYPE>::edit()
00986 {
00987 TYPE* p = m_ptr;
00988 if (p != NULL) {
00989 p = p->Edit();
00990 m_ptr = p;
00991 }
00992 return p;
00993 }
00994
00995 template<class TYPE> inline
00996 TYPE * sptr<TYPE>::edit(size_t size)
00997 {
00998 TYPE* p = m_ptr;
00999 if (p != NULL) {
01000 p = p->Edit(size);
01001 m_ptr = p;
01002 }
01003 return p;
01004 }
01005
01006
01007
01008 template<class TYPE> inline wptr<TYPE>::wptr()
01009 {
01010 m_ptr = NULL;
01011 }
01012
01013 template<class TYPE> inline wptr<TYPE>::wptr(TYPE* p)
01014 {
01015 if (p) {
01016 m_ptr = p->CreateWeak(p);
01017 if (m_ptr != NULL) m_ptr->Increment(this);
01018 } else m_ptr = NULL;
01019 }
01020
01021 template<class TYPE> inline wptr<TYPE>& wptr<TYPE>::operator =(TYPE *p)
01022 {
01023 SAtom::weak_atom_ptr* weak = NULL;
01024 if (p) {
01025 weak = p->CreateWeak(p);
01026 if (weak != NULL) weak->Increment(this);
01027 }
01028 if (m_ptr) m_ptr->Decrement(this);
01029 m_ptr = weak;
01030 return *this;
01031 }
01032
01033 template<class TYPE> inline SAtom::weak_atom_ptr* wptr<TYPE>::get_weak_atom_ptr() const
01034 {
01035 return m_ptr;
01036 }
01037
01038 template<class TYPE> inline void wptr<TYPE>::set_weak_atom_ptr(SAtom::weak_atom_ptr* weak)
01039 {
01040 weak->Increment(this);
01041 if (m_ptr != NULL) m_ptr->Decrement(this);
01042 m_ptr = weak;
01043 }
01044
01045 template<class TYPE> inline wptr<TYPE>::wptr(const wptr<TYPE>& p)
01046 {
01047 if ((m_ptr=p.m_ptr) != NULL) m_ptr->Increment(this);
01048 }
01049
01050 template<class TYPE> inline wptr<TYPE>::wptr(const sptr<TYPE>& p)
01051 {
01052 if (p.ptr()) {
01053 m_ptr = p->CreateWeak(p.ptr());
01054 if (m_ptr != NULL) m_ptr->Increment(this);
01055 } else m_ptr = NULL;
01056 }
01057
01058 template<class TYPE> inline wptr<TYPE>& wptr<TYPE>::operator =(const wptr<TYPE>& p)
01059 {
01060 if (p.m_ptr) p.m_ptr->Increment(this);
01061 if (m_ptr) m_ptr->Decrement(this);
01062 m_ptr = p.m_ptr;
01063 return *this;
01064 }
01065
01066 template<class TYPE> inline wptr<TYPE>& wptr<TYPE>::operator =(const sptr<TYPE>& p)
01067 {
01068 SAtom::weak_atom_ptr* weak = NULL;
01069 if (p.ptr()) {
01070 weak = p->CreateWeak(p.ptr());
01071 if (weak != NULL) weak->Increment(this);
01072 }
01073 if (m_ptr) m_ptr->Decrement(this);
01074 m_ptr = weak;
01075 return *this;
01076 }
01077
01078 template<class TYPE> template<class NEWTYPE> inline
01079 wptr<TYPE>::wptr(const wptr<NEWTYPE>& p)
01080 {
01081 TypeConversion<NEWTYPE, TYPE>::Assert();
01082 if (p.m_ptr)
01083 {
01084 m_ptr = p->CreateWeak((NEWTYPE*)p.m_ptr);
01085 if (m_ptr != NULL) m_ptr->Increment(this);
01086 } else m_ptr = NULL;
01087 }
01088
01089 template<class TYPE> template<class NEWTYPE> inline
01090 wptr<TYPE>::wptr(const sptr<NEWTYPE>& p)
01091 {
01092 TypeConversion<NEWTYPE, TYPE>::Assert();
01093 if (p.ptr())
01094 {
01095 m_ptr = p->CreateWeak((NEWTYPE*)p.ptr());
01096 if (m_ptr != NULL) m_ptr->Increment(this);
01097 } else m_ptr = NULL;
01098 }
01099
01100 template<class TYPE> template<class NEWTYPE> inline
01101 wptr<TYPE>& wptr<TYPE>::operator =(const sptr<NEWTYPE> &p)
01102 {
01103 TypeConversion<NEWTYPE, TYPE>::Assert();
01104 SAtom::weak_atom_ptr* weak = NULL;
01105 if (p.ptr()) {
01106 weak = p->CreateWeak((NEWTYPE*)p.ptr());
01107 if (weak != NULL) weak->Increment(this);
01108 }
01109 if (m_ptr) m_ptr->Decrement(this);
01110 m_ptr = weak;
01111 return *this;
01112 }
01113 template<class TYPE> template<class NEWTYPE> inline
01114 wptr<TYPE>& wptr<TYPE>::operator =(const wptr<NEWTYPE> &p)
01115 {
01116 TypeConversion<NEWTYPE, TYPE>::Assert();
01117 SAtom::weak_atom_ptr* weak = NULL;
01118 if (p.m_ptr) {
01119 weak = p->CreateWeak((NEWTYPE*)p.m_ptr);
01120 if (weak != NULL) weak->Increment(this);
01121 }
01122 if (m_ptr) m_ptr->Decrement(this);
01123 m_ptr = weak;
01124 return *this;
01125 }
01126
01127 template<class TYPE> inline
01128 wptr<TYPE>::~wptr()
01129 {
01130 if (m_ptr) m_ptr->Decrement(this);
01131 }
01132
01133 template<class TYPE> inline
01134 TYPE * wptr<TYPE>::unsafe_ptr_access() const
01135 {
01136 return (m_ptr != NULL) ? reinterpret_cast<TYPE*>(m_ptr->cookie) : NULL;
01137 }
01138
01139 template<class TYPE> inline
01140 const sptr<TYPE> wptr<TYPE>::promote() const
01141 {
01142 return sptr<TYPE>(m_ptr, true);
01143 }
01144
01145 template<class TYPE> inline
01146 void wptr<TYPE>::inc_weak(const void* id) const
01147 {
01148 if (m_ptr) B_INC_WEAK(m_ptr->atom, id);
01149 }
01150
01151 template<class TYPE> inline
01152 void wptr<TYPE>::dec_weak(const void* id) const
01153 {
01154 if (m_ptr) B_DEC_WEAK(m_ptr->atom, id);
01155 }
01156
01157 #if _SUPPORTS_NAMESPACE
01158 } }
01159 #endif
01160
01161 #endif