Make UEFI boot-platform build again
[haiku.git] / headers / private / shared / WeakReferenceable.h
blob7d1774fe3257327fbc6ff35e28074fe154567a68
1 /*
2 * Copyright 2009, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
4 */
5 #ifndef _WEAK_REFERENCEABLE_H
6 #define _WEAK_REFERENCEABLE_H
9 #include <Referenceable.h>
11 #include <new>
14 namespace BPrivate {
17 class BWeakReferenceable;
20 class WeakPointer : public BReferenceable {
21 public:
22 WeakPointer(BWeakReferenceable* object);
23 ~WeakPointer();
25 BWeakReferenceable* Get();
26 bool Put();
28 int32 UseCount() const;
30 void GetUnchecked();
32 private:
33 int32 fUseCount;
34 BWeakReferenceable* fObject;
38 class BWeakReferenceable {
39 public:
40 BWeakReferenceable();
41 virtual ~BWeakReferenceable();
43 status_t InitCheck();
45 void AcquireReference()
46 { fPointer->GetUnchecked(); }
48 bool ReleaseReference()
49 { return fPointer->Put(); }
51 int32 CountReferences() const
52 { return fPointer->UseCount(); }
54 WeakPointer* GetWeakPointer();
55 private:
56 WeakPointer* fPointer;
60 template<typename Type>
61 class BWeakReference {
62 public:
63 BWeakReference()
65 fPointer(NULL)
69 BWeakReference(Type* object)
71 fPointer(NULL)
73 SetTo(object);
76 BWeakReference(const BWeakReference<Type>& other)
78 fPointer(NULL)
80 SetTo(other);
83 BWeakReference(const BReference<Type>& other)
85 fPointer(NULL)
87 SetTo(other);
90 template<typename OtherType>
91 BWeakReference(const BReference<OtherType>& other)
93 fPointer(NULL)
95 SetTo(other.Get());
98 template<typename OtherType>
99 BWeakReference(const BWeakReference<OtherType>& other)
101 fPointer(NULL)
103 SetTo(other);
106 ~BWeakReference()
108 Unset();
111 void SetTo(Type* object)
113 Unset();
115 if (object != NULL)
116 fPointer = object->GetWeakPointer();
119 void SetTo(const BWeakReference<Type>& other)
121 Unset();
123 if (other.fPointer) {
124 fPointer = other.fPointer;
125 fPointer->AcquireReference();
129 template<typename OtherType>
130 void SetTo(const BWeakReference<OtherType>& other)
132 // Just a compiler check if the types are compatible.
133 OtherType* otherDummy = NULL;
134 Type* dummy = otherDummy;
135 dummy = NULL;
137 Unset();
139 if (other.PrivatePointer()) {
140 fPointer = const_cast<WeakPointer*>(other.PrivatePointer());
141 fPointer->AcquireReference();
145 void SetTo(const BReference<Type>& other)
147 SetTo(other.Get());
150 void Unset()
152 if (fPointer != NULL) {
153 fPointer->ReleaseReference();
154 fPointer = NULL;
158 bool IsAlive()
160 if (fPointer == NULL)
161 return false;
162 Type* object = static_cast<Type*>(fPointer->Get());
163 if (object == NULL)
164 return false;
165 fPointer->Put();
166 return true;
169 BReference<Type> GetReference()
171 Type* object = static_cast<Type*>(fPointer->Get());
172 return BReference<Type>(object, true);
175 BWeakReference& operator=(const BWeakReference<Type>& other)
177 if (this == &other)
178 return *this;
180 SetTo(other);
181 return *this;
184 BWeakReference& operator=(Type* other)
186 SetTo(other);
187 return *this;
190 BWeakReference& operator=(const BReference<Type>& other)
192 SetTo(other.Get());
193 return *this;
196 template<typename OtherType>
197 BWeakReference& operator=(const BReference<OtherType>& other)
199 SetTo(other.Get());
200 return *this;
203 template<typename OtherType>
204 BWeakReference& operator=(const BWeakReference<OtherType>& other)
206 SetTo(other);
207 return *this;
210 bool operator==(const BWeakReference<Type>& other) const
212 return fPointer == other.fPointer;
215 bool operator!=(const BWeakReference<Type>& other) const
217 return fPointer != other.fPointer;
220 /*! Do not use this if you do not know what you are doing. The WeakPointer
221 is for internal use only.
223 const WeakPointer* PrivatePointer() const
225 return fPointer;
228 private:
229 WeakPointer* fPointer;
233 // #pragma mark -
236 inline
237 WeakPointer::WeakPointer(BWeakReferenceable* object)
239 fUseCount(1),
240 fObject(object)
245 inline
246 WeakPointer::~WeakPointer()
251 inline BWeakReferenceable*
252 WeakPointer::Get()
254 int32 count = -11;
256 do {
257 count = atomic_get(&fUseCount);
258 if (count == 0)
259 return NULL;
260 } while (atomic_test_and_set(&fUseCount, count + 1, count) != count);
262 return fObject;
266 inline bool
267 WeakPointer::Put()
269 if (atomic_add(&fUseCount, -1) == 1) {
270 delete fObject;
271 return true;
274 return false;
278 inline int32
279 WeakPointer::UseCount() const
281 return fUseCount;
285 inline void
286 WeakPointer::GetUnchecked()
288 atomic_add(&fUseCount, 1);
292 // #pragma -
295 inline
296 BWeakReferenceable::BWeakReferenceable()
298 fPointer(new(std::nothrow) WeakPointer(this))
303 inline
304 BWeakReferenceable::~BWeakReferenceable()
306 fPointer->ReleaseReference();
310 inline status_t
311 BWeakReferenceable::InitCheck()
313 if (fPointer == NULL)
314 return B_NO_MEMORY;
315 return B_OK;
319 inline WeakPointer*
320 BWeakReferenceable::GetWeakPointer()
322 fPointer->AcquireReference();
323 return fPointer;
326 } // namespace BPrivate
328 using BPrivate::BWeakReferenceable;
329 using BPrivate::BWeakReference;
331 #endif // _WEAK_REFERENCEABLE_H