00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef INCLUDED_GC_PTR_HH
00025 #define INCLUDED_GC_PTR_HH
00026
00027 #ifndef INCLUDED_THREAD_LOCK_HH
00028 #include "Thread/Lock.hh"
00029 #endif
00030
00031 #ifndef INCLUDED_THREAD_SYNCHRONIZE_HH
00032 #include "Thread/Synchronize.hh"
00033 #endif
00034
00035 template<class TM>
00036 class usg_cnt_t {
00037 typedef typename TM::FastLock lock_t;
00038 typedef fatalmind::Synchronize<lock_t> sync;
00039 public:
00040 inline usg_cnt_t(): d_cnt(1) {};
00041 inline ~usg_cnt_t() {};
00042
00043 inline int inc() {sync s(_lk); return ++d_cnt;};
00044 inline int dec() {sync s(_lk); return --d_cnt;};
00045 inline void reset() {sync s(_lk); d_cnt = 1;};
00046
00047 private:
00048 int d_cnt;
00049 lock_t _lk;
00050 };
00051
00052 template<class T, class TM>
00053 class gc_ptr_ref {
00054 public:
00055 gc_ptr_ref(T* ptr, usg_cnt_t<TM>* usg)
00056 : d_ptr(ptr)
00057 , d_usg(usg)
00058 {
00059 }
00060
00061 typedef usg_cnt_t<TM> usg_cnt;
00062 T* d_ptr;
00063 usg_cnt* d_usg;
00064 };
00065
00070 template<class T, class TM = fatalmind::DefaultThreadedModel>
00071 class gc_ptr {
00072 typedef usg_cnt_t<TM> usg_cnt;
00073 public:
00074 explicit gc_ptr(T* p=0): d_ptr(p), d_usg(p != 0 ? new usg_cnt(): 0) {};
00075
00076
00077
00078 inline gc_ptr(const gc_ptr<T, TM>&p) throw()
00079 : d_ptr(p.get()), d_usg(p.d_usg)
00080 {
00081 if (d_usg) {
00082 d_usg->inc();
00083 }
00084 }
00085
00086 inline gc_ptr(const gc_ptr_ref<T, TM>&p) throw()
00087 : d_ptr(p.d_ptr), d_usg(p.d_usg)
00088 {
00089 if (d_usg) {
00090 d_usg->inc();
00091 }
00092 }
00093
00094 ~gc_ptr() throw() {
00095 dispose();
00096 }
00097
00098 inline gc_ptr<T, TM>& operator= (const gc_ptr<T, TM>& p) throw()
00099 {
00100 if (this != &p) {
00101 dispose();
00102 d_ptr = p.d_ptr;
00103 d_usg = p.d_usg;
00104 if (d_usg) {
00105 d_usg->inc();
00106 }
00107 }
00108 return *this;
00109 }
00110
00111 inline T& operator*() const throw()
00112 {
00113 return *d_ptr;
00114 }
00115
00116 inline T* operator->() const throw()
00117 {
00118 return d_ptr;
00119 }
00120
00121 inline T* get() const throw()
00122 {
00123 return d_ptr;
00124 }
00125
00126 inline bool isNull() const throw()
00127 {
00128 return d_ptr == 0;
00129 }
00130
00131 void reset(T* ptr= 0) throw()
00132 {
00133 if (d_ptr != ptr) {
00134 dispose();
00135 d_ptr = ptr;
00136 d_usg = d_ptr != 0? new usg_cnt() : 0;
00137 }
00138 }
00139
00140 inline bool operator<(const gc_ptr<T>& a) const {
00141 return *d_ptr < *a.d_ptr;
00142 }
00143
00144 template<class Y>
00145 operator gc_ptr_ref<Y, TM>() throw() {
00146 return gc_ptr_ref<Y, TM>(d_ptr, d_usg);
00147 }
00148
00149 protected:
00150 T* d_ptr;
00151 usg_cnt* d_usg;
00152
00153 inline void dispose() throw() {
00154 if (d_usg != 0 && d_usg->dec() == 0) {
00155 delete d_usg;
00156 delete d_ptr;
00157 }
00158 }
00159 };
00160
00161 #endif