Added helper class Referencable (a simple base class for reference counting).
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@11028 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
73895a69a0
commit
47e01f5075
41
src/servers/registrar/Referencable.cpp
Normal file
41
src/servers/registrar/Referencable.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
// Referencable.cpp
|
||||
|
||||
#include "Debug.h"
|
||||
#include "Referencable.h"
|
||||
|
||||
// constructor
|
||||
Referencable::Referencable(bool deleteWhenUnreferenced)
|
||||
: fReferenceCount(1),
|
||||
fDeleteWhenUnreferenced(deleteWhenUnreferenced)
|
||||
{
|
||||
}
|
||||
|
||||
// destructor
|
||||
Referencable::~Referencable()
|
||||
{
|
||||
}
|
||||
|
||||
// AddReference
|
||||
void
|
||||
Referencable::AddReference()
|
||||
{
|
||||
atomic_add(&fReferenceCount, 1);
|
||||
}
|
||||
|
||||
// RemoveReference
|
||||
bool
|
||||
Referencable::RemoveReference()
|
||||
{
|
||||
bool unreferenced = (atomic_add(&fReferenceCount, -1) == 1);
|
||||
if (fDeleteWhenUnreferenced && unreferenced)
|
||||
delete this;
|
||||
return unreferenced;
|
||||
}
|
||||
|
||||
// CountReferences
|
||||
int32
|
||||
Referencable::CountReferences() const
|
||||
{
|
||||
return fReferenceCount;
|
||||
}
|
||||
|
109
src/servers/registrar/Referencable.h
Normal file
109
src/servers/registrar/Referencable.h
Normal file
@ -0,0 +1,109 @@
|
||||
// Referencable.h
|
||||
|
||||
#ifndef REFERENCABLE_H
|
||||
#define REFERENCABLE_H
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
// Referencable
|
||||
class Referencable {
|
||||
public:
|
||||
Referencable(
|
||||
bool deleteWhenUnreferenced = false);
|
||||
virtual ~Referencable();
|
||||
|
||||
void AddReference();
|
||||
bool RemoveReference(); // returns true after last
|
||||
|
||||
int32 CountReferences() const;
|
||||
|
||||
protected:
|
||||
vint32 fReferenceCount;
|
||||
bool fDeleteWhenUnreferenced;
|
||||
};
|
||||
|
||||
// Reference
|
||||
template<typename Type>
|
||||
class Reference {
|
||||
public:
|
||||
Reference()
|
||||
: fObject(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
Reference(Type* object, bool alreadyHasReference = false)
|
||||
: fObject(NULL)
|
||||
{
|
||||
SetTo(object, alreadyHasReference);
|
||||
}
|
||||
|
||||
Reference(const Reference<Type>& other)
|
||||
: fObject(NULL)
|
||||
{
|
||||
SetTo(other.fObject);
|
||||
}
|
||||
|
||||
~Reference()
|
||||
{
|
||||
Unset();
|
||||
}
|
||||
|
||||
void SetTo(Type* object, bool alreadyHasReference = false)
|
||||
{
|
||||
Unset();
|
||||
fObject = object;
|
||||
if (fObject && !alreadyHasReference)
|
||||
fObject->AddReference();
|
||||
}
|
||||
|
||||
void Unset()
|
||||
{
|
||||
if (fObject) {
|
||||
fObject->RemoveReference();
|
||||
fObject = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
Type* Get() const
|
||||
{
|
||||
return fObject;
|
||||
}
|
||||
|
||||
Type* Detach()
|
||||
{
|
||||
Type* object = fObject;
|
||||
fObject = NULL;
|
||||
return object;
|
||||
}
|
||||
|
||||
Type& operator*() const
|
||||
{
|
||||
return *fObject;
|
||||
}
|
||||
|
||||
Type* operator->() const
|
||||
{
|
||||
return fObject;
|
||||
}
|
||||
|
||||
Reference& operator=(const Reference<Type>& other)
|
||||
{
|
||||
SetTo(other.fObject);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const Reference<Type>& other) const
|
||||
{
|
||||
return (fObject == other.fObject);
|
||||
}
|
||||
|
||||
bool operator!=(const Reference<Type>& other) const
|
||||
{
|
||||
return (fObject != other.fObject);
|
||||
}
|
||||
|
||||
private:
|
||||
Type* fObject;
|
||||
};
|
||||
|
||||
#endif // REFERENCABLE_H
|
Loading…
Reference in New Issue
Block a user