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