00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00043
00044
00045 #ifndef NET_INSTAWEB_UTIL_PUBLIC_REF_COUNTED_OWNER_H_
00046 #define NET_INSTAWEB_UTIL_PUBLIC_REF_COUNTED_OWNER_H_
00047
00048 #include "base/logging.h"
00049 #include "net/instaweb/util/public/basictypes.h"
00050
00052 template<typename T>
00053 class RefCountedOwner {
00054 public:
00055 class Family {
00056 public:
00057 Family() : ptr_(NULL), ref_count_(0) {}
00058
00059 private:
00060 friend class RefCountedOwner<T>;
00061 T* ptr_;
00062 int ref_count_;
00063 DISALLOW_COPY_AND_ASSIGN(Family);
00064 };
00065
00068 explicit RefCountedOwner(Family* family)
00069 : family_(family),
00070 attached_(false) {}
00071
00072 ~RefCountedOwner() {
00073 if (attached_) {
00074 --family_->ref_count_;
00075 if (family_->ref_count_ == 0) {
00076 delete family_->ptr_;
00077 family_->ptr_ = NULL;
00078 }
00079 }
00080 }
00081
00088 bool Attach() {
00089 if (attached_) {
00090 return true;
00091 } else if (family_->ref_count_ != 0) {
00093 attached_ = true;
00094 ++family_->ref_count_;
00095 return true;
00096 } else {
00098 return false;
00099 }
00100 }
00101
00105 void Initialize(T* value) {
00106 CHECK(!attached_ && family_->ref_count_ == 0);
00107 attached_ = true;
00108 family_->ref_count_ = 1;
00109 family_->ptr_ = value;
00110 }
00111
00114 T* Get() {
00115 DCHECK(attached_);
00116 return family_->ptr_;
00117 }
00118
00119 const T* Get() const {
00120 DCHECK(attached_);
00121 return family_->ptr_;
00122 }
00123
00124 private:
00125 friend class Family;
00126 Family* family_;
00127 bool attached_;
00128 DISALLOW_COPY_AND_ASSIGN(RefCountedOwner);
00129 };
00130
00131 #endif ///< NET_INSTAWEB_UTIL_PUBLIC_REF_COUNTED_OWNER_H_