00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00048
00049
00050
00051
00052
00054
00055 namespace stlplus
00056 {
00057
00059
00061
00062 template<typename T>
00063 class smart_ptr_holder
00064 {
00065 private:
00066 unsigned m_count;
00067 T* m_data;
00068
00069
00070 smart_ptr_holder(const smart_ptr_holder& s) :
00071 m_count(0), m_data(0)
00072 {
00073 }
00074
00075 smart_ptr_holder& operator=(const smart_ptr_holder& s)
00076 {
00077 return *this;
00078 }
00079
00080 public:
00081 smart_ptr_holder(T* p = 0) :
00082 m_count(1), m_data(p)
00083 {
00084 }
00085
00086 ~smart_ptr_holder(void)
00087 {
00088 clear();
00089 }
00090
00091 unsigned count(void) const
00092 {
00093 return m_count;
00094 }
00095
00096 void increment(void)
00097 {
00098 ++m_count;
00099 }
00100
00101 bool decrement(void)
00102 {
00103 --m_count;
00104 return m_count == 0;
00105 }
00106
00107 bool null(void)
00108 {
00109 return m_data == 0;
00110 }
00111
00112 void clear(void)
00113 {
00114 if(m_data)
00115 delete m_data;
00116 m_data = 0;
00117 }
00118
00119 void set(T* p = 0)
00120 {
00121 clear();
00122 m_data = p;
00123 }
00124
00125 T*& pointer(void)
00126 {
00127 return m_data;
00128 }
00129
00130 const T* pointer(void) const
00131 {
00132 return m_data;
00133 }
00134
00135 T& value(void)
00136 {
00137 return *m_data;
00138 }
00139
00140 const T& value(void) const
00141 {
00142 return *m_data;
00143 }
00144 };
00145
00147
00149
00151
00152
00153
00154 template <typename T, typename C>
00155 smart_ptr_base<T,C>::smart_ptr_base(void) :
00156 m_holder(new smart_ptr_holder<T>)
00157 {
00158 }
00159
00160
00161 template <typename T, typename C>
00162 smart_ptr_base<T,C>::smart_ptr_base(const T& data) throw(illegal_copy) :
00163 m_holder(new smart_ptr_holder<T>)
00164 {
00165 m_holder->set(C()(data));
00166 }
00167
00168
00169
00170
00171 template <typename T, typename C>
00172 smart_ptr_base<T,C>::smart_ptr_base(T* data) :
00173 m_holder(new smart_ptr_holder<T>)
00174 {
00175 m_holder->set(data);
00176 }
00177
00178
00179 template <typename T, typename C>
00180 smart_ptr_base<T,C>::smart_ptr_base(const smart_ptr_base<T,C>& r) :
00181 m_holder(0)
00182 {
00183 m_holder = r.m_holder;
00184 m_holder->increment();
00185 }
00186
00187
00188 template <typename T, typename C>
00189 smart_ptr_base<T,C>::~smart_ptr_base(void)
00190 {
00191 if(m_holder->decrement())
00192 delete m_holder;
00193 }
00194
00196
00197
00198 template <typename T, typename C>
00199 bool smart_ptr_base<T,C>::null(void) const
00200 {
00201 return m_holder->null();
00202 }
00203
00204 template <typename T, typename C>
00205 bool smart_ptr_base<T,C>::present(void) const
00206 {
00207 return !m_holder->null();
00208 }
00209
00210 template <typename T, typename C>
00211 bool smart_ptr_base<T,C>::operator!(void) const
00212 {
00213 return m_holder->null();
00214 }
00215
00216 template <typename T, typename C>
00217 smart_ptr_base<T,C>::operator bool(void) const
00218 {
00219 return !m_holder->null();
00220 }
00221
00223
00224
00225 template <typename T, typename C>
00226 T& smart_ptr_base<T,C>::operator*(void) throw(null_dereference)
00227 {
00228 if (m_holder->null()) throw null_dereference("null pointer dereferenced in smart_ptr::operator*");
00229 return m_holder->value();
00230 }
00231
00232 template <typename T, typename C>
00233 const T& smart_ptr_base<T,C>::operator*(void) const throw(null_dereference)
00234 {
00235 if (m_holder->null()) throw null_dereference("null pointer dereferenced in smart_ptr::operator*");
00236 return m_holder->value();
00237 }
00238
00239 template <typename T, typename C>
00240 T* smart_ptr_base<T,C>::operator->(void) throw(null_dereference)
00241 {
00242 if (m_holder->null()) throw null_dereference("null pointer dereferenced in smart_ptr::operator->");
00243 return m_holder->pointer();
00244 }
00245
00246 template <typename T, typename C>
00247 const T* smart_ptr_base<T,C>::operator->(void) const throw(null_dereference)
00248 {
00249 if (m_holder->null()) throw null_dereference("null pointer dereferenced in smart_ptr::operator->");
00250 return m_holder->pointer();
00251 }
00252
00254
00255
00256 template <typename T, typename C>
00257 void smart_ptr_base<T,C>::set_value(const T& data) throw(illegal_copy)
00258 {
00259 m_holder->set(C()(data));
00260 }
00261
00262 template <typename T, typename C>
00263 T& smart_ptr_base<T,C>::value(void) throw(null_dereference)
00264 {
00265 if (m_holder->null()) throw null_dereference("null pointer dereferenced in smart_ptr::value");
00266 return m_holder->value();
00267 }
00268
00269 template <typename T, typename C>
00270 const T& smart_ptr_base<T,C>::value(void) const throw(null_dereference)
00271 {
00272 if (m_holder->null()) throw null_dereference("null pointer dereferenced in smart_ptr::value");
00273 return m_holder->value();
00274 }
00275
00276 template <typename T, typename C>
00277 void smart_ptr_base<T,C>::set(T* data)
00278 {
00279 m_holder->set(data);
00280 }
00281
00282 template <typename T, typename C>
00283 T* smart_ptr_base<T,C>::pointer(void)
00284 {
00285 return m_holder->pointer();
00286 }
00287
00288 template <typename T, typename C>
00289 const T* smart_ptr_base<T,C>::pointer(void) const
00290 {
00291 return m_holder->pointer();
00292 }
00293
00295
00296
00297
00298 template <typename T, typename C>
00299 void smart_ptr_base<T,C>::alias(const smart_ptr_base<T,C>& r)
00300 {
00301
00302
00303
00304
00305
00306
00307
00308 make_alias(r.m_holder);
00309 }
00310
00311 template <typename T, typename C>
00312 bool smart_ptr_base<T,C>::aliases(const smart_ptr_base<T,C>& r) const
00313 {
00314 return m_holder == r.m_holder;
00315 }
00316
00317 template <typename T, typename C>
00318 unsigned smart_ptr_base<T,C>::alias_count(void) const
00319 {
00320 return m_holder->count();
00321 }
00322
00323 template <typename T, typename C>
00324 void smart_ptr_base<T,C>::clear(void)
00325 {
00326 m_holder->clear();
00327 }
00328
00329 template <typename T, typename C>
00330 void smart_ptr_base<T,C>::clear_unique(void)
00331 {
00332 if (m_holder->count() == 1)
00333 m_holder->clear();
00334 else
00335 {
00336 m_holder->decrement();
00337 m_holder = 0;
00338 m_holder = new smart_ptr_holder<T>;
00339 }
00340 }
00341
00342 template <typename T, typename C>
00343 void smart_ptr_base<T,C>::make_unique(void) throw(illegal_copy)
00344 {
00345 if (m_holder->count() > 1)
00346 {
00347 smart_ptr_holder<T>* old_holder = m_holder;
00348 m_holder->decrement();
00349 m_holder = 0;
00350 m_holder = new smart_ptr_holder<T>;
00351 if (old_holder->pointer())
00352 m_holder->set(C()(old_holder->value()));
00353 }
00354 }
00355
00356 template <typename T, typename C>
00357 void smart_ptr_base<T,C>::copy(const smart_ptr_base<T,C>& data) throw(illegal_copy)
00358 {
00359 alias(data);
00360 make_unique();
00361 }
00362
00363
00364
00365
00366 template <typename T, typename C>
00367 void* smart_ptr_base<T,C>::handle(void) const
00368 {
00369 return m_holder;
00370 }
00371
00372 template <typename T, typename C>
00373 void smart_ptr_base<T,C>::make_alias(void* handle)
00374 {
00375 smart_ptr_holder<T>* r_holder = (smart_ptr_holder<T>*)handle;
00376 if (m_holder != r_holder)
00377 {
00378 if (m_holder->decrement())
00379 delete m_holder;
00380 m_holder = r_holder;
00381 m_holder->increment();
00382 }
00383 }
00384
00386
00387 }
00388