00001
00002 #ifndef HDNUM_COUNTINGPTR_HH
00003 #define HDNUM_COUNTINGPTR_HH
00004
00005 #include <iostream>
00006
00013 namespace hdnum {
00014
00021 class NondeletingMemoryManagementPolicy
00022 {
00023 public:
00024 template<typename T>
00025 static void delete_action (T* p)
00026 {}
00027 };
00028
00035 class DeletingMemoryManagementPolicy
00036 {
00037 public:
00038 template<typename T>
00039 static void delete_action (T* p)
00040 {
00041 if (p->reference_counter_zero())
00042 delete p;
00043 }
00044 };
00045
00046 template<typename T, typename P=DeletingMemoryManagementPolicy>
00069 class CP
00070 {
00071 T* p;
00072
00073 public:
00075 CP ()
00076 {
00077 p = 0;
00078 }
00079
00081 explicit CP (T* p_)
00082 {
00083 p = p_;
00084 if (p!=0)
00085 p->reference_counter_increment();
00086 }
00087
00089 CP (const CP<T>& cp)
00090 {
00091 p = cp.p;
00092 if (p!=0)
00093 p->reference_counter_increment();
00094 }
00095
00097 ~CP ()
00098 {
00099 if (p!=0)
00100 {
00101 p->reference_counter_decrement();
00102 P::delete_action(p);
00103 }
00104 }
00105
00107 CP<T>& operator= (T* p_)
00108 {
00109 if (p!=p_)
00110 {
00111 if (p!=0)
00112 p->reference_counter_decrement();
00113 p = p_;
00114 if (p!=0)
00115 p->reference_counter_increment();
00116 }
00117 return *this;
00118 }
00119
00121 CP<T>& operator= (const CP<T>& cp)
00122 {
00123 if (p!=cp.p)
00124 {
00125 if (p!=0)
00126 p->reference_counter_decrement();
00127 p = cp.p;
00128 if (p!=0)
00129 p->reference_counter_increment();
00130 }
00131 return *this;
00132 }
00133
00135 T* operator-> () const
00136 {
00137 return p;
00138 }
00139
00141 T& operator* () const
00142 {
00143 return *p;
00144 }
00145
00147 bool operator== (const CP<T>& cp) const
00148 {
00149 return p==cp.p;
00150 }
00151
00153 bool operator!= (const CP<T>& cp) const
00154 {
00155 return p!=cp.p;
00156 }
00157
00158 };
00159
00160 class CountableException
00161 {
00162 int counter;
00163 public:
00164 CountableException (int i) : counter(i) {}
00165 int get_counter () const
00166 {
00167 return counter;
00168 }
00169 };
00170
00176 class Countable
00177 {
00178 mutable int counter;
00179
00180 public:
00181
00183 Countable () : counter(0)
00184 {
00185 }
00186
00188 Countable (const Countable& x)
00189 {
00190 counter = 0;
00191 }
00192
00194 Countable& operator= (const Countable& x)
00195 {
00196 return *this;
00197 }
00198
00200 void reference_counter_increment () const
00201 {
00202 counter++;
00203 }
00204
00206 void reference_counter_decrement () const
00207 {
00208 counter--;
00209 }
00210
00212 bool reference_counter_zero () const
00213 {
00214 return counter==0;
00215 }
00216
00218 int get_reference_counter () const
00219 {
00220 return counter;
00221 }
00222
00227 ~Countable ()
00228 {
00229 if (counter!=0)
00230 {
00231 std::cout << counter << " counting pointer(s) point to object at "
00232 << this << " while it is deleted" << std::endl;
00233 throw CountableException(counter);
00234 }
00235 }
00236 };
00237
00238 }
00239
00240 #endif