ref_counter.h

Go to the documentation of this file.
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 };

Generated on Fri Apr 25 18:49:37 2008 for foobar2000 SDK by  doxygen 1.5.5