/* * Copyright 2004-2010, Ingo Weinhold, ingo_weinhold@gmx.de. * Distributed under the terms of the MIT License. */ #ifndef _REFERENCEABLE_H #define _REFERENCEABLE_H #include // #pragma mark - BReferenceable class BReferenceable { public: BReferenceable(); virtual ~BReferenceable(); // acquire and release return // the previous ref count int32 AcquireReference(); int32 ReleaseReference(); int32 CountReferences() const { return fReferenceCount; } protected: virtual void FirstReferenceAcquired(); virtual void LastReferenceReleased(); protected: int32 fReferenceCount; }; // #pragma mark - BReference template class BReference { public: BReference() : fObject(NULL) { } BReference(Type* object, bool alreadyHasReference = false) : fObject(NULL) { SetTo(object, alreadyHasReference); } BReference(const BReference& other) : fObject(NULL) { SetTo(other.Get()); } template BReference(const BReference& other) : fObject(NULL) { SetTo(other.Get()); } ~BReference() { Unset(); } void SetTo(Type* object, bool alreadyHasReference = false) { if (object != NULL && !alreadyHasReference) object->AcquireReference(); Unset(); fObject = object; } void Unset() { if (fObject) { fObject->ReleaseReference(); fObject = NULL; } } Type* Get() const { return fObject; } Type* Detach() { Type* object = fObject; fObject = NULL; return object; } Type& operator*() const { return *fObject; } Type* operator->() const { return fObject; } operator Type*() const { return fObject; } BReference& operator=(const BReference& other) { SetTo(other.fObject); 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; } bool operator==(const Type* other) const { return fObject == other; } bool operator!=(const BReference& other) const { return fObject != other.fObject; } bool operator!=(const Type* other) const { return fObject != other; } private: Type* fObject; }; // #pragma mark - BReference template class BReference { public: BReference(Type* object, bool alreadyHasReference = false) : fReference(object, alreadyHasReference) { } BReference(const BReference& other) : fReference(const_cast(other.Get())) { } template BReference(const BReference& other) : fReference(other.Get()) { } void SetTo(Type* object, bool alreadyHasReference = false) { fReference.SetTo(object, alreadyHasReference); } 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& other) { fReference = other.fReference; return *this; } BReference& operator=(Type* other) { fReference = other; return *this; } template BReference& operator=(const BReference& other) { fReference = other.Get(); return *this; } bool operator==(const BReference& other) const { return fReference == other.Get(); } bool operator==(const Type* other) const { return fReference == other; } bool operator!=(const BReference& other) const { return fReference != other.Get(); } bool operator!=(const Type* other) const { return fReference != other; } private: BReference fReference; }; #endif // _REFERENCEABLE_H