From e9b82428687037c1998e7140661a249710dd93c8 Mon Sep 17 00:00:00 2001 From: Adrien Destugues Date: Thu, 22 Jan 2015 14:36:40 +0100 Subject: [PATCH] Add a BConstReference class. This is a BReference that allows only const access to the referenced object. This was not easily possible with the existing BReference for two reasons: * BReference would not work, as BReference needs to change the reference count of the referenced object. Adding mutable and casting where appropriate wouldwork but, * It is now also possible to assign a BReference to a BConstReference (to the same type, of course). The reverse is not allowed, making it more difficult to "const cast" the referenced object (it's still possible to "get" the object pointer and cast that). BConstReference can be used to provide shared read-only access to an object, for example this can be used to cache non-copiable or expansive to create objects. --- headers/os/support/Referenceable.h | 59 ++++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 12 deletions(-) diff --git a/headers/os/support/Referenceable.h b/headers/os/support/Referenceable.h index 0c7b2980df..a9af8c691c 100644 --- a/headers/os/support/Referenceable.h +++ b/headers/os/support/Referenceable.h @@ -37,7 +37,7 @@ protected: // #pragma mark - BReference -template +template class BReference { public: BReference() @@ -57,7 +57,7 @@ public: : fObject(NULL) { - SetTo(other.fObject); + SetTo(other.Get()); } @@ -92,34 +92,34 @@ public: } } - Type* Get() const + ConstType* Get() const { return fObject; } - Type* Detach() + ConstType* Detach() { Type* object = fObject; fObject = NULL; return object; } - Type& operator*() const + ConstType& operator*() const { return *fObject; } - Type* operator->() const + ConstType* operator->() const { return fObject; } - operator Type*() const + operator ConstType*() const { return fObject; } - BReference& operator=(const BReference& other) + BReference& operator=(const BReference& other) { SetTo(other.fObject); return *this; @@ -131,14 +131,14 @@ public: return *this; } - template - BReference& operator=(const BReference& other) + template + BReference& operator=(const BReference& other) { SetTo(other.Get()); return *this; } - bool operator==(const BReference& other) const + bool operator==(const BReference& other) const { return fObject == other.fObject; } @@ -148,7 +148,7 @@ public: return fObject == other; } - bool operator!=(const BReference& other) const + bool operator!=(const BReference& other) const { return fObject != other.fObject; } @@ -163,4 +163,39 @@ private: }; +// #pragma mark - BReference + + +template +class BConstReference: public BReference { +public: + BConstReference() + : + BReference() + { + } + + BConstReference(Type* object, bool alreadyHasReference = false) + : + BReference(object, alreadyHasReference) + { + } + + BConstReference(const BReference& other) + : + BReference(other) + { + } + + // Allow assignment of a const reference from a mutable one (but not the + // reverse). + BConstReference& operator=(const BReference& other) + { + SetTo(other.Get()); + return *this; + } + +}; + + #endif // _REFERENCEABLE_H