00001 // -*- C++ -*- 00002 #ifndef __CPP_ADDON_SHARED_PTR_H__ 00003 #define __CPP_ADDON_SHARED_PTR_H__ 00004 00015 template <typename T> 00016 class _shared_ptr { 00017 protected: 00018 T* ptr; 00019 UINT* pcnt; 00020 00021 void delete_this () { 00022 if (valid() && !(--*pcnt)) { 00023 delete ptr; delete pcnt; 00024 ptr = 0; pcnt = 0; 00025 } 00026 } 00027 00029 bool valid () const { 00030 assert((!ptr && !pcnt) || (ptr && pcnt && *pcnt > 0)); 00031 return (ptr != 0); 00032 } 00033 00034 UINT use_count () const { assert(valid()); return *pcnt; } 00035 bool unique () const { return (use_count() == 1); } 00036 00037 public: 00038 explicit _shared_ptr (T* p = 0) : ptr(p), pcnt(0) { 00039 if (p) { pcnt = new UINT(1); assert(valid()); } } 00040 _shared_ptr (const _shared_ptr<T>& s) : ptr(s.ptr), pcnt(s.pcnt) { 00041 if (valid()) ++(*pcnt); } 00042 ~_shared_ptr () { delete_this(); } 00043 00044 const _shared_ptr<T>& operator= (const _shared_ptr<T>& s) { 00045 if (this == &s) return *this; 00046 delete_this(); 00047 ptr = s.ptr; pcnt = s.pcnt; 00048 if (valid()) ++(*pcnt); 00049 return *this; 00050 } 00051 bool operator!= (const T* p) const { return ptr != p; } 00052 bool operator== (const T* p) const { return ptr == p; } 00053 bool operator!= (const _shared_ptr& p) const { return ptr != p.ptr; } 00054 bool operator== (const _shared_ptr& p) const { return ptr == p.ptr; } 00055 bool operator! () const { return !ptr; } 00056 00057 typedef bool (_shared_ptr::*implicit_bool_type) () const; 00058 operator implicit_bool_type () const { 00059 return ptr? &_shared_ptr::valid : 0; 00060 } 00061 }; 00062 00064 template <typename T> 00065 class const_shared_ptr : public _shared_ptr<T> { 00066 using _shared_ptr<T>::valid; 00067 using _shared_ptr<T>::ptr; 00068 public: 00069 const_shared_ptr () {} 00070 const_shared_ptr (T* p) : _shared_ptr<T>(p) {} 00071 const_shared_ptr (const const_shared_ptr<T>& s) : _shared_ptr<T>(s) {} 00072 00073 const const_shared_ptr<T>& operator= (const const_shared_ptr<T>& s) { 00074 _shared_ptr<T>::operator=(s); 00075 return *this; 00076 } 00077 const T* operator-> () const { assert(valid()); return ptr; } 00078 const T& operator* () const { assert(valid()); return *ptr; } 00079 }; 00080 00082 template <typename T> 00083 class var_shared_ptr : public _shared_ptr<T> { 00084 using _shared_ptr<T>::valid; 00085 using _shared_ptr<T>::ptr; 00086 public: 00087 var_shared_ptr () {} 00088 var_shared_ptr (T* p) : _shared_ptr<T>(p) {} 00089 var_shared_ptr (const var_shared_ptr<T>& s) : _shared_ptr<T>(s) {} 00090 00091 const var_shared_ptr<T>& operator= (const var_shared_ptr<T>& s) { 00092 _shared_ptr<T>::operator=(s); 00093 return *this; 00094 } 00095 T* operator-> () const { assert(valid()); return ptr; } 00096 T& operator* () const { assert(valid()); return *ptr; } 00097 }; 00098 00099 #ifdef __SHARED_PTR_H__ 00100 #warning "This header file may conflict with another `shared_ptr.h' file." 00101 #endif 00102 #define __SHARED_PTR_H__ 00103 #endif