00001 namespace pfc { 00002 class counter { 00003 public: 00004 counter(long p_val = 0) : m_val(p_val) {} 00005 #ifdef _WINDOWS 00006 long operator++() throw() {return InterlockedIncrement(&m_val);} 00007 long operator--() throw() {return InterlockedDecrement(&m_val);} 00008 long operator++(int) throw() {return InterlockedIncrement(&m_val)-1;} 00009 long operator--(int) throw() {return InterlockedDecrement(&m_val)+1;} 00010 #else 00011 long operator++() {return ++m_val;} 00012 long operator--() {return --m_val;} 00013 long operator++(int) {return m_val++;} 00014 long operator--(int) {return m_val--;} 00015 #pragma message("PORTME") 00016 #endif 00017 operator long() const throw() {return m_val;} 00018 typedef long t_val; 00019 private: 00020 volatile long m_val; 00021 }; 00022 00023 typedef counter refcounter; 00024 00025 class NOVTABLE refcounted_object_root 00026 { 00027 public: 00028 void refcount_add_ref() throw() {++m_counter;} 00029 void refcount_release() throw() {if (--m_counter == 0) delete this;} 00030 void _refcount_release_temporary() throw() {--m_counter;}//for internal use only! 00031 protected: 00032 refcounted_object_root() {} 00033 virtual ~refcounted_object_root() {} 00034 private: 00035 refcounter m_counter; 00036 }; 00037 00038 template<typename T> 00039 class refcounted_object_ptr_t { 00040 private: 00041 typedef refcounted_object_ptr_t<T> t_self; 00042 public: 00043 inline refcounted_object_ptr_t() throw() : m_ptr(NULL) {} 00044 inline refcounted_object_ptr_t(T* p_ptr) throw() : m_ptr(NULL) {copy(p_ptr);} 00045 inline refcounted_object_ptr_t(const t_self & p_source) throw() : m_ptr(NULL) {copy(p_source);} 00046 00047 template<typename t_source> 00048 inline refcounted_object_ptr_t(t_source * p_ptr) throw() : m_ptr(NULL) {copy(p_ptr);} 00049 00050 template<typename t_source> 00051 inline refcounted_object_ptr_t(const refcounted_object_ptr_t<t_source> & p_source) throw() : m_ptr(NULL) {copy(p_source);} 00052 00053 inline ~refcounted_object_ptr_t() throw() {if (m_ptr != NULL) m_ptr->refcount_release();} 00054 00055 template<typename t_source> 00056 inline void copy(t_source * p_ptr) throw() { 00057 T* torel = pfc::replace_t(m_ptr,pfc::safe_ptr_cast<T>(p_ptr)); 00058 if (m_ptr != NULL) m_ptr->refcount_add_ref(); 00059 if (torel != NULL) torel->refcount_release(); 00060 00061 } 00062 00063 template<typename t_source> 00064 inline void copy(const refcounted_object_ptr_t<t_source> & p_source) throw() {copy(p_source.get_ptr());} 00065 00066 00067 inline const t_self & operator=(const t_self & p_source) throw() {copy(p_source); return *this;} 00068 inline const t_self & operator=(T * p_ptr) throw() {copy(p_ptr); return *this;} 00069 00070 template<typename t_source> inline t_self & operator=(const refcounted_object_ptr_t<t_source> & p_source) throw() {copy(p_source); return *this;} 00071 template<typename t_source> inline t_self & operator=(t_source * p_ptr) throw() {copy(p_ptr); return *this;} 00072 00073 inline void release() throw() { 00074 T * temp = pfc::replace_t(m_ptr,(T*)NULL); 00075 if (temp != NULL) temp->refcount_release(); 00076 } 00077 00078 00079 inline T& operator*() const throw() {return *m_ptr;} 00080 00081 inline T* operator->() const throw() {PFC_ASSERT(m_ptr != NULL);return m_ptr;} 00082 00083 inline T* get_ptr() const throw() {return m_ptr;} 00084 00085 inline bool is_valid() const throw() {return m_ptr != NULL;} 00086 inline bool is_empty() const throw() {return m_ptr == NULL;} 00087 00088 inline bool operator==(const t_self & p_item) const throw() {return m_ptr == p_item.get_ptr();} 00089 inline bool operator!=(const t_self & p_item) const throw() {return m_ptr != p_item.get_ptr();} 00090 inline bool operator>(const t_self & p_item) const throw() {return m_ptr > p_item.get_ptr();} 00091 inline bool operator<(const t_self & p_item) const throw() {return m_ptr < p_item.get_ptr();} 00092 00093 00094 inline T* __unsafe_duplicate() const throw()//should not be used ! temporary ! 00095 { 00096 if (m_ptr) m_ptr->refcount_add_ref(); 00097 return m_ptr; 00098 } 00099 00100 inline T* detach() throw() {//should not be used ! temporary ! 00101 T* ret = m_ptr; 00102 m_ptr = 0; 00103 return ret; 00104 } 00105 00106 inline void attach(T * p_ptr) throw() {//should not be used ! temporary ! 00107 release(); 00108 m_ptr = p_ptr; 00109 } 00110 inline t_self & operator<<(t_self & p_source) throw() {attach(p_source.detach());return *this;} 00111 inline t_self & operator>>(t_self & p_dest) throw() {p_dest.attach(detach());return *this;} 00112 private: 00113 T* m_ptr; 00114 }; 00115 00116 template<typename T> 00117 class traits_t<refcounted_object_ptr_t<T> > : public traits_default { 00118 public: 00119 enum { realloc_safe = true, constructor_may_fail = false}; 00120 }; 00121 00122 };
1.5.5