* Made the WeakReferenceable class templatized. Not really sure yet I like that

better, though :-)
* Also fixed a mixup of the unintuitive argument order of our
  atomic_test_and_set(); I guess I will change that sooner or later.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29994 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2009-04-07 15:14:15 +00:00
parent 411461b72a
commit 28a650e94d
4 changed files with 75 additions and 43 deletions
+75 -28
View File
@@ -11,19 +11,20 @@
namespace BPrivate { namespace BPrivate {
class WeakReferenceable; template<typename Type> class WeakReferenceable;
template<typename Type>
class WeakPointer : public Referenceable { class WeakPointer : public Referenceable {
public: public:
WeakReferenceable* Get(); Type* Get();
bool Put(); bool Put();
int32 UseCount() const; int32 UseCount() const;
private: private:
friend class WeakReferenceable; friend class WeakReferenceable<Type>;
WeakPointer(WeakReferenceable* object); WeakPointer(Type* object);
~WeakPointer(); ~WeakPointer();
private: private:
@@ -31,13 +32,14 @@ private:
private: private:
vint32 fUseCount; vint32 fUseCount;
WeakReferenceable* fObject; Type* fObject;
}; };
template<typename Type>
class WeakReferenceable { class WeakReferenceable {
public: public:
WeakReferenceable(); WeakReferenceable(Type* object);
virtual ~WeakReferenceable(); ~WeakReferenceable();
void AddReference() void AddReference()
{ fPointer->_GetUnchecked(); } { fPointer->_GetUnchecked(); }
@@ -48,13 +50,13 @@ public:
int32 CountReferences() const int32 CountReferences() const
{ return fPointer->UseCount(); } { return fPointer->UseCount(); }
WeakPointer* GetWeakPointer(); WeakPointer<Type>* GetWeakPointer();
protected: protected:
WeakPointer* fPointer; WeakPointer<Type>* fPointer;
}; };
template<typename Type = BPrivate::Referenceable> template<typename Type>
class WeakReference { class WeakReference {
public: public:
WeakReference() WeakReference()
@@ -72,7 +74,7 @@ public:
SetTo(object); SetTo(object);
} }
WeakReference(const WeakPointer& other) WeakReference(WeakPointer<Type>& other)
: :
fPointer(NULL), fPointer(NULL),
fObject(NULL) fObject(NULL)
@@ -80,6 +82,14 @@ public:
SetTo(&other); SetTo(&other);
} }
WeakReference(WeakPointer<Type>* other)
:
fPointer(NULL),
fObject(NULL)
{
SetTo(other);
}
WeakReference(const WeakReference<Type>& other) WeakReference(const WeakReference<Type>& other)
: :
fPointer(NULL), fPointer(NULL),
@@ -103,12 +113,13 @@ public:
} }
} }
void SetTo(WeakPointer* pointer) void SetTo(WeakPointer<Type>* pointer)
{ {
Unset(); Unset();
if (pointer != NULL) { if (pointer != NULL) {
fPointer = pointer->AddReference(); fPointer = pointer;
fPointer->AddReference();
fObject = pointer->Get(); fObject = pointer->Get();
} }
} }
@@ -142,6 +153,11 @@ public:
return *fObject; return *fObject;
} }
operator Type*() const
{
return fObject;
}
Type* operator->() const Type* operator->() const
{ {
return fObject; return fObject;
@@ -149,6 +165,9 @@ public:
WeakReference& operator=(const WeakReference<Type>& other) WeakReference& operator=(const WeakReference<Type>& other)
{ {
if (this == &other)
return *this;
SetTo(other.fPointer); SetTo(other.fPointer);
return *this; return *this;
} }
@@ -159,6 +178,18 @@ public:
return *this; return *this;
} }
WeakReference& operator=(WeakPointer<Type>& other)
{
SetTo(&other);
return *this;
}
WeakReference& operator=(WeakPointer<Type>* other)
{
SetTo(other);
return *this;
}
bool operator==(const WeakReference<Type>& other) const bool operator==(const WeakReference<Type>& other) const
{ {
return fPointer == other.fPointer; return fPointer == other.fPointer;
@@ -170,7 +201,7 @@ public:
} }
private: private:
WeakPointer* fPointer; WeakPointer<Type>* fPointer;
Type* fObject; Type* fObject;
}; };
@@ -178,23 +209,25 @@ private:
// #pragma mark - // #pragma mark -
inline WeakReferenceable* template<typename Type>
WeakPointer::Get() inline Type*
WeakPointer<Type>::Get()
{ {
int32 count; int32 count = -11;
do { do {
count = fUseCount; count = atomic_get(&fUseCount);
if (count == 0) if (count == 0)
return NULL; return NULL;
} while (atomic_test_and_set(&fUseCount, count, count + 1) != count); } while (atomic_test_and_set(&fUseCount, count + 1, count) != count);
return fObject; return fObject;
} }
template<typename Type>
inline bool inline bool
WeakPointer::Put() WeakPointer<Type>::Put()
{ {
if (atomic_add(&fUseCount, -1) == 1) { if (atomic_add(&fUseCount, -1) == 1) {
delete fObject; delete fObject;
@@ -205,15 +238,17 @@ WeakPointer::Put()
} }
template<typename Type>
inline int32 inline int32
WeakPointer::UseCount() const WeakPointer<Type>::UseCount() const
{ {
return fUseCount; return fUseCount;
} }
template<typename Type>
inline inline
WeakPointer::WeakPointer(WeakReferenceable* object) WeakPointer<Type>::WeakPointer(Type* object)
: :
fUseCount(1), fUseCount(1),
fObject(object) fObject(object)
@@ -221,14 +256,16 @@ WeakPointer::WeakPointer(WeakReferenceable* object)
} }
template<typename Type>
inline inline
WeakPointer::~WeakPointer() WeakPointer<Type>::~WeakPointer()
{ {
} }
template<typename Type>
inline bool inline bool
WeakPointer::_GetUnchecked() WeakPointer<Type>::_GetUnchecked()
{ {
return atomic_add(&fUseCount, 1) == 1; return atomic_add(&fUseCount, 1) == 1;
} }
@@ -237,16 +274,26 @@ WeakPointer::_GetUnchecked()
// #pragma - // #pragma -
template<typename Type>
inline inline
WeakReferenceable::WeakReferenceable() WeakReferenceable<Type>::WeakReferenceable(Type* object)
: :
fPointer(new WeakPointer(this)) fPointer(new WeakPointer<Type>(object))
{ {
} }
inline WeakPointer* template<typename Type>
WeakReferenceable::GetWeakPointer() inline
WeakReferenceable<Type>::~WeakReferenceable()
{
fPointer->RemoveReference();
}
template<typename Type>
inline WeakPointer<Type>*
WeakReferenceable<Type>::GetWeakPointer()
{ {
fPointer->AddReference(); fPointer->AddReference();
return fPointer; return fPointer;
-1
View File
@@ -18,5 +18,4 @@ MergeObject <libbe>support_kit.o :
Referenceable.cpp Referenceable.cpp
StopWatch.cpp StopWatch.cpp
String.cpp String.cpp
WeakReferenceable.cpp
; ;
-13
View File
@@ -1,13 +0,0 @@
/*
* Copyright 2009, Axel Dörfler, [email protected].
* Distributed under the terms of the MIT License.
*/
#include <WeakReferenceable.h>
WeakReferenceable::~WeakReferenceable()
{
}
-1
View File
@@ -120,7 +120,6 @@ SEARCH_SOURCE = [ FDirName $(HAIKU_TOP) src kits support ] ;
KernelMergeObject kernel_misc.o : KernelMergeObject kernel_misc.o :
Referenceable.cpp Referenceable.cpp
WeakReferenceable.cpp
: $(TARGET_KERNEL_PIC_CCFLAGS) : $(TARGET_KERNEL_PIC_CCFLAGS)
; ;