📄 ncbiobj.hpp
字号:
/* * =========================================================================== * PRODUCTION $Log: ncbiobj.hpp,v $ * PRODUCTION Revision 1000.1 2004/04/13 19:57:54 gouriano * PRODUCTION PRODUCTION: UPGRADED [CATCHUP_003] Dev-tree R1.56 * PRODUCTION * =========================================================================== */#ifndef CORELIB___NCBIOBJ__HPP#define CORELIB___NCBIOBJ__HPP/* $Id: ncbiobj.hpp,v 1000.1 2004/04/13 19:57:54 gouriano Exp $ * =========================================================================== * * PUBLIC DOMAIN NOTICE * National Center for Biotechnology Information * * This software/database is a "United States Government Work" under the * terms of the United States Copyright Act. It was written as part of * the author's official duties as a United States Government employee and * thus cannot be copyrighted. This software/database is freely available * to the public for use. The National Library of Medicine and the U.S. * Government have not placed any restriction on its use or reproduction. * * Although all reasonable efforts have been taken to ensure the accuracy * and reliability of the software and data, the NLM and the U.S. * Government do not and cannot warrant the performance or results that * may be obtained by using this software or data. The NLM and the U.S. * Government disclaim all warranties, express or implied, including * warranties of performance, merchantability or fitness for any particular * purpose. * * Please cite the author in any work or product based on this material. * * =========================================================================== * * Author: Eugene Vasilchenko * * *//// @file ncbiobj.hpp/// Portable reference counted smart pointers using CRef and CObject.#include <corelib/ncbistd.hpp>#include <corelib/ncbicntr.hpp>#include <corelib/ncbiatomic.hpp>#include <corelib/ddumpable.hpp>/** @addtogroup Object * * @{ */BEGIN_NCBI_SCOPE/// Define "null" pointer value.enum ENull { null = 0};/////////////////////////////////////////////////////////////////////////////////// CObjectException --////// Define exceptions generated by CObject.////// CObjectException inherits its basic functionality from CCoreException/// and defines additional error codes.class NCBI_XNCBI_EXPORT CObjectException : public CCoreException{public: /// Error types that an application can generate. enum EErrCode { eRefDelete, ///< Attempt to delete valid reference eDeleted, ///< Attempt to delete a deleted object eCorrupted, ///< Object corrupted error eRefOverflow, ///< Reference overflow error eNoRef, ///< Attempt to access an object that is unreferenced eRefUnref ///< Attempt to make a referenced object an ///< unreferenced one }; /// Translate from the error code value to its string representation. virtual const char* GetErrCodeString(void) const { switch (GetErrCode()) { case eRefDelete: return "eRefDelete"; case eDeleted: return "eDeleted"; case eCorrupted: return "eCorrupted"; case eRefOverflow: return "eRefOverflow"; case eNoRef: return "eNoRef"; case eRefUnref: return "eRefUnref"; default: return CException::GetErrCodeString(); } } // Standard exception boilerplate code. NCBI_EXCEPTION_DEFAULT(CObjectException, CCoreException);protected: void x_InitErrCode(CException::EErrCode err_code);};/////////////////////////////////////////////////////////////////////////////////// CObject --////// Define the CObject which stores the reference count and the object.////// CObject inherits from CDebugDumpable the ability to "dump" diagnostic/// information useful for debugging.class CObject : public CDebugDumpable{public: /// Constructor. NCBI_XNCBI_EXPORT CObject(void); /// Copy constructor. NCBI_XNCBI_EXPORT CObject(const CObject& src); /// Destructor. NCBI_XNCBI_EXPORT virtual ~CObject(void); /// Assignment operator. CObject& operator=(const CObject& src) THROWS_NONE; /// Check if object can be deleted. bool CanBeDeleted(void) const THROWS_NONE; /// Check if object is referenced. bool Referenced(void) const THROWS_NONE; /// Check if object is referenced only once. bool ReferencedOnlyOnce(void) const THROWS_NONE; /// Add reference to object. void AddReference(void) const; /// Remove reference to object. void RemoveReference(void) const; /// Remove reference without deleting object. NCBI_XNCBI_EXPORT void ReleaseReference(void) const; /// Mark this object as not allocated in heap -- do not delete this /// object. NCBI_XNCBI_EXPORT virtual void DoNotDeleteThisObject(void); /// Mark this object as allocated in heap -- object can be deleted. NCBI_XNCBI_EXPORT virtual void DoDeleteThisObject(void); // operators new/delete for additional checking in debug mode /// Define new operator for memory allocation. NCBI_XNCBI_EXPORT void* operator new(size_t size); /// Define new[] operator for 'array' memory allocation. NCBI_XNCBI_EXPORT void* operator new[](size_t size); /// Define delete operator for memory deallocation. NCBI_XNCBI_EXPORT void operator delete(void* ptr); /// Define delete[] operator for memory deallocation. NCBI_XNCBI_EXPORT void operator delete[](void* ptr); /// Define new operator. NCBI_XNCBI_EXPORT void* operator new(size_t size, void* place); /// Define delete operator. NCBI_XNCBI_EXPORT void operator delete(void* ptr, void* place); /// Define method for dumping debug information. NCBI_XNCBI_EXPORT virtual void DebugDump(CDebugDumpContext ddc, unsigned int depth) const; /// Define method to throw null pointer exception. /// /// Static method through which all CRef<> / CConstRef<> null pointer /// throws travel. This is done to avoid an inline throw. NCBI_XNCBI_EXPORT static void ThrowNullPointerException(void);private: typedef CAtomicCounter TCounter; ///< Counter type is CAtomiCounter typedef TCounter::TValue TCount; ///< Alias for value type of counter /// Define possible object states. /// /// When TCounter is signed, all valid values start with 01; /// when it is unsigned, they start with 1. In other words, when /// TCounter is signed, the msb (most significant bit) is 0, and the bit /// after that is a 1; and if the counter is unsigned, then the msb is 1. /// /// Least significant bit is the "heap" bit and the most significant bit /// (or the one after it) is the "valid" bit. /// /// The following bit positions have special signifcance: /// - Least significant bit = 0 means object not in heap. /// - Least significant bit = 1 means object in heap. /// - Most significant bit (or one after it) = 0 means object not valid /// - Most significant bit (or one after it) = 1 means object is valid /// /// Possible bit patterns: /// - [0]0x...xxx : non valid object -> cannot be referenced. /// - [0]1c...cc0 : object not in heap -> cannot be referenced. /// - [0]1c...cc1 : object in heap -> can be referenced. enum EObjectState { eStateBitsInHeap = 1 << 0,#ifdef NCBI_COUNTER_UNSIGNED eStateBitsValid = (unsigned int)(1 << (sizeof(TCount) * 8 - 1)), ///< 1 in the left most of the valid bits -- unsigned case#else eStateBitsValid = (unsigned int)(1 << (sizeof(TCount) * 8 - 2)), ///< 1 in the left most of the valid bits -- signed case#endif eStateMask = eStateBitsValid | eStateBitsInHeap, ///< Valid object, and object in heap. eCounterStep = 1 << 1, ///< Shift one bit left over the "heap" bit eCounterNotInHeap = eStateBitsValid, ///< Mask for testing if counter is for valid object, not in heap eCounterInHeap = eStateBitsValid | eStateBitsInHeap, ///< Mask for testing if counter is for valid object, in heap eCounterValid = eStateBitsValid, ///< Mask for testing if counter is for a valid object eSpecialValueMask = (unsigned int)eStateBitsValid - (unsigned int)eCounterStep, ///< Special mask value: lsb two bits 0, and msb (or one bit after) ///< is 0 and all other bits are 1 eCounterDeleted = (unsigned int)(0x5b4d9f34 & eSpecialValueMask), ///< Mask for testing if counter is for a deleted object eCounterNew = (unsigned int)(0x3423cb13 & eSpecialValueMask) ///< Mask for testing if counter is for a new object }; // special methods for parsing object state number /// Check if object state is valid. static bool ObjectStateValid(TCount count); /// Check if object can be deleted. static bool ObjectStateCanBeDeleted(TCount count); /// Check if object can be referenced. static bool ObjectStateReferenced(TCount count); /// Check if object can be double referenced. static bool ObjectStateDoubleReferenced(TCount count); /// Check if object can be referenced only once. static bool ObjectStateReferencedOnlyOnce(TCount count); /// Initialize counter. void InitCounter(void); /// Remove the last reference. NCBI_XNCBI_EXPORT void RemoveLastReference(void) const; // report different kinds of error /// Report object is invalid. /// /// Example: Attempt to use a deleted object. void InvalidObject(void) const; /// Report that counter has overflowed. NCBI_XNCBI_EXPORT void CheckReferenceOverflow(TCount count) const; mutable TCounter m_Counter; ///< The actual reference counter};/////////////////////////////////////////////////////////////////////////////////// CRefBase --////// Define a template class for adding, removing, and releasing references.template<class C>class CRefBase{public: /// Add reference to specified object. static void AddReference(const C* object) { object->AddReference(); } /// Remove reference from specified object. static void RemoveReference(const C* object) { object->RemoveReference(); } /// Release reference from specified object. static void ReleaseReference(const C* object) { object->ReleaseReference(); }};/////////////////////////////////////////////////////////////////////////////////// CRef --////// Define a template class that stores a pointer to an object and defines/// methods for referencing that object.template<class C>class CRef {public: typedef C element_type; ///< Define alias element_type typedef element_type TObjectType; ///< Define alias TObjectType /// Constructor for null pointer. inline CRef(void) THROWS_NONE : m_Ptr(0) { } /// Constructor for ENull pointer. inline CRef(ENull /*null*/) THROWS_NONE : m_Ptr(0) { } /// Constructor for explicit type conversion from pointer to object. explicit CRef(TObjectType* ptr) { if ( ptr ) CRefBase<C>::AddReference(ptr); m_Ptr = ptr; } /// Copy constructor from an existing CRef object, CRef(const CRef<C>& ref) { TObjectType* ptr = ref.m_Ptr; if ( ptr ) CRefBase<C>::AddReference(ptr); m_Ptr = ptr; } /// Destructor. ~CRef(void) { TObjectType* ptr = m_Ptr; if ( ptr ) CRefBase<C>::RemoveReference(ptr); } /// Check if CRef is empty -- not pointing to any object, which means /// having a null value. /// /// @sa /// IsNull() bool Empty(void) const THROWS_NONE { return m_Ptr == 0; } /// Check if CRef is not empty -- pointing to an object and has
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -