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<const Type> 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.
This commit is contained in:
Adrien Destugues
2015-01-26 10:50:48 +01:00
parent 2ba13ecd93
commit e9b8242868
+47 -12
View File
@@ -37,7 +37,7 @@ protected:
// #pragma mark - BReference
template<typename Type = BReferenceable>
template<typename Type = BReferenceable, typename ConstType = Type>
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<Type>& other)
BReference& operator=(const BReference<Type, ConstType>& other)
{
SetTo(other.fObject);
return *this;
@@ -131,14 +131,14 @@ public:
return *this;
}
template<typename OtherType>
BReference& operator=(const BReference<OtherType>& other)
template<typename OtherType, typename OtherConstType>
BReference& operator=(const BReference<OtherType, OtherConstType>& other)
{
SetTo(other.Get());
return *this;
}
bool operator==(const BReference<Type>& other) const
bool operator==(const BReference<Type, ConstType>& other) const
{
return fObject == other.fObject;
}
@@ -148,7 +148,7 @@ public:
return fObject == other;
}
bool operator!=(const BReference<Type>& other) const
bool operator!=(const BReference<Type, ConstType>& other) const
{
return fObject != other.fObject;
}
@@ -163,4 +163,39 @@ private:
};
// #pragma mark - BReference
template<typename Type = BReferenceable>
class BConstReference: public BReference<Type, const Type> {
public:
BConstReference()
:
BReference<Type, const Type>()
{
}
BConstReference(Type* object, bool alreadyHasReference = false)
:
BReference<Type, const Type>(object, alreadyHasReference)
{
}
BConstReference(const BReference<Type>& other)
:
BReference<Type, const Type>(other)
{
}
// Allow assignment of a const reference from a mutable one (but not the
// reverse).
BConstReference& operator=(const BReference<Type, Type>& other)
{
SetTo(other.Get());
return *this;
}
};
#endif // _REFERENCEABLE_H