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