Make BReference and BWeakReference behave more like a normal pointer.

* Casts like BReference<Derived> to BReference<Base> are now possible.
* This cast for BWeakReference is, because of the underlying structure, not automatically type safe. I used a simple hack to make the compiler complain if the cast
is not type safe. Please take a look if that can be done better.
* Smaller style and bug fixes.
This commit is contained in:
czeidler
2012-01-05 13:42:45 +13:00
parent dafbb16406
commit 32951c4e63
2 changed files with 82 additions and 10 deletions
+28 -3
View File
@@ -41,22 +41,34 @@ template<typename Type = BReferenceable>
class BReference { class BReference {
public: public:
BReference() BReference()
: fObject(NULL) :
fObject(NULL)
{ {
} }
BReference(Type* object, bool alreadyHasReference = false) BReference(Type* object, bool alreadyHasReference = false)
: fObject(NULL) :
fObject(NULL)
{ {
SetTo(object, alreadyHasReference); SetTo(object, alreadyHasReference);
} }
BReference(const BReference<Type>& other) BReference(const BReference<Type>& other)
: fObject(NULL) :
fObject(NULL)
{ {
SetTo(other.fObject); SetTo(other.fObject);
} }
template <typename OtherType>
BReference(const BReference<OtherType>& other)
:
fObject(NULL)
{
SetTo(other.Get());
}
~BReference() ~BReference()
{ {
Unset(); Unset();
@@ -113,6 +125,19 @@ public:
return *this; return *this;
} }
BReference& operator=(Type* other)
{
SetTo(other);
return *this;
}
template <typename OtherType>
BReference& operator=(const BReference<OtherType>& other)
{
SetTo(other.Get());
return *this;
}
bool operator==(const BReference<Type>& other) const bool operator==(const BReference<Type>& other) const
{ {
return (fObject == other.fObject); return (fObject == other.fObject);
+54 -7
View File
@@ -87,6 +87,22 @@ public:
SetTo(other); SetTo(other);
} }
template <typename OtherType>
BWeakReference(const BReference<OtherType>& other)
:
fPointer(NULL)
{
SetTo(other.Get());
}
template <typename OtherType>
BWeakReference(const BWeakReference<OtherType>& other)
:
fPointer(NULL)
{
SetTo(other);
}
~BWeakReference() ~BWeakReference()
{ {
Unset(); Unset();
@@ -110,6 +126,22 @@ public:
} }
} }
template <typename OtherType>
void SetTo(const BWeakReference<OtherType>& other)
{
// Just a compiler check if the types are compatible.
OtherType* otherDummy = NULL;
Type* dummy = otherDummy;
dummy = NULL;
Unset();
if (other.Get()) {
fPointer = const_cast<WeakPointer*>(other.Get());
fPointer->AcquireReference();
}
}
void SetTo(const BReference<Type>& other) void SetTo(const BReference<Type>& other)
{ {
SetTo(other.Get()); SetTo(other.Get());
@@ -140,18 +172,19 @@ public:
return BReference<Type>(object, true); return BReference<Type>(object, true);
} }
/*! Do not use this if you do not know what you are doing. The WeakPointer
is for internal use only. */
const WeakPointer* Get() const
{
return fPointer;
}
BWeakReference& operator=(const BWeakReference<Type>& other) BWeakReference& operator=(const BWeakReference<Type>& other)
{ {
if (this == &other) if (this == &other)
return *this; return *this;
SetTo(other.fPointer); SetTo(other);
return *this;
}
BWeakReference& operator=(const Type& other)
{
SetTo(&other);
return *this; return *this;
} }
@@ -167,6 +200,20 @@ public:
return *this; return *this;
} }
template <typename OtherType>
BWeakReference& operator=(const BReference<OtherType>& other)
{
SetTo(other.Get());
return *this;
}
template <typename OtherType>
BWeakReference& operator=(const BWeakReference<OtherType>& other)
{
SetTo(other);
return *this;
}
bool operator==(const BWeakReference<Type>& other) const bool operator==(const BWeakReference<Type>& other) const
{ {
return fPointer == other.fPointer; return fPointer == other.fPointer;