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 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 Type* Get() const 95 { 96 return fObject; 97 } 98 99 Type* Detach() 100 { 101 Type* object = fObject; 102 fObject = NULL; 103 return object; 104 } 105 106 Type& operator*() const 107 { 108 return *fObject; 109 } 110 111 Type* operator->() const 112 { 113 return fObject; 114 } 115 116 operator Type*() const 117 { 118 return fObject; 119 } 120 121 BReference& operator=(const BReference<Type>& other) 122 { 123 SetTo(other.fObject); 124 return *this; 125 } 126 127 BReference& operator=(Type* other) 128 { 129 SetTo(other); 130 return *this; 131 } 132 133 template<typename OtherType> 134 BReference& operator=(const BReference<OtherType>& other) 135 { 136 SetTo(other.Get()); 137 return *this; 138 } 139 140 bool operator==(const BReference<Type>& other) const 141 { 142 return fObject == other.fObject; 143 } 144 145 bool operator==(const Type* other) const 146 { 147 return fObject == other; 148 } 149 150 bool operator!=(const BReference<Type>& other) const 151 { 152 return fObject != other.fObject; 153 } 154 155 bool operator!=(const Type* other) const 156 { 157 return fObject != other; 158 } 159 160 private: 161 Type* fObject; 162 }; 163 164 165 // #pragma mark - BReference<const> 166 167 168 template<typename Type> 169 class BReference<const Type> { 170 public: 171 BReference(Type* object, bool alreadyHasReference = false) 172 : 173 fReference(object, alreadyHasReference) 174 { 175 } 176 177 BReference(const BReference<const Type>& other) 178 : 179 fReference(const_cast<Type*>(other.Get())) 180 { 181 } 182 183 template<typename OtherType> 184 BReference(const BReference<OtherType>& other) 185 : 186 fReference(other.Get()) 187 { 188 } 189 190 void SetTo(Type* object, bool alreadyHasReference = false) 191 { 192 fReference.SetTo(object, alreadyHasReference); 193 } 194 195 void Unset() 196 { 197 fReference.Unset(); 198 } 199 200 const Type* Get() const 201 { 202 return fReference.Get(); 203 } 204 205 const Type* Detach() 206 { 207 return fReference.Detach(); 208 } 209 210 const Type& operator*() const 211 { 212 return *fReference; 213 } 214 215 const Type* operator->() const 216 { 217 return fReference.Get(); 218 } 219 220 operator const Type*() const 221 { 222 return fReference.Get(); 223 } 224 225 BReference& operator=(const BReference<const Type>& other) 226 { 227 fReference = other.fReference; 228 } 229 230 BReference& operator=(Type* other) 231 { 232 fReference = other; 233 } 234 235 template<typename OtherType> 236 BReference& operator=(const BReference<OtherType>& other) 237 { 238 fReference = other.Get(); 239 } 240 241 bool operator==(const BReference<const Type>& other) const 242 { 243 return fReference == other.Get(); 244 } 245 246 bool operator==(const Type* other) const 247 { 248 return fReference == other; 249 } 250 251 bool operator!=(const BReference<const Type>& other) const 252 { 253 return fReference != other.Get(); 254 } 255 256 bool operator!=(const Type* other) const 257 { 258 return fReference != other; 259 } 260 261 private: 262 BReference<Type> fReference; 263 }; 264 265 266 #endif // _REFERENCEABLE_H 267