From 32951c4e632ef88d5a2db417806eb5d0a0f4ec43 Mon Sep 17 00:00:00 2001 From: czeidler Date: Thu, 5 Jan 2012 13:29:47 +1300 Subject: [PATCH] Make BReference and BWeakReference behave more like a normal pointer. * Casts like BReference to BReference 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. --- headers/private/shared/Referenceable.h | 31 +++++++++-- headers/private/shared/WeakReferenceable.h | 61 +++++++++++++++++++--- 2 files changed, 82 insertions(+), 10 deletions(-) diff --git a/headers/private/shared/Referenceable.h b/headers/private/shared/Referenceable.h index e1f0a6edcd..d6d9c312f3 100644 --- a/headers/private/shared/Referenceable.h +++ b/headers/private/shared/Referenceable.h @@ -41,22 +41,34 @@ template class BReference { public: BReference() - : fObject(NULL) + : + fObject(NULL) { } BReference(Type* object, bool alreadyHasReference = false) - : fObject(NULL) + : + fObject(NULL) { SetTo(object, alreadyHasReference); } BReference(const BReference& other) - : fObject(NULL) + : + fObject(NULL) { SetTo(other.fObject); } + + template + BReference(const BReference& other) + : + fObject(NULL) + { + SetTo(other.Get()); + } + ~BReference() { Unset(); @@ -113,6 +125,19 @@ public: return *this; } + BReference& operator=(Type* other) + { + SetTo(other); + return *this; + } + + template + BReference& operator=(const BReference& other) + { + SetTo(other.Get()); + return *this; + } + bool operator==(const BReference& other) const { return (fObject == other.fObject); diff --git a/headers/private/shared/WeakReferenceable.h b/headers/private/shared/WeakReferenceable.h index 22d4181885..376ae294b4 100644 --- a/headers/private/shared/WeakReferenceable.h +++ b/headers/private/shared/WeakReferenceable.h @@ -87,6 +87,22 @@ public: SetTo(other); } + template + BWeakReference(const BReference& other) + : + fPointer(NULL) + { + SetTo(other.Get()); + } + + template + BWeakReference(const BWeakReference& other) + : + fPointer(NULL) + { + SetTo(other); + } + ~BWeakReference() { Unset(); @@ -110,6 +126,22 @@ public: } } + template + void SetTo(const BWeakReference& 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(other.Get()); + fPointer->AcquireReference(); + } + } + void SetTo(const BReference& other) { SetTo(other.Get()); @@ -140,18 +172,19 @@ public: return BReference(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& other) { if (this == &other) return *this; - SetTo(other.fPointer); - return *this; - } - - BWeakReference& operator=(const Type& other) - { - SetTo(&other); + SetTo(other); return *this; } @@ -167,6 +200,20 @@ public: return *this; } + template + BWeakReference& operator=(const BReference& other) + { + SetTo(other.Get()); + return *this; + } + + template + BWeakReference& operator=(const BWeakReference& other) + { + SetTo(other); + return *this; + } + bool operator==(const BWeakReference& other) const { return fPointer == other.fPointer;