BReferencable: implement const references with specialization
This is simpler and cleaner than my previous attempt. Thanks to Ingo for suggesting this.
This commit is contained in:
@@ -37,7 +37,7 @@ protected:
|
|||||||
// #pragma mark - BReference
|
// #pragma mark - BReference
|
||||||
|
|
||||||
|
|
||||||
template<typename Type = BReferenceable, typename ConstType = Type>
|
template<typename Type = BReferenceable>
|
||||||
class BReference {
|
class BReference {
|
||||||
public:
|
public:
|
||||||
BReference()
|
BReference()
|
||||||
@@ -92,34 +92,34 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstType* Get() const
|
Type* Get() const
|
||||||
{
|
{
|
||||||
return fObject;
|
return fObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstType* Detach()
|
Type* Detach()
|
||||||
{
|
{
|
||||||
Type* object = fObject;
|
Type* object = fObject;
|
||||||
fObject = NULL;
|
fObject = NULL;
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstType& operator*() const
|
Type& operator*() const
|
||||||
{
|
{
|
||||||
return *fObject;
|
return *fObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstType* operator->() const
|
Type* operator->() const
|
||||||
{
|
{
|
||||||
return fObject;
|
return fObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator ConstType*() const
|
operator Type*() const
|
||||||
{
|
{
|
||||||
return fObject;
|
return fObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
BReference& operator=(const BReference<Type, ConstType>& other)
|
BReference& operator=(const BReference<Type>& other)
|
||||||
{
|
{
|
||||||
SetTo(other.fObject);
|
SetTo(other.fObject);
|
||||||
return *this;
|
return *this;
|
||||||
@@ -131,14 +131,14 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename OtherType, typename OtherConstType>
|
template<typename OtherType>
|
||||||
BReference& operator=(const BReference<OtherType, OtherConstType>& other)
|
BReference& operator=(const BReference<OtherType>& other)
|
||||||
{
|
{
|
||||||
SetTo(other.Get());
|
SetTo(other.Get());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const BReference<Type, ConstType>& other) const
|
bool operator==(const BReference<Type>& other) const
|
||||||
{
|
{
|
||||||
return fObject == other.fObject;
|
return fObject == other.fObject;
|
||||||
}
|
}
|
||||||
@@ -148,7 +148,7 @@ public:
|
|||||||
return fObject == other;
|
return fObject == other;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const BReference<Type, ConstType>& other) const
|
bool operator!=(const BReference<Type>& other) const
|
||||||
{
|
{
|
||||||
return fObject != other.fObject;
|
return fObject != other.fObject;
|
||||||
}
|
}
|
||||||
@@ -163,38 +163,104 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - BReference
|
// #pragma mark - BReference<const>
|
||||||
|
|
||||||
|
|
||||||
template<typename Type = BReferenceable>
|
template<typename Type>
|
||||||
class BConstReference: public BReference<Type, const Type> {
|
class BReference<const Type> {
|
||||||
public:
|
public:
|
||||||
BConstReference()
|
BReference(Type* object, bool alreadyHasReference = false)
|
||||||
:
|
:
|
||||||
BReference<Type, const Type>()
|
fReference(object, alreadyHasReference)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
BConstReference(Type* object, bool alreadyHasReference = false)
|
BReference(const BReference<const Type>& other)
|
||||||
:
|
:
|
||||||
BReference<Type, const Type>(object, alreadyHasReference)
|
fReference(other)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
BConstReference(const BReference<Type>& other)
|
template<typename OtherType>
|
||||||
|
BReference(const BReference<OtherType>& other)
|
||||||
:
|
:
|
||||||
BReference<Type, const Type>(other)
|
fReference(other.Get())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow assignment of a const reference from a mutable one (but not the
|
void SetTo(Type* object, bool alreadyHasReference = false)
|
||||||
// reverse).
|
|
||||||
BConstReference& operator=(const BReference<Type, Type>& other)
|
|
||||||
{
|
{
|
||||||
SetTo(other.Get());
|
fReference.SetTo(object, alreadyHasReference);
|
||||||
return *this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Unset()
|
||||||
|
{
|
||||||
|
fReference.Unset();
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
BReference& operator=(Type* other)
|
||||||
|
{
|
||||||
|
fReference = other;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename OtherType>
|
||||||
|
BReference& operator=(const BReference<OtherType>& other)
|
||||||
|
{
|
||||||
|
fReference = other.Get();
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user