2 * Copyright 2009, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
5 #ifndef _WEAK_REFERENCEABLE_H
6 #define _WEAK_REFERENCEABLE_H
9 #include <Referenceable.h>
17 class BWeakReferenceable
;
20 class WeakPointer
: public BReferenceable
{
22 WeakPointer(BWeakReferenceable
* object
);
25 BWeakReferenceable
* Get();
28 int32
UseCount() const;
34 BWeakReferenceable
* fObject
;
38 class BWeakReferenceable
{
41 virtual ~BWeakReferenceable();
45 void AcquireReference()
46 { fPointer
->GetUnchecked(); }
48 bool ReleaseReference()
49 { return fPointer
->Put(); }
51 int32
CountReferences() const
52 { return fPointer
->UseCount(); }
54 WeakPointer
* GetWeakPointer();
56 WeakPointer
* fPointer
;
60 template<typename Type
>
61 class BWeakReference
{
69 BWeakReference(Type
* object
)
76 BWeakReference(const BWeakReference
<Type
>& other
)
83 BWeakReference(const BReference
<Type
>& other
)
90 template<typename OtherType
>
91 BWeakReference(const BReference
<OtherType
>& other
)
98 template<typename OtherType
>
99 BWeakReference(const BWeakReference
<OtherType
>& other
)
111 void SetTo(Type
* object
)
116 fPointer
= object
->GetWeakPointer();
119 void SetTo(const BWeakReference
<Type
>& other
)
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
;
139 if (other
.PrivatePointer()) {
140 fPointer
= const_cast<WeakPointer
*>(other
.PrivatePointer());
141 fPointer
->AcquireReference();
145 void SetTo(const BReference
<Type
>& other
)
152 if (fPointer
!= NULL
) {
153 fPointer
->ReleaseReference();
160 if (fPointer
== NULL
)
162 Type
* object
= static_cast<Type
*>(fPointer
->Get());
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
)
184 BWeakReference
& operator=(Type
* other
)
190 BWeakReference
& operator=(const BReference
<Type
>& other
)
196 template<typename OtherType
>
197 BWeakReference
& operator=(const BReference
<OtherType
>& other
)
203 template<typename OtherType
>
204 BWeakReference
& operator=(const BWeakReference
<OtherType
>& other
)
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
229 WeakPointer
* fPointer
;
237 WeakPointer::WeakPointer(BWeakReferenceable
* object
)
246 WeakPointer::~WeakPointer()
251 inline BWeakReferenceable
*
257 count
= atomic_get(&fUseCount
);
260 } while (atomic_test_and_set(&fUseCount
, count
+ 1, count
) != count
);
269 if (atomic_add(&fUseCount
, -1) == 1) {
279 WeakPointer::UseCount() const
286 WeakPointer::GetUnchecked()
288 atomic_add(&fUseCount
, 1);
296 BWeakReferenceable::BWeakReferenceable()
298 fPointer(new(std::nothrow
) WeakPointer(this))
304 BWeakReferenceable::~BWeakReferenceable()
306 fPointer
->ReleaseReference();
311 BWeakReferenceable::InitCheck()
313 if (fPointer
== NULL
)
320 BWeakReferenceable::GetWeakPointer()
322 fPointer
->AcquireReference();
326 } // namespace BPrivate
328 using BPrivate::BWeakReferenceable
;
329 using BPrivate::BWeakReference
;
331 #endif // _WEAK_REFERENCEABLE_H