00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef __sp_impl_hpp
00021 #define __sp_impl_hpp
00022
00023 #ifdef MYNAHSA_USE_BOOST
00024
00025 #include <boost/shared_ptr.hpp>
00026 #define SHARED_PTR boost::shared_ptr
00027 #define STATIC_PTR_CAST boost::static_pointer_cast
00028
00029 #else
00030
00031 #define SHARED_PTR MynahSA::SharedPtr
00032 #define STATIC_PTR_CAST MynahSA::StaticPtrCast
00033
00034 #include <mynahsa/thread.hpp>
00035
00036 namespace MynahSA {
00037
00038 namespace Detail {
00039 class SPBase {
00040 public:
00041 inline SPBase() : _ptr(0), _count(0) { }
00042 inline SPBase(void* p) : _ptr(p), _count(0) { }
00043 inline virtual ~SPBase() {
00044 }
00045
00046 inline void ref() {
00047 Lock l(_m);
00048 _count++;
00049 }
00050
00051 inline void unref() {
00052 Mutex::lock(_m);
00053 if (--_count == 0) {
00054
00055 deleteMe();
00056
00057
00058 Mutex::unlock(_m);
00059
00060
00061 delete this;
00062
00063 } else {
00064 Mutex::unlock(_m);
00065 }
00066 }
00067
00068 inline void* get() const { return _ptr; }
00069
00070 protected:
00071 virtual void deleteMe() = 0;
00072
00073 void* _ptr;
00074
00075 private:
00076 unsigned int _count;
00077
00078 Mutex _m;
00079 };
00080
00081 template <class L>
00082 class SPImpl : public SPBase {
00083 public:
00084 inline SPImpl(L* p) : SPBase(p) {
00085 ref();
00086 }
00087
00088 inline ~SPImpl() {
00089 }
00090
00091 protected:
00092 void deleteMe() {
00093 delete static_cast<L*>(_ptr);
00094 _ptr = 0;
00095 }
00096 };
00097
00098 };
00099
00112 template<class T>
00113 class SharedPtr {
00114 public:
00115 template <class B,class A>
00116 friend SharedPtr<B> StaticPtrCast(const SharedPtr<A>& src);
00117 public:
00119 SharedPtr() : _spref(0) {
00120 }
00121
00122
00129 SharedPtr(T* p) : _spref(new Detail::SPImpl<T>(p)) {
00130 }
00131
00133 SharedPtr(const SharedPtr& p) : _spref(p._spref) {
00134 if (_spref) {
00135
00136 _spref->ref();
00137 }
00138 }
00139
00140
00148 SharedPtr(Detail::SPBase* p) : _spref(p) {
00149 if (p) {
00150 p->ref();
00151 }
00152 }
00153
00155 virtual ~SharedPtr() {
00156 if (_spref) {
00157
00158 _spref->unref();
00159 }
00160 }
00161
00163 T* get() const {
00164 if (_spref){
00165 return static_cast<T*>(_spref->get());
00166 } else {
00167 return 0;
00168 }
00169 }
00170
00172 T& operator*() const {
00173
00174 return *(static_cast<T*>(_spref->get()));
00175 }
00176
00178 T* operator->() const {
00179 return static_cast<T*>(_spref->get());
00180 }
00181
00183 bool operator<(const SharedPtr& in) const {
00184 return _spref->get() < in._spref->get();
00185 }
00186
00188 SharedPtr& operator=(const SharedPtr& in) {
00189 if (_spref) {
00190 _spref->unref();
00191 }
00192 _spref = in._spref;
00193
00194 if (_spref) {
00195 _spref->ref();
00196 }
00197
00198 return *this;
00199 }
00200
00202 bool operator==(const SharedPtr& in) const {
00203 return _spref == in._spref;
00204 }
00205
00207 bool operator==(T* ptr) const {
00208
00209 return _spref == 0 ? (ptr == 0) : ptr == static_cast<T*>(_spref->get());
00210 }
00211
00213 operator bool() const {
00214 return _spref == 0 ? false : _spref->get() != 0;
00215 }
00216
00218 template<class B>
00219 operator SharedPtr<B>() const {
00220
00221 if (!_spref->get()) {
00222 return SharedPtr<B>();
00223 }
00224
00225 static_cast<B*>( static_cast<T*>(_spref->get()) );
00226 SharedPtr<B> dst(_spref);
00227 return dst;
00228 }
00229
00230
00231 private:
00233 Detail::SPBase* _spref;
00234 };
00235
00236
00237
00244 template<>
00245 class SharedPtr<void> {
00246
00247
00248
00249
00250 template <class B,class A>
00251 friend SharedPtr<B> StaticPtrCast(const SharedPtr<A>& src);
00252
00253
00254 public:
00256 SharedPtr() : _spref(0) {
00257 }
00258
00259
00260
00262 SharedPtr(const SharedPtr& p) : _spref(p._spref) {
00263 if (_spref) {
00264
00265 _spref->ref();
00266 }
00267 }
00268
00269
00270 SharedPtr(Detail::SPBase* p) : _spref(p) {
00271 if (p) {
00272 p->ref();
00273 }
00274 }
00275
00276 virtual ~SharedPtr() {
00277 if (_spref) {
00278
00279 _spref->unref();
00280 }
00281 }
00282
00284 void* get() const {
00285 if (_spref){
00286
00287 return _spref->get();
00288 } else {
00289 return 0;
00290 }
00291 }
00292
00293
00294
00295 bool operator<(const SharedPtr& in) const {
00296 return _spref->get() < in._spref->get();
00297 }
00298
00299
00300 SharedPtr& operator=(const SharedPtr& in) {
00301 if (_spref) {
00302 _spref->unref();
00303 }
00304 _spref = in._spref;
00305 _spref->ref();
00306
00307 return *this;
00308 }
00309
00310
00311 bool operator==(const SharedPtr& in) const {
00312 return _spref == in._spref;
00313 }
00314
00315 bool operator==(void* ptr) const {
00316
00317 return _spref == 0 ? (ptr == 0) : ptr == static_cast<void*>(_spref->get());
00318 }
00319
00320 operator bool() const {
00321 return _spref == 0 ? false : _spref->get() != 0;
00322 }
00323
00324 template<class B>
00325 operator SharedPtr<B>() const {
00326
00327 if (!_spref->get()) {
00328 return SharedPtr<B>();
00329 }
00330
00331 SharedPtr<B> dst(_spref);
00332 return dst;
00333 }
00334
00335
00336
00337 private:
00338 Detail::SPBase* _spref;
00339 };
00340
00341 template <class B,class A>
00342 SharedPtr<B> StaticPtrCast(const SharedPtr<A>& src) {
00343 static_cast<B*>( static_cast<A*>(0));
00344 SharedPtr<B> dst(src._spref);
00345 return dst;
00346 }
00347
00348
00349
00350
00351 };
00352
00353 #endif
00354
00355 #endif