Atom.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2005 Palmsource, Inc.
00003  * 
00004  * This software is licensed as described in the file LICENSE, which
00005  * you should have received as part of this distribution. The terms
00006  * are also available at http://www.openbinder.org/license.html.
00007  * 
00008  * This software consists of voluntary contributions made by many
00009  * individuals. For the exact contribution history, see the revision
00010  * history and logs, available at http://www.openbinder.org
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 } } // palmos::osp
00042 #endif
00043 
00044 #if _SUPPORTS_NAMESPACE
00045 namespace palmos {
00046 namespace support {
00047 #endif
00048 
00055 // forward reference
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             // ----- private debugging support -----
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             // ----- private debugging support -----
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             // XXX this should be moved to m_debugPtr, probably.
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; // this is needed to placate ADS!
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         // Give comparison operators access to our pointer.
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         // Special constructor for more efficient wptr::promote().
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 // A zillion kinds of comparison operators.
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 /*---- No user serviceable parts after this -------------------*/
00920 
00921 /* ----------------- sptr Implementation ------------------*/
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 //  m_ptr = (p && B_ATTEMPT_INC_STRONG(p->atom, this)) ? dynamic_cast<TYPE*>(p->cookie) : NULL;
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 /* ----------------- wptr Implementation ------------------*/
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 } } // namespace palmos::support
01159 #endif
01160 
01161 #endif /* _SUPPORT_ATOM_H */