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
00031
00032 #ifndef header_sharedptr
00033 #define header_sharedptr
00034
00035 #include "mutex.h"
00036
00037 class CL_UnknownSharedPtr_Generic
00038 {
00039 public:
00040 CL_UnknownSharedPtr_Generic() : ref_count(1), mutex(0) { return; }
00041
00042 virtual ~CL_UnknownSharedPtr_Generic() { return; }
00043
00044 public:
00045
00046 unsigned int ref_count;
00047
00048
00049 CL_Mutex *mutex;
00050 };
00051
00052 class CL_UnknownSharedPtr;
00053
00054 template <typename TEvil>
00055 class CL_SharedPtr_Generic : public CL_UnknownSharedPtr_Generic
00056 {
00057 public:
00058 CL_SharedPtr_Generic() : ptr(0) { return; }
00059
00060 public:
00061
00062 TEvil *ptr;
00063 };
00064
00065 template <typename T, typename TEvil>
00066 class CL_SharedPtr_Deleter : public CL_SharedPtr_Generic<T>
00067 {
00068 public:
00069 CL_SharedPtr_Deleter(TEvil *e, CL_Mutex *mutex = 0) { this->ptr = e; this->mutex = mutex; }
00070
00071 ~CL_SharedPtr_Deleter() { delete this->ptr; }
00072 };
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 template <typename T, typename U = T>
00084 class CL_SharedPtr
00085 {
00087 public:
00088
00089
00090
00091
00092
00093 CL_SharedPtr() : impl(0) { return; }
00094
00095 CL_SharedPtr(const CL_SharedPtr<T, U>& other) : impl(other.impl) { increment(); }
00096
00097 CL_SharedPtr(const CL_UnknownSharedPtr& other) : impl(0)
00098 {
00099 if (other.impl)
00100 {
00101 impl = dynamic_cast<CL_SharedPtr_Generic<T>*>(other.impl)
00102 increment();
00103 }
00104 }
00105
00106 template <typename D>
00107 explicit CL_SharedPtr(D* ptr, CL_Mutex *mutex = 0) : impl(0)
00108 {
00109 if (ptr)
00110 impl = new CL_SharedPtr_Deleter<T, D>(ptr, mutex);
00111 }
00112
00113 explicit CL_SharedPtr(CL_SharedPtr_Generic<T> *impl) : impl(impl) { increment(); }
00114
00115 ~CL_SharedPtr() { decrement(); }
00116
00118 public:
00119
00120 bool is_null() const { return impl ? (impl->ptr == 0) : true; }
00121
00122
00123
00124 int get_ref_count() const { if (impl == 0) return 0; return impl->ref_count; }
00125
00126
00127
00128
00129
00130 U* get() { return (U*) ((impl != 0) ? impl->ptr : 0); }
00131
00132 const U* get() const { return (const U*) ((impl != 0) ? impl->ptr : 0); }
00133
00134
00135 operator U*() { return get(); }
00136
00137
00138 operator const U*() const { return get(); }
00139
00140
00141
00142
00143 bool operator==(const T* other) const { return other == ((impl != 0) ? impl->ptr : 0); }
00144
00145 bool operator==(const CL_SharedPtr<T, U>& other) const { return other.impl == impl; }
00146
00148 public:
00149
00150 CL_SharedPtr<T, U>& operator=(const CL_SharedPtr<T, U>& other)
00151 {
00152 if (other.impl != impl)
00153 {
00154 decrement();
00155 impl = other.impl;
00156 increment();
00157 }
00158 return *this;
00159 }
00160
00161 CL_SharedPtr<T, U>& operator=(const CL_UnknownSharedPtr& other)
00162 {
00163 if (other.impl != impl)
00164 {
00165 decrement();
00166 if (other.impl)
00167 {
00168 impl = dynamic_cast<CL_SharedPtr_Generic<T>*>(other.impl)
00169 increment();
00170 }
00171 }
00172 return *this;
00173 }
00174
00175
00176 U& operator*() { return *((U*) impl->ptr); }
00177
00178 U const& operator*() const { return *((const U*) impl->ptr); }
00179
00180
00181 U* operator->() { return (U*) impl->ptr; }
00182
00183 U const* operator->() const { return (const U*) impl->ptr; }
00184
00185 CL_SharedPtr_Generic<T> *get_impl() { return impl; }
00186
00188 private:
00189
00190 CL_SharedPtr_Generic<T> *impl;
00191
00192
00193 void increment()
00194 {
00195 if (impl != 0)
00196 {
00197 CL_MutexSection lock(impl->mutex);
00198 ++impl->ref_count;
00199 }
00200 }
00201
00202
00203 void decrement()
00204 {
00205 if (impl != 0)
00206 {
00207 CL_MutexSection lock(impl->mutex);
00208 if (--impl->ref_count == 0)
00209 {
00210 lock.unlock();
00211 delete impl;
00212 impl = 0;
00213 }
00214 }
00215 }
00216
00217 friend class CL_UnknownSharedPtr;
00218 };
00219
00220
00221
00222
00223
00224 class CL_UnknownSharedPtr
00225 {
00227 public:
00228 CL_UnknownSharedPtr() : impl(0) { return; }
00229
00230 template <typename T, typename U>
00231 explicit CL_UnknownSharedPtr(const CL_SharedPtr<T, U>& other) : impl(other.impl) { increment(); }
00232
00233 ~CL_UnknownSharedPtr() { decrement(); }
00234
00236 public:
00237
00238 bool is_null() const { return impl ? false : true; }
00239
00240
00241
00242 int get_ref_count() const { if (impl == 0) return 0; return impl->ref_count; }
00243
00244
00245 bool operator==(const CL_UnknownSharedPtr& other) const { return other.impl == impl; }
00246
00247 template <typename T, typename U>
00248 bool operator==(const CL_SharedPtr<T, U>& other) const { return other.impl == impl; }
00249
00251 public:
00252
00253 template <typename T, typename U>
00254 CL_UnknownSharedPtr& operator=(const CL_SharedPtr<T, U>& other)
00255 {
00256 if (other.impl != impl)
00257 {
00258 decrement();
00259 impl = other.impl;
00260 increment();
00261 }
00262 return *this;
00263 }
00264
00266 private:
00267
00268 CL_UnknownSharedPtr_Generic *impl;
00269
00270
00271 void increment()
00272 {
00273 if (impl != 0)
00274 {
00275 CL_MutexSection lock(impl->mutex);
00276 ++impl->ref_count;
00277 }
00278 }
00279
00280
00281 void decrement()
00282 {
00283 if (impl != 0)
00284 {
00285 CL_MutexSection lock(impl->mutex);
00286 if (--impl->ref_count == 0)
00287 {
00288 lock.unlock();
00289 delete impl;
00290 impl = 0;
00291 }
00292 }
00293 }
00294 };
00295
00296 #endif