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.fObject); 61 } 62 63 64 template<typename OtherType> 65 BReference(const BReference<OtherType>& other) 66 : 67 fObject(NULL) 68 { 69 SetTo(other.Get()); 70 } 71 72 ~BReference() 73 { 74 Unset(); 75 } 76 77 void SetTo(Type* object, bool alreadyHasReference = false) 78 { 79 if (object != NULL && !alreadyHasReference) 80 object->AcquireReference(); 81 82 Unset(); 83 84 fObject = object; 85 } 86 87 void Unset() 88 { 89 if (fObject) { 90 fObject->ReleaseReference(); 91 fObject = NULL; 92 } 93 } 94 95 Type* Get() const 96 { 97 return fObject; 98 } 99 100 Type* Detach() 101 { 102 Type* object = fObject; 103 fObject = NULL; 104 return object; 105 } 106 107 Type& operator*() const 108 { 109 return *fObject; 110 } 111 112 Type* operator->() const 113 { 114 return fObject; 115 } 116 117 operator Type*() const 118 { 119 return fObject; 120 } 121 122 BReference& operator=(const BReference<Type>& other) 123 { 124 SetTo(other.fObject); 125 return *this; 126 } 127 128 BReference& operator=(Type* other) 129 { 130 SetTo(other); 131 return *this; 132 } 133 134 template<typename OtherType> 135 BReference& operator=(const BReference<OtherType>& other) 136 { 137 SetTo(other.Get()); 138 return *this; 139 } 140 141 bool operator==(const BReference<Type>& other) const 142 { 143 return fObject == other.fObject; 144 } 145 146 bool operator==(const Type* other) const 147 { 148 return fObject == other; 149 } 150 151 bool operator!=(const BReference<Type>& other) const 152 { 153 return fObject != other.fObject; 154 } 155 156 bool operator!=(const Type* other) const 157 { 158 return fObject != other; 159 } 160 161 private: 162 Type* fObject; 163 }; 164 165 166 #endif // _REFERENCEABLE_H 167