00001 #ifndef __REF_COUNTER_H__ 00002 #define __REF_COUNTER_H__ 00003 00015 template <class T> class RCPointer { 00016 T *_x; 00017 public: 00018 RCPointer() : _x(NULL) {} 00019 RCPointer(T * x) : _x(x) { 00020 if (_x) { 00021 _x->inc_refs(); 00022 } 00023 } 00024 RCPointer(const RCPointer &a) : _x(a._x) { 00025 if (_x) { 00026 _x->inc_refs(); 00027 } 00028 } 00029 00030 ~RCPointer() { 00031 make_null(); 00032 } 00033 RCPointer &operator =(const RCPointer &a) { 00034 if (a._x) { 00035 a._x->inc_refs(); 00036 } 00037 make_null(); 00038 _x = a._x; 00039 return *this; 00040 } 00041 bool operator ==(const RCPointer &x) const { 00042 return (_x == x._x); 00043 } 00044 00045 /*operator bool() const { 00046 return !is_null(); 00047 }*/ 00048 void make_null() { 00049 if (_x) { 00050 if (_x->dec_refs() == 0) { 00051 delete _x; 00052 } 00053 } 00054 _x = 0; 00055 } 00056 00057 bool is_null() const {return (!_x);} 00058 T* get_ptr() const { 00059 return _x; 00060 } 00061 00062 T *operator ->() const {return get_ptr();} 00063 operator T *() const {return get_ptr();} 00064 }; 00065 00074 template <class T,class P> class DerivedRCPointer : public P { 00075 public: 00076 DerivedRCPointer() : P() {} 00077 DerivedRCPointer(T * x) : P(x) {} 00078 DerivedRCPointer(const DerivedRCPointer &a) : P(a) {} 00079 00080 T* get_ptr() const { 00081 return (T *)P::get_ptr(); 00082 } 00083 00084 T *operator ->() const {return get_ptr();} 00085 operator T *() const {return get_ptr();} 00086 }; 00087 00088 00094 class RefCountedClass { 00095 unsigned long _count; 00096 public: 00097 // note that we use zero as a "latch" to detect overflow 00098 // _count is actually one greater than the reference count 00099 RefCountedClass() : _count(1) {} 00100 unsigned long inc_refs() { 00101 if(_count)_count ++; 00102 return _count-1;} 00103 unsigned long dec_refs() {if (_count > 1)--_count;return _count-1;} 00104 unsigned long ref_count() {return _count -1;} 00105 }; 00106 00120 template <class x> class ref_stack : public simple_stack<x> 00121 { 00122 typedef simple_stack<x> SS; 00123 public: 00124 ref_stack(unsigned int start_size = 10, 00125 unsigned int expansion_size = 10) 00126 : SS(start_size,expansion_size) {} 00127 00128 void reset() { 00129 int l = len(); 00130 while (l > 0) { 00131 l --; 00132 (*this)[l].make_null(); 00133 } 00134 SS::reset(); 00135 } 00136 void set_len(int newlen) { 00137 int l = len(); 00138 while (l > newlen) { 00139 l --; 00140 (*this)[l].make_null(); 00141 } 00142 SS::set_len(newlen); 00143 } 00144 00145 void cut(int len) { 00146 set_len(len + 1); 00147 } 00148 00149 void remove(int p) { 00150 if (p >= len()) 00151 return; 00152 x &top = SS::top(); 00153 SS::remove(p); 00154 top.make_null(); 00155 } 00156 x pop() { 00157 x top = SS::top(); 00158 set_len(len()-1); 00159 return top; 00160 } 00161 }; 00162 00163 #endif 00164 00165