1 /* 2 * Copyright 2004-2010, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 #ifndef _REFERENCEABLE_H 6 #define _REFERENCEABLE_H 7 8 9 #include <SupportDefs.h> 10 11 12 // #pragma mark - BReferenceable 13 14 15 class BReferenceable { 16 public: 17 BReferenceable(); 18 virtual ~BReferenceable(); 19 20 // acquire and release return 21 // the previous ref count 22 int32 AcquireReference(); 23 int32 ReleaseReference(); 24 25 int32 CountReferences() const 26 { return atomic_get((int32*)&fReferenceCount); } 27 28 protected: 29 virtual void FirstReferenceAcquired(); 30 virtual void LastReferenceReleased(); 31 32 protected: 33 int32 fReferenceCount; 34 }; 35 36 37 // #pragma mark - BReference 38 39 40 template<typename Type = BReferenceable> 41 class BReference { 42 public: 43 BReference() 44 : 45 fObject(NULL) 46 { 47 } 48 49 BReference(Type* object, bool alreadyHasReference = false) 50 : 51 fObject(NULL) 52 { 53 SetTo(object, alreadyHasReference); 54 } 55 56 BReference(const BReference<Type>& other) 57 : 58 fObject(NULL) 59 { 60 SetTo(other.Get()); 61 } 62 63 template<typename OtherType> 64 BReference(const BReference<OtherType>& other) 65 : 66 fObject(NULL) 67 { 68 SetTo(other.Get()); 69 } 70 71 ~BReference() 72 { 73 Unset(); 74 } 75 76 void SetTo(Type* object, bool alreadyHasReference = false) 77 { 78 if (object != NULL && !alreadyHasReference) 79 object->AcquireReference(); 80 81 Unset(); 82 83 fObject = object; 84 } 85 86 void Unset() 87 { 88 if (fObject) { 89 fObject->ReleaseReference(); 90 fObject = NULL; 91 } 92 } 93 94 bool IsSet() const 95 { 96 return fObject != NULL; 97 } 98 99 Type* Get() const 100 { 101 return fObject; 102 } 103 104 Type* Detach() 105 { 106 Type* object = fObject; 107 fObject = NULL; 108 return object; 109 } 110 111 Type& operator*() const 112 { 113 return *fObject; 114 } 115 116 Type* operator->() const 117 { 118 return fObject; 119 } 120 121 operator Type*() const 122 { 123 return fObject; 124 } 125 126 BReference& operator=(const BReference<Type>& other) 127 { 128 SetTo(other.fObject); 129 return *this; 130 } 131 132 BReference& operator=(Type* other) 133 { 134 SetTo(other); 135 return *this; 136 } 137 138 template<typename OtherType> 139 BReference& operator=(const BReference<OtherType>& other) 140 { 141 SetTo(other.Get()); 142 return *this; 143 } 144 145 bool operator==(const BReference<Type>& other) const 146 { 147 return fObject == other.fObject; 148 } 149 150 bool operator==(const Type* other) const 151 { 152 return fObject == other; 153 } 154 155 bool operator!=(const BReference<Type>& other) const 156 { 157 return fObject != other.fObject; 158 } 159 160 bool operator!=(const Type* other) const 161 { 162 return fObject != other; 163 } 164 165 private: 166 Type* fObject; 167 }; 168 169 170 // #pragma mark - BReference<const> 171 172 173 template<typename Type> 174 class BReference<const Type> { 175 public: 176 BReference(Type* object, bool alreadyHasReference = false) 177 : 178 fReference(object, alreadyHasReference) 179 { 180 } 181 182 BReference(const BReference<const Type>& other) 183 : 184 fReference(const_cast<Type*>(other.Get())) 185 { 186 } 187 188 template<typename OtherType> 189 BReference(const BReference<OtherType>& other) 190 : 191 fReference(other.Get()) 192 { 193 } 194 195 void SetTo(Type* object, bool alreadyHasReference = false) 196 { 197 fReference.SetTo(object, alreadyHasReference); 198 } 199 200 void Unset() 201 { 202 fReference.Unset(); 203 } 204 205 bool IsSet() const 206 { 207 return fReference.IsSet(); 208 } 209 210 const Type* Get() const 211 { 212 return fReference.Get(); 213 } 214 215 const Type* Detach() 216 { 217 return fReference.Detach(); 218 } 219 220 const Type& operator*() const 221 { 222 return *fReference; 223 } 224 225 const Type* operator->() const 226 { 227 return fReference.Get(); 228 } 229 230 operator const Type*() const 231 { 232 return fReference.Get(); 233 } 234 235 BReference& operator=(const BReference<const Type>& other) 236 { 237 fReference = other.fReference; 238 return *this; 239 } 240 241 BReference& operator=(Type* other) 242 { 243 fReference = other; 244 return *this; 245 } 246 247 template<typename OtherType> 248 BReference& operator=(const BReference<OtherType>& other) 249 { 250 fReference = other.Get(); 251 return *this; 252 } 253 254 bool operator==(const BReference<const Type>& other) const 255 { 256 return fReference == other.Get(); 257 } 258 259 bool operator==(const Type* other) const 260 { 261 return fReference == other; 262 } 263 264 bool operator!=(const BReference<const Type>& other) const 265 { 266 return fReference != other.Get(); 267 } 268 269 bool operator!=(const Type* other) const 270 { 271 return fReference != other; 272 } 273 274 private: 275 BReference<Type> fReference; 276 }; 277 278 279 #endif // _REFERENCEABLE_H 280