2007-07-31 20:20:37 +04:00
|
|
|
/*
|
2010-12-16 19:35:42 +03:00
|
|
|
* Copyright 2004-2010, Ingo Weinhold, ingo_weinhold@gmx.de.
|
2005-01-25 19:10:03 +03:00
|
|
|
* Distributed under the terms of the MIT License.
|
|
|
|
*/
|
2007-07-31 20:20:37 +04:00
|
|
|
#ifndef _REFERENCEABLE_H
|
|
|
|
#define _REFERENCEABLE_H
|
2005-01-25 18:00:12 +03:00
|
|
|
|
|
|
|
|
|
|
|
#include <SupportDefs.h>
|
|
|
|
|
2007-07-31 20:20:37 +04:00
|
|
|
|
2010-12-16 19:35:42 +03:00
|
|
|
// #pragma mark - BReferenceable
|
|
|
|
|
|
|
|
|
2009-11-04 18:08:53 +03:00
|
|
|
class BReferenceable {
|
2005-01-25 18:00:12 +03:00
|
|
|
public:
|
2010-12-16 19:35:42 +03:00
|
|
|
BReferenceable();
|
2009-11-04 18:08:53 +03:00
|
|
|
virtual ~BReferenceable();
|
2005-01-25 18:00:12 +03:00
|
|
|
|
2011-06-11 02:31:33 +04:00
|
|
|
// acquire and release return
|
|
|
|
// the previous ref count
|
2011-06-10 05:55:12 +04:00
|
|
|
int32 AcquireReference();
|
2011-06-11 02:31:33 +04:00
|
|
|
int32 ReleaseReference();
|
2005-01-25 18:00:12 +03:00
|
|
|
|
2007-07-31 20:20:37 +04:00
|
|
|
int32 CountReferences() const
|
|
|
|
{ return fReferenceCount; }
|
2005-01-25 18:00:12 +03:00
|
|
|
|
2009-07-02 01:59:27 +04:00
|
|
|
protected:
|
|
|
|
virtual void FirstReferenceAcquired();
|
|
|
|
virtual void LastReferenceReleased();
|
|
|
|
|
2005-01-25 18:00:12 +03:00
|
|
|
protected:
|
2013-11-06 01:32:59 +04:00
|
|
|
int32 fReferenceCount;
|
2005-01-25 18:00:12 +03:00
|
|
|
};
|
|
|
|
|
2009-07-02 01:59:27 +04:00
|
|
|
|
2010-12-16 19:35:42 +03:00
|
|
|
// #pragma mark - BReference
|
2009-07-02 01:59:27 +04:00
|
|
|
|
|
|
|
|
2015-01-27 12:31:08 +03:00
|
|
|
template<typename Type = BReferenceable>
|
2009-11-04 18:08:53 +03:00
|
|
|
class BReference {
|
|
|
|
public:
|
|
|
|
BReference()
|
2012-01-05 04:29:47 +04:00
|
|
|
:
|
|
|
|
fObject(NULL)
|
2009-11-04 18:08:53 +03:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
BReference(Type* object, bool alreadyHasReference = false)
|
2012-01-05 04:29:47 +04:00
|
|
|
:
|
|
|
|
fObject(NULL)
|
2009-11-04 18:08:53 +03:00
|
|
|
{
|
|
|
|
SetTo(object, alreadyHasReference);
|
|
|
|
}
|
|
|
|
|
|
|
|
BReference(const BReference<Type>& other)
|
2012-01-05 04:29:47 +04:00
|
|
|
:
|
|
|
|
fObject(NULL)
|
2009-11-04 18:08:53 +03:00
|
|
|
{
|
2015-01-22 16:36:40 +03:00
|
|
|
SetTo(other.Get());
|
2009-11-04 18:08:53 +03:00
|
|
|
}
|
|
|
|
|
2012-01-06 00:34:06 +04:00
|
|
|
template<typename OtherType>
|
2012-01-05 04:29:47 +04:00
|
|
|
BReference(const BReference<OtherType>& other)
|
|
|
|
:
|
|
|
|
fObject(NULL)
|
|
|
|
{
|
|
|
|
SetTo(other.Get());
|
|
|
|
}
|
|
|
|
|
2009-11-04 18:08:53 +03:00
|
|
|
~BReference()
|
|
|
|
{
|
|
|
|
Unset();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SetTo(Type* object, bool alreadyHasReference = false)
|
|
|
|
{
|
|
|
|
if (object != NULL && !alreadyHasReference)
|
2010-02-15 01:22:17 +03:00
|
|
|
object->AcquireReference();
|
2009-11-04 18:08:53 +03:00
|
|
|
|
|
|
|
Unset();
|
|
|
|
|
|
|
|
fObject = object;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Unset()
|
|
|
|
{
|
|
|
|
if (fObject) {
|
2010-02-15 01:22:17 +03:00
|
|
|
fObject->ReleaseReference();
|
2009-11-04 18:08:53 +03:00
|
|
|
fObject = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-12-09 21:02:39 +03:00
|
|
|
bool IsSet() const
|
|
|
|
{
|
|
|
|
return fObject != NULL;
|
|
|
|
}
|
|
|
|
|
2015-01-27 12:31:08 +03:00
|
|
|
Type* Get() const
|
2009-11-04 18:08:53 +03:00
|
|
|
{
|
|
|
|
return fObject;
|
|
|
|
}
|
|
|
|
|
2015-01-27 12:31:08 +03:00
|
|
|
Type* Detach()
|
2009-11-04 18:08:53 +03:00
|
|
|
{
|
|
|
|
Type* object = fObject;
|
|
|
|
fObject = NULL;
|
|
|
|
return object;
|
|
|
|
}
|
|
|
|
|
2015-01-27 12:31:08 +03:00
|
|
|
Type& operator*() const
|
2009-11-04 18:08:53 +03:00
|
|
|
{
|
|
|
|
return *fObject;
|
|
|
|
}
|
|
|
|
|
2015-01-27 12:31:08 +03:00
|
|
|
Type* operator->() const
|
2009-11-04 18:08:53 +03:00
|
|
|
{
|
|
|
|
return fObject;
|
|
|
|
}
|
|
|
|
|
2015-01-27 12:31:08 +03:00
|
|
|
operator Type*() const
|
2010-07-26 23:18:56 +04:00
|
|
|
{
|
|
|
|
return fObject;
|
|
|
|
}
|
|
|
|
|
2015-01-27 12:31:08 +03:00
|
|
|
BReference& operator=(const BReference<Type>& other)
|
2009-11-04 18:08:53 +03:00
|
|
|
{
|
|
|
|
SetTo(other.fObject);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2012-01-05 04:29:47 +04:00
|
|
|
BReference& operator=(Type* other)
|
|
|
|
{
|
|
|
|
SetTo(other);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2015-01-27 12:31:08 +03:00
|
|
|
template<typename OtherType>
|
|
|
|
BReference& operator=(const BReference<OtherType>& other)
|
2012-01-05 04:29:47 +04:00
|
|
|
{
|
|
|
|
SetTo(other.Get());
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2015-01-27 12:31:08 +03:00
|
|
|
bool operator==(const BReference<Type>& other) const
|
2009-11-04 18:08:53 +03:00
|
|
|
{
|
2012-10-07 01:48:17 +04:00
|
|
|
return fObject == other.fObject;
|
2009-11-04 18:08:53 +03:00
|
|
|
}
|
|
|
|
|
2012-10-05 03:12:25 +04:00
|
|
|
bool operator==(const Type* other) const
|
|
|
|
{
|
2012-10-07 01:48:17 +04:00
|
|
|
return fObject == other;
|
2012-10-05 03:12:25 +04:00
|
|
|
}
|
|
|
|
|
2015-01-27 12:31:08 +03:00
|
|
|
bool operator!=(const BReference<Type>& other) const
|
2009-11-04 18:08:53 +03:00
|
|
|
{
|
2012-10-07 01:48:17 +04:00
|
|
|
return fObject != other.fObject;
|
2009-11-04 18:08:53 +03:00
|
|
|
}
|
|
|
|
|
2012-10-05 03:12:25 +04:00
|
|
|
bool operator!=(const Type* other) const
|
|
|
|
{
|
2012-10-07 01:48:17 +04:00
|
|
|
return fObject != other;
|
2012-10-05 03:12:25 +04:00
|
|
|
}
|
|
|
|
|
2009-11-04 18:08:53 +03:00
|
|
|
private:
|
|
|
|
Type* fObject;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2015-01-27 12:31:08 +03:00
|
|
|
// #pragma mark - BReference<const>
|
2015-01-22 16:36:40 +03:00
|
|
|
|
|
|
|
|
2015-01-27 12:31:08 +03:00
|
|
|
template<typename Type>
|
|
|
|
class BReference<const Type> {
|
2015-01-22 16:36:40 +03:00
|
|
|
public:
|
2015-01-27 12:31:08 +03:00
|
|
|
BReference(Type* object, bool alreadyHasReference = false)
|
2015-01-22 16:36:40 +03:00
|
|
|
:
|
2015-01-27 12:31:08 +03:00
|
|
|
fReference(object, alreadyHasReference)
|
2015-01-22 16:36:40 +03:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2015-01-27 12:31:08 +03:00
|
|
|
BReference(const BReference<const Type>& other)
|
2015-01-22 16:36:40 +03:00
|
|
|
:
|
2015-06-14 12:02:41 +03:00
|
|
|
fReference(const_cast<Type*>(other.Get()))
|
2015-01-22 16:36:40 +03:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2015-01-27 12:31:08 +03:00
|
|
|
template<typename OtherType>
|
|
|
|
BReference(const BReference<OtherType>& other)
|
2015-01-22 16:36:40 +03:00
|
|
|
:
|
2015-01-27 12:31:08 +03:00
|
|
|
fReference(other.Get())
|
2015-01-22 16:36:40 +03:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2015-01-27 12:31:08 +03:00
|
|
|
void SetTo(Type* object, bool alreadyHasReference = false)
|
2015-01-22 16:36:40 +03:00
|
|
|
{
|
2015-01-27 12:31:08 +03:00
|
|
|
fReference.SetTo(object, alreadyHasReference);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Unset()
|
|
|
|
{
|
|
|
|
fReference.Unset();
|
2015-01-22 16:36:40 +03:00
|
|
|
}
|
|
|
|
|
2020-12-09 21:02:39 +03:00
|
|
|
bool IsSet() const
|
|
|
|
{
|
|
|
|
return fReference.IsSet();
|
|
|
|
}
|
|
|
|
|
2015-01-27 12:31:08 +03:00
|
|
|
const Type* Get() const
|
|
|
|
{
|
|
|
|
return fReference.Get();
|
|
|
|
}
|
|
|
|
|
|
|
|
const Type* Detach()
|
|
|
|
{
|
|
|
|
return fReference.Detach();
|
|
|
|
}
|
|
|
|
|
|
|
|
const Type& operator*() const
|
|
|
|
{
|
|
|
|
return *fReference;
|
|
|
|
}
|
|
|
|
|
|
|
|
const Type* operator->() const
|
|
|
|
{
|
|
|
|
return fReference.Get();
|
|
|
|
}
|
|
|
|
|
|
|
|
operator const Type*() const
|
|
|
|
{
|
|
|
|
return fReference.Get();
|
|
|
|
}
|
|
|
|
|
|
|
|
BReference& operator=(const BReference<const Type>& other)
|
|
|
|
{
|
|
|
|
fReference = other.fReference;
|
2019-07-16 22:13:57 +03:00
|
|
|
return *this;
|
2015-01-27 12:31:08 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
BReference& operator=(Type* other)
|
|
|
|
{
|
|
|
|
fReference = other;
|
2019-07-16 22:13:57 +03:00
|
|
|
return *this;
|
2015-01-27 12:31:08 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
template<typename OtherType>
|
|
|
|
BReference& operator=(const BReference<OtherType>& other)
|
|
|
|
{
|
|
|
|
fReference = other.Get();
|
2019-07-16 22:13:57 +03:00
|
|
|
return *this;
|
2015-01-27 12:31:08 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
bool operator==(const BReference<const Type>& other) const
|
|
|
|
{
|
|
|
|
return fReference == other.Get();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator==(const Type* other) const
|
|
|
|
{
|
|
|
|
return fReference == other;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator!=(const BReference<const Type>& other) const
|
|
|
|
{
|
|
|
|
return fReference != other.Get();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator!=(const Type* other) const
|
|
|
|
{
|
|
|
|
return fReference != other;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
BReference<Type> fReference;
|
2015-01-22 16:36:40 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2007-07-31 20:20:37 +04:00
|
|
|
#endif // _REFERENCEABLE_H
|