|
IBR-DTNSuite 0.6
|
00001 /* 00002 * Copyright 2011 Johannes Morgenroth, IBR, TU Braunschweig 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #ifndef IBRCOMMON_refcnt_ptr_h 00018 #define IBRCOMMON_refcnt_ptr_h 1 00019 00020 #include "ibrcommon/thread/Mutex.h" 00021 #include "ibrcommon/thread/MutexLock.h" 00022 00023 template <class T> class refcnt_ptr 00024 { 00025 protected: 00026 // a helper class that holds the pointer to the managed object 00027 // and its reference count 00028 class Holder 00029 { 00030 public: 00031 Holder( T* ptr) : ptr_(ptr), count_(1) {}; 00032 virtual ~Holder() { delete ptr_;}; 00033 00034 T* ptr_; 00035 unsigned count_; 00036 ibrcommon::Mutex lock; 00037 }; 00038 00039 Holder* h_; 00040 00041 private: 00042 void down() 00043 { 00044 try { 00045 ibrcommon::MutexLock l(h_->lock); 00046 if (--h_->count_ == 0) throw true; 00047 } catch (const bool&) { 00048 delete h_; 00049 } 00050 } 00051 00052 public: 00053 // ctor of refcnt_ptr (p must not be NULL) 00054 explicit refcnt_ptr(T* p) : h_(new Holder(p)) 00055 { 00056 } 00057 00058 // dtor of refcnt_ptr 00059 ~refcnt_ptr() 00060 { 00061 down(); 00062 } 00063 00064 // copy and assignment of refcnt_ptr 00065 refcnt_ptr (const refcnt_ptr<T>& right) : h_(right.h_) 00066 { 00067 ibrcommon::MutexLock l(h_->lock); 00068 ++h_->count_; 00069 } 00070 00071 refcnt_ptr<T>& operator= (const refcnt_ptr<T>& right) 00072 { 00073 ibrcommon::MutexLock l(right.h_->lock); 00074 ++right.h_->count_; 00075 00076 down(); 00077 00078 h_ = right.h_; 00079 00080 return *this; 00081 } 00082 00083 refcnt_ptr<T>& operator= (refcnt_ptr<T>& right) 00084 { 00085 ibrcommon::MutexLock l(right.h_->lock); 00086 ++right.h_->count_; 00087 00088 down(); 00089 00090 h_ = right.h_; 00091 00092 return *this; 00093 } 00094 00095 // access to the managed object 00096 T* operator-> () { return h_->ptr_; } 00097 T& operator* () { return *h_->ptr_; } 00098 T* getPointer() { return h_->ptr_; } 00099 00100 const T* operator-> () const { return h_->ptr_; } 00101 const T& operator* () const { return *h_->ptr_; } 00102 const T* getPointer() const { return h_->ptr_; } 00103 }; 00104 #endif