ncbiobj.hpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:46k
- /*
- * ===========================================================================
- * 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
- /// a non-null value.
- bool NotEmpty(void) const THROWS_NONE
- {
- return m_Ptr != 0;
- }
- /// Check if pointer is null -- same affect as Empty().
- ///
- /// @sa
- /// Empty()
- bool IsNull(void) const THROWS_NONE
- {
- return m_Ptr == 0;
- }
- /// Operator to test object.
- ///
- /// @return
- /// TRUE if there is a pointer to object; FALSE, otherwise.
- operator bool(void) THROWS_NONE
- {
- return NotEmpty();
- }
- /// Operator to test object -- const version.
- ///
- /// @return
- /// TRUE if there is a pointer to object; FALSE, otherwise.
- operator bool(void) const THROWS_NONE
- {
- return NotEmpty();
- }
- /// Operator to test object.
- ///
- /// @return
- /// TRUE if there is a null pointer to object; FALSE, otherwise.
- bool operator!(void) const THROWS_NONE
- {
- return Empty();
- }
- /// Reset reference object.
- ///
- /// This sets the pointer to object to null, and removes reference
- /// count to object and deletes the object if this is the last reference
- /// to the object.
- /// @sa
- /// Reset(TObjectType*)
- inline
- void Reset(void)
- {
- TObjectType* ptr = m_Ptr;
- if ( ptr ) {
- m_Ptr = 0;
- CRefBase<C>::RemoveReference(ptr);
- }
- }
- /// Reset reference object to new pointer.
- ///
- /// This sets the pointer to object to the new pointer, and removes
- /// reference count to old object and deletes the old object if this is
- /// the last reference to the old object.
- /// @sa
- /// Reset()
- inline
- void Reset(TObjectType* newPtr)
- {
- TObjectType* oldPtr = m_Ptr;
- if ( newPtr != oldPtr ) {
- if ( newPtr )
- CRefBase<C>::AddReference(newPtr);
- m_Ptr = newPtr;
- if ( oldPtr )
- CRefBase<C>::RemoveReference(oldPtr);
- }
- }
- /// Release a reference to the object and return a pointer to the object.
- ///
- /// Releasing a reference means decreasing the reference count by "1". A
- /// pointer to the existing object is returned, unless this pointer is
- /// already null(0), in which case a null(0) is returned.
- ///
- /// Similar to Release(), except that this method returns a null,
- /// whereas Release() throws a null pointer exception.
- ///
- /// @sa
- /// Release()
- inline
- TObjectType* ReleaseOrNull(void)
- {
- TObjectType* ptr = m_Ptr;
- if ( !ptr )
- return 0;
- m_Ptr = 0;
- CRefBase<C>::ReleaseReference(ptr);
- return ptr;
- }
- /// Release a reference to the object and return a pointer to the object.
- ///
- /// Releasing a reference means decreasing the reference count by "1". A
- /// pointer to the existing object is returned, unless this pointer is
- /// already null(0), in which the null pointer exception (eNullPtr) is
- /// thrown.
- ///
- /// Similar to ReleaseOrNull(), except that this method throws an exception
- /// whereas ReleaseOrNull() does not.
- ///
- /// @sa
- /// ReleaseOrNull()
- inline
- TObjectType* Release(void)
- {
- TObjectType* ptr = m_Ptr;
- if ( !ptr ) {
- CObject::ThrowNullPointerException();
- }
- m_Ptr = 0;
- CRefBase<C>::ReleaseReference(ptr);
- return ptr;
- }
- /// Reset reference object to new pointer.
- ///
- /// This sets the pointer to object to the new pointer, and removes
- /// reference count to old object and deletes the old object if this is
- /// the last reference to the old object.
- /// The new pointer is got from ref argument.
- /// Operation is atomic on this object, so that AtomicResetFrom() and
- /// AtomicReleaseTo() called from different threads will work properly.
- /// Operation is not atomic on ref argument.
- /// @sa
- /// AtomicReleaseTo(CRef& ref);
- inline
- void AtomicResetFrom(const CRef& ref)
- {
- TObjectType* ptr = ref.m_Ptr;
- if ( ptr )
- CRefBase<C>::AddReference(ptr); // for this
- TObjectType* old_ptr = AtomicSwap(ptr);
- if ( old_ptr )
- CRefBase<C>::RemoveReference(old_ptr);
- }
- /// Release referenced object to another CRef<> object.
- ///
- /// This copies the pointer to object to the argument ref,
- /// and release reference from this object.
- /// Old reference object held by argument ref is released and deleted if
- /// necessary.
- /// Operation is atomic on this object, so that AtomicResetFrom() and
- /// AtomicReleaseTo() called from different threads will work properly.
- /// Operation is not atomic on ref argument.
- /// @sa
- /// AtomicResetFrom(const CRef& ref);
- inline
- void AtomicReleaseTo(CRef& ref)
- {
- TObjectType* old_ptr = AtomicSwap(0);
- if ( old_ptr ) {
- ref.Reset(old_ptr);
- CRefBase<C>::RemoveReference(old_ptr);
- }
- else {
- ref.Reset();
- }
- }
- /// Assignment operator for references.
- CRef<C>& operator=(const CRef<C>& ref)
- {
- Reset(ref.m_Ptr);
- return *this;
- }
- /// Assignment operator for references with right hand side set to
- /// a pointer.
- CRef<C>& operator=(TObjectType* ptr)
- {
- Reset(ptr);
- return *this;
- }
- /// Assignment operator with right hand side set to ENull.
- CRef<C>& operator=(ENull /*null*/)
- {
- Reset(0);
- return *this;
- }
- /// Get pointer value and throw a null pointer exception if pointer
- /// is null.
- ///
- /// Similar to GetPointerOrNull() except that this method throws a null
- /// pointer exception if pointer is null, whereas GetPointerOrNull()
- /// returns a null value.
- ///
- /// @sa
- /// GetPointerOrNull(), GetPointer(), GetObject()
- inline
- TObjectType* GetNonNullPointer(void)
- {
- TObjectType* ptr = m_Ptr;
- if ( !ptr ) {
- CObject::ThrowNullPointerException();
- }
- return ptr;
- }
- /// Get pointer value.
- ///
- /// Similar to GetNonNullPointer() except that this method returns a null
- /// if the pointer is null, whereas GetNonNullPointer() throws a null
- /// pointer exception.
- ///
- /// @sa
- /// GetNonNullPointer()
- inline
- TObjectType* GetPointerOrNull(void) THROWS_NONE
- {
- return m_Ptr;
- }
- /// Get pointer,
- ///
- /// Same as GetPointerOrNull().
- ///
- /// @sa
- /// GetPointerOrNull()
- inline
- TObjectType* GetPointer(void) THROWS_NONE
- {
- return GetPointerOrNull();
- }
- /// Get object.
- ///
- /// Similar to GetNonNullPointer(), except that this method returns the
- /// object whereas GetNonNullPointer() returns a pointer to the object.
- ///
- /// @sa
- /// GetNonNullPointer()
- inline
- TObjectType& GetObject(void)
- {
- return *GetNonNullPointer();
- }
- /// Dereference operator returning object.
- ///
- /// @sa
- /// GetObject()
- inline
- TObjectType& operator*(void)
- {
- return *GetNonNullPointer();
- }
- /// Reference operator.
- ///
- /// @sa
- /// GetPointer()
- inline
- TObjectType* operator->(void)
- {
- return GetNonNullPointer();
- }
- /// Dereference operator returning pointer.
- ///
- /// @sa
- /// GetPointer()
- inline
- operator TObjectType*(void)
- {
- return GetPointerOrNull();
- }
- // Const getters.
- /// Get pointer value and throw a null pointer exception if pointer
- /// is null -- constant version.
- ///
- /// Similar to GetPointerOrNull() except that this method throws a null
- /// pointer exception if pointer is null, whereas GetPointerOrNull()
- /// returns a null value.
- ///
- /// @sa
- /// GetPointerOrNull(), GetPointer(), GetObject()
- const TObjectType* GetNonNullPointer(void) const
- {
- const TObjectType* ptr = m_Ptr;
- if ( !ptr ) {
- CObject::ThrowNullPointerException();
- }
- return ptr;
- }
- /// Get pointer value -- constant version.
- ///
- /// Similar to GetNonNullPointer() except that this method returns a null
- /// if the pointer is null, whereas GetNonNullPointer() throws a null
- /// pointer exception.
- ///
- /// @sa
- /// GetNonNullPointer()
- const TObjectType* GetPointerOrNull(void) const THROWS_NONE
- {
- return m_Ptr;
- }
- /// Get pointer -- constant version,
- ///
- /// Same as GetPointerOrNull().
- ///
- /// @sa
- /// GetPointerOrNull()
- inline
- const TObjectType* GetPointer(void) const THROWS_NONE
- {
- return GetPointerOrNull();
- }
- /// Get object -- constant version.
- ///
- /// Similar to GetNonNullPointer(), except that this method returns the
- /// object whereas GetNonNullPointer() returns a pointer to the object.
- ///
- /// @sa
- /// GetNonNullPointer()
- inline
- const TObjectType& GetObject(void) const
- {
- return *GetNonNullPointer();
- }
- /// Dereference operator returning object -- constant version.
- ///
- /// @sa
- /// GetObject()
- inline
- const TObjectType& operator*(void) const
- {
- return *GetNonNullPointer();
- }
- /// Reference operator -- constant version.
- ///
- /// @sa
- /// GetPointer()
- inline
- const TObjectType* operator->(void) const
- {
- return GetNonNullPointer();
- }
- /// Dereference operator returning pointer -- constant version.
- ///
- /// @sa
- /// GetPointer()
- inline
- operator const TObjectType*(void) const
- {
- return GetPointerOrNull();
- }
- private:
- TObjectType* AtomicSwap(TObjectType* ptr)
- {
- // MIPSpro won't accept static_cast for some reason.
- return reinterpret_cast<TObjectType*>
- (SwapPointers(const_cast<void*volatile*>(
- reinterpret_cast<void**>(&m_Ptr)),
- ptr));
- }
- TObjectType* m_Ptr; ///< Pointer to object
- };
- /////////////////////////////////////////////////////////////////////////////
- ///
- /// CConstRef --
- ///
- /// Define a template class that stores a pointer to an object and defines
- /// methods for constant referencing of object.
- template<class C>
- class CConstRef {
- public:
- typedef C element_type; ///< Define alias element_type
- typedef const element_type TObjectType; ///< Define alias TObjectType
- /// Constructor for null pointer.
- inline
- CConstRef(void) THROWS_NONE
- : m_Ptr(0)
- {
- }
- /// Constructor for ENull pointer.
- inline
- CConstRef(ENull /*null*/) THROWS_NONE
- : m_Ptr(0)
- {
- }
- /// Constructor for explicit type conversion from pointer to object.
- explicit CConstRef(TObjectType* ptr)
- {
- if ( ptr )
- CRefBase<C>::AddReference(ptr);
- m_Ptr = ptr;
- }
- /// Constructor from an existing CRef object,
- CConstRef(const CConstRef<C>& ref)
- {
- TObjectType* ptr = ref.m_Ptr;
- if ( ptr )
- CRefBase<C>::AddReference(ptr);
- m_Ptr = ptr;
- }
- /// Constructor from an existing CRef object,
- CConstRef(const CRef<C>& ref)
- {
- TObjectType* ptr = ref.GetPointerOrNull();
- if ( ptr )
- CRefBase<C>::AddReference(ptr);
- m_Ptr = ptr;
- }
- /// Destructor.
- ~CConstRef(void)
- {
- TObjectType* ptr = m_Ptr;
- if ( ptr )
- CRefBase<C>::RemoveReference(ptr);
- }
-
- /// Check if CConstRef 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 CConstRef is not empty -- pointing to an object and has
- /// a non-null value.
- bool NotEmpty(void) const THROWS_NONE
- {
- return m_Ptr != 0;
- }
- /// Check if pointer is null -- same affect as Empty().
- ///
- /// @sa
- /// Empty()
- bool IsNull(void) const THROWS_NONE
- {
- return m_Ptr == 0;
- }
- /// Operator to test object.
- ///
- /// @return
- /// TRUE if there is a pointer to object; FALSE, otherwise.
- operator bool(void) THROWS_NONE
- {
- return NotEmpty();
- }
- /// Operator to test object.
- ///
- /// @return
- /// TRUE if there is a pointer to object; FALSE, otherwise.
- operator bool(void) const THROWS_NONE
- {
- return NotEmpty();
- }
- /// Operator to test object -- const version.
- ///
- /// @return
- /// TRUE if there is a null pointer to object; FALSE, otherwise.
- bool operator!(void) const THROWS_NONE
- {
- return Empty();
- }
- /// Reset reference object.
- ///
- /// This sets the pointer to object to null, and removes reference
- /// count to object and deletes the object if this is the last reference
- /// to the object.
- /// @sa
- /// Reset(TObjectType*)
- inline
- void Reset(void)
- {
- TObjectType* ptr = m_Ptr;
- if ( ptr ) {
- m_Ptr = 0;
- CRefBase<C>::RemoveReference(ptr);
- }
- }
- /// Reset reference object to new pointer.
- ///
- /// This sets the pointer to object to the new pointer, and removes
- /// reference count to old object and deletes the old object if this is
- /// the last reference to the old object.
- /// @sa
- /// Reset()
- inline
- void Reset(TObjectType* newPtr)
- {
- TObjectType* oldPtr = m_Ptr;
- if ( newPtr != oldPtr ) {
- if ( newPtr )
- CRefBase<C>::AddReference(newPtr);
- m_Ptr = newPtr;
- if ( oldPtr )
- CRefBase<C>::RemoveReference(oldPtr);
- }
- }
- /// Release a reference to the object and return a pointer to the object.
- ///
- /// Releasing a reference means decreasing the reference count by "1". A
- /// pointer to the existing object is returned, unless this pointer is
- /// already null(0), in which case a null(0) is returned.
- ///
- /// Similar to Release(), except that this method returns a null,
- /// whereas Release() throws a null pointer exception.
- ///
- /// @sa
- /// Release()
- inline
- TObjectType* ReleaseOrNull(void)
- {
- TObjectType* ptr = m_Ptr;
- if ( !ptr )
- return 0;
- m_Ptr = 0;
- CRefBase<C>::ReleaseReference(ptr);
- return ptr;
- }
- /// Release a reference to the object and return a pointer to the object.
- ///
- /// Releasing a reference means decreasing the reference count by "1". A
- /// pointer to the existing object is returned, unless this pointer is
- /// already null(0), in which the null pointer exception (eNullPtr) is
- /// thrown.
- ///
- /// Similar to ReleaseOrNull(), except that this method throws an exception
- /// whereas ReleaseOrNull() does not.
- ///
- /// @sa
- /// ReleaseOrNull()
- inline
- TObjectType* Release(void)
- {
- TObjectType* ptr = m_Ptr;
- if ( !ptr ) {
- CObject::ThrowNullPointerException();
- }
- m_Ptr = 0;
- CRefBase<C>::ReleaseReference(ptr);
- return ptr;
- }
- /// Reset reference object to new pointer.
- ///
- /// This sets the pointer to object to the new pointer, and removes
- /// reference count to old object and deletes the old object if this is
- /// the last reference to the old object.
- /// The new pointer is got from ref argument.
- /// Operation is atomic on this object, so that AtomicResetFrom() and
- /// AtomicReleaseTo() called from different threads will work properly.
- /// Operation is not atomic on ref argument.
- /// @sa
- /// AtomicReleaseTo(CConstRef& ref);
- inline
- void AtomicResetFrom(const CConstRef& ref)
- {
- TObjectType* ptr = ref.m_Ptr;
- if ( ptr )
- CRefBase<C>::AddReference(ptr); // for this
- TObjectType* old_ptr = AtomicSwap(ptr);
- if ( old_ptr )
- CRefBase<C>::RemoveReference(old_ptr);
- }
- /// Release referenced object to another CConstRef<> object.
- ///
- /// This copies the pointer to object to the argument ref,
- /// and release reference from this object.
- /// Old reference object held by argument ref is released and deleted if
- /// necessary.
- /// Operation is atomic on this object, so that AtomicResetFrom() and
- /// AtomicReleaseTo() called from different threads will work properly.
- /// Operation is not atomic on ref argument.
- /// @sa
- /// AtomicResetFrom(const CConstRef& ref);
- inline
- void AtomicReleaseTo(CConstRef& ref)
- {
- TObjectType* old_ptr = AtomicSwap(0);
- if ( old_ptr ) {
- ref.Reset(old_ptr);
- CRefBase<C>::RemoveReference(old_ptr);
- }
- else {
- ref.Reset();
- }
- }
- /// Assignment operator for const references.
- CConstRef<C>& operator=(const CConstRef<C>& ref)
- {
- Reset(ref.m_Ptr);
- return *this;
- }
- /// Assignment operator for assigning a reference to a const reference.
- CConstRef<C>& operator=(const CRef<C>& ref)
- {
- Reset(ref.GetPointerOrNull());
- return *this;
- }
- /// Assignment operator for const references with right hand side set to
- /// a pointer.
- CConstRef<C>& operator=(TObjectType* ptr)
- {
- Reset(ptr);
- return *this;
- }
- /// Assignment operator with right hand side set to ENull.
- CConstRef<C>& operator=(ENull /*null*/)
- {
- Reset(0);
- return *this;
- }
- /// Get pointer value and throw a null pointer exception if pointer
- /// is null.
- ///
- /// Similar to GetPointerOrNull() except that this method throws a null
- /// pointer exception if pointer is null, whereas GetPointerOrNull()
- /// returns a null value.
- ///
- /// @sa
- /// GetPointerOrNull(), GetPointer(), GetObject()
- inline
- TObjectType* GetNonNullPointer(void) const
- {
- TObjectType* ptr = m_Ptr;
- if ( !ptr ) {
- CObject::ThrowNullPointerException();
- }
- return ptr;
- }
- /// Get pointer value.
- ///
- /// Similar to GetNonNullPointer() except that this method returns a null
- /// if the pointer is null, whereas GetNonNullPointer() throws a null
- /// pointer exception.
- ///
- /// @sa
- /// GetNonNullPointer()
- inline
- TObjectType* GetPointerOrNull(void) const THROWS_NONE
- {
- return m_Ptr;
- }
- /// Get pointer,
- ///
- /// Same as GetPointerOrNull().
- ///
- /// @sa
- /// GetPointerOrNull()
- inline
- TObjectType* GetPointer(void) const THROWS_NONE
- {
- return GetPointerOrNull();
- }
- /// Get object.
- ///
- /// Similar to GetNonNullPointer(), except that this method returns the
- /// object whereas GetNonNullPointer() returns a pointer to the object.
- ///
- /// @sa
- /// GetNonNullPointer()
- inline
- TObjectType& GetObject(void) const
- {
- return *GetNonNullPointer();
- }
- /// Dereference operator returning object.
- ///
- /// @sa
- /// GetObject()
- inline
- TObjectType& operator*(void) const
- {
- return *GetNonNullPointer();
- }
- /// Reference operator.
- ///
- /// @sa
- /// GetPointer()
- inline
- TObjectType* operator->(void) const
- {
- return GetNonNullPointer();
- }
- /// Dereference operator returning pointer.
- ///
- /// @sa
- /// GetPointer()
- inline
- operator TObjectType*(void) const
- {
- return GetPointerOrNull();
- }
- private:
- TObjectType* AtomicSwap(TObjectType* ptr)
- {
- // MIPSpro won't accept static_cast for some reason.
- return reinterpret_cast<TObjectType*>
- (SwapPointers(const_cast<void*volatile*>(
- const_cast<void**>(
- reinterpret_cast<const void**>(&m_Ptr))),
- const_cast<C*>(ptr)));
- }
- TObjectType* m_Ptr; ///< Pointer to object
- };
- /// Template operator < function for CRef objects.
- template<class T>
- inline
- bool operator< (const CRef<T>& r1, const CRef<T>& r2)
- {
- return r1.GetPointerOrNull() < r2.GetPointerOrNull();
- }
- /// Template operator > function for CRef objects.
- template<class T>
- inline
- bool operator> (const CRef<T>& r1, const CRef<T>& r2)
- {
- return r1.GetPointerOrNull() > r2.GetPointerOrNull();
- }
- /// Template operator == function for CRef objects -- rhs is null.
- template<class T>
- inline
- bool operator== (const CRef<T>& r1, ENull /*null*/)
- {
- return r1.IsNull();
- }
- /// Template operator == function for CRef objects -- lhs is null.
- template<class T>
- inline
- bool operator== (ENull /*null*/, const CRef<T>& r1)
- {
- return r1.IsNull();
- }
- /// Template operator != function for CRef objects -- rhs is null.
- template<class T>
- inline
- bool operator!= (const CRef<T>& r1, ENull /*null*/)
- {
- return !r1.IsNull();
- }
- /// Template operator != function for CRef objects -- lhs is null.
- template<class T>
- inline
- bool operator!= (ENull /*null*/, const CRef<T>& r1)
- {
- return !r1.IsNull();
- }
- /// Template operator < function for CConstRef objects.
- template<class T>
- inline
- bool operator< (const CConstRef<T>& r1, const CConstRef<T>& r2)
- {
- return r1.GetPointerOrNull() < r2.GetPointerOrNull();
- }
- /// Template operator > function for CConstRef objects.
- template<class T>
- inline
- bool operator> (const CConstRef<T>& r1, const CConstRef<T>& r2)
- {
- return r1.GetPointerOrNull() > r2.GetPointerOrNull();
- }
- /// Template operator == function for CConstRef objects -- rhs is null.
- template<class T>
- inline
- bool operator== (const CConstRef<T>& r1, ENull /*null*/)
- {
- return r1.IsNull();
- }
- /// Template operator == function for CConstRef objects -- lhs is null.
- template<class T>
- inline
- bool operator== (ENull /*null*/, const CConstRef<T>& r1)
- {
- return r1.IsNull();
- }
- /// Template operator != function for CConstRef objects -- rhs is null.
- template<class T>
- inline
- bool operator!= (const CConstRef<T>& r1, ENull /*null*/)
- {
- return !r1.IsNull();
- }
- /// Template operator != function for CConstRef objects -- lhs is null.
- template<class T>
- inline
- bool operator!= (ENull /*null*/, const CConstRef<T>& r1)
- {
- return !r1.IsNull();
- }
- /// Template operator == function for CRef objects.
- template<class T>
- inline
- bool operator== (const CRef<T>& r1, const CRef<T>& r2)
- {
- return r1.GetPointerOrNull() == r2.GetPointerOrNull();
- }
- /// Template operator == function for CConstRef objects.
- template<class T>
- inline
- bool operator== (const CConstRef<T>& r1, const CConstRef<T>& r2)
- {
- return r1.GetPointerOrNull() == r2.GetPointerOrNull();
- }
- /// Template operator == function for CConstRef and CRef objects.
- template<class T>
- inline
- bool operator== (const CConstRef<T>& r1, const CRef<T>& r2)
- {
- return r1.GetPointerOrNull() == r2.GetPointerOrNull();
- }
- /// Template operator == function for CRef and CConstRef objects.
- template<class T>
- inline
- bool operator== (const CRef<T>& r1, const CConstRef<T>& r2)
- {
- return r1.GetPointerOrNull() == r2.GetPointerOrNull();
- }
- /// Template operator == function for CRef and CRef objects.
- template<class T>
- inline
- bool operator!= (const CRef<T>& r1, const CRef<T>& r2)
- {
- return r1.GetPointerOrNull() != r2.GetPointerOrNull();
- }
- /// Template operator != function for CConstRef objects.
- template<class T>
- inline
- bool operator!= (const CConstRef<T>& r1, const CConstRef<T>& r2)
- {
- return r1.GetPointerOrNull() != r2.GetPointerOrNull();
- }
- /// Template operator != function for CConstRef and CRef objects.
- template<class T>
- inline
- bool operator!= (const CConstRef<T>& r1, const CRef<T>& r2)
- {
- return r1.GetPointerOrNull() != r2.GetPointerOrNull();
- }
- /// Template operator != function for CRef and CConstRef objects.
- template<class T>
- inline
- bool operator!= (const CRef<T>& r1, const CConstRef<T>& r2)
- {
- return r1.GetPointerOrNull() != r2.GetPointerOrNull();
- }
- /// Template function for conversion of object pointer to CRef
- template<class C>
- inline
- CRef<C> Ref(C* object)
- {
- return CRef<C>(object);
- }
- /// Template function for conversion of const object pointer to CConstRef
- template<class C>
- inline
- CConstRef<C> ConstRef(const C* object)
- {
- return CConstRef<C>(object);
- }
- /////////////////////////////////////////////////////////////////////////////
- ///
- /// CObjectFor --
- ///
- /// Define a template class whose template parameter is a standard data type
- /// that will be pointed to.
- ///
- /// The template class defines a private data member of the same type as the
- /// template parameter, and accessor methods GetData() to retrieve the value
- /// of this private data member. The class is derived from CObject and
- /// therefore inherits the reference counter defined in that class. In essence,
- /// this class serves as a "wrapper" class for standard data types allowing
- /// reference counted smart pointers to be used for standard data types.
- template<typename T>
- class CObjectFor : public CObject
- {
- public:
- typedef T TObjectType; ///< Define alias for template parameter
- /// Get data as a reference.
- T& GetData(void)
- {
- return m_Data;
- }
- /// Get data as a reference -- const version.
- const T& GetData(void) const
- {
- return m_Data;
- }
- /// Operator () to get data -- same as GetData().
- ///
- /// @sa
- /// GetData()
- operator T& (void)
- {
- return GetData();
- }
- /// Operator () to get data -- const version, same as GetData().
- ///
- /// @sa
- /// GetData()
- operator const T& (void) const
- {
- return GetData();
- }
- /// Assignment operator.
- T& operator=(const T& data)
- {
- m_Data = data;
- return *this;
- }
- private:
- T m_Data; ///< Data member of template parameter type
- };
- /* @} */
- #include <corelib/ncbiobj.inl>
- END_NCBI_SCOPE
- /*
- * ===========================================================================
- * $Log: ncbiobj.hpp,v $
- * Revision 1000.1 2004/04/13 19:57:54 gouriano
- * PRODUCTION: UPGRADED [CATCHUP_003] Dev-tree R1.56
- *
- * Revision 1.56 2004/04/06 20:34:23 grichenk
- * Added atomic release and reset to CRef.
- *
- * Revision 1.55 2004/03/10 18:40:21 gorelenk
- * Added/Removed NCBI_XNCBI_EXPORT prefixes.
- *
- * Revision 1.54 2004/03/10 17:34:05 gorelenk
- * Removed NCBI_XNCBI_EXPORT prefix for classes members-functions
- * that are implemented as a inline functions.
- *
- * Revision 1.53 2003/10/20 20:07:10 siyan
- * Added CORELIB___ prefix in conditional includes.
- *
- * Revision 1.52 2003/10/01 00:24:02 ucko
- * CConstRef::AtomicSwap: use reinterpret_cast rather than static_cast to
- * placate MIPSpro.
- *
- * Revision 1.51 2003/09/17 17:57:38 vasilche
- * Added Ref() and ConstRef() templated functions for getting CRef<> objects.
- *
- * Revision 1.50 2003/09/17 15:20:45 vasilche
- * Moved atomic counter swap functions to separate file.
- * Added CRef<>::AtomicResetFrom(), CRef<>::AtomicReleaseTo() methods.
- *
- * Revision 1.49 2003/08/12 13:35:50 siyan
- * Minor comment changes.
- *
- * Revision 1.48 2003/08/12 12:03:48 siyan
- * Added documentation. Change private method name from AddReferenceOverflow()
- * to a more meaningful name of its purpose, CheckReferenceOverflow().
- *
- * Revision 1.47 2003/07/17 23:00:50 vasilche
- * Added matching operator delete.
- *
- * Revision 1.46 2003/07/17 20:01:06 vasilche
- * Added inplace operator new().
- *
- * Revision 1.45 2003/05/18 04:47:09 vakatov
- * Rollback to R1.43, as R1.44 created another, more problematic warning --
- * that "operator T*()" would be chosen over "operator bool()" for non-const
- *
- * Revision 1.43 2003/04/01 14:19:58 siyan
- * Added doxygen support
- *
- * Revision 1.42 2002/12/18 22:53:21 dicuccio
- * Added export specifier for building DLLs in windows. Added global list of
- * all such specifiers in mswin_exports.hpp, included through ncbistl.hpp
- *
- * Revision 1.41 2002/11/27 12:53:14 dicuccio
- * Added CObject::ThrowNullPointerException to get around some inlining issues.
- * Fixed a few returns (m_Ptr -> ptr).
- *
- * Revision 1.40 2002/11/26 14:25:34 dicuccio
- * Added more explicit error reporting for thrown exceptions.
- *
- * Revision 1.39 2002/11/08 19:43:29 grichenk
- * CConstRef<> constructor made explicit
- *
- * Revision 1.38 2002/11/04 21:30:53 grichenk
- * Made CRef<> constructor explicit, const CRef<> getters
- * return const references/pointers.
- *
- * Revision 1.37 2002/09/19 20:05:41 vasilche
- * Safe initialization of static mutexes
- *
- * Revision 1.36 2002/08/28 17:05:50 vasilche
- * Remove virtual inheritance, fixed heap detection
- *
- * Revision 1.35 2002/07/15 18:17:51 gouriano
- * renamed CNcbiException and its descendents
- *
- * Revision 1.34 2002/07/11 14:17:55 gouriano
- * exceptions replaced by CNcbiException-type ones
- *
- * Revision 1.33 2002/05/31 15:16:51 gouriano
- * more unsigned ints in EObjectState flags
- *
- * Revision 1.32 2002/05/30 18:32:14 gouriano
- * changed eStateBitsValid to "unsigned int" to make some compilers happy
- *
- * Revision 1.31 2002/05/23 22:24:21 ucko
- * Use low-level atomic operations for reference counts
- *
- * Revision 1.30 2002/05/17 14:25:40 gouriano
- * added DebugDump base class and function to CObject
- *
- * Revision 1.29 2002/05/14 21:12:59 gouriano
- * DebugDump moved into a separate class
- *
- * Revision 1.28 2002/05/14 14:42:13 gouriano
- * added DebugDump function to CObject
- *
- * Revision 1.27 2002/04/11 20:39:18 ivanov
- * CVS log moved to end of the file
- *
- * Revision 1.26 2001/10/10 04:03:22 vakatov
- * Added operator> for C(Const)Ref -- for ICC and MIPSpro
- *
- * Revision 1.25 2001/06/21 15:17:42 kholodov
- * Added: null special value, support for null in CRef classes, equality
- * operators.
- *
- * Revision 1.24 2001/06/13 14:19:54 grichenk
- * Added operators == and != for C(Const)Ref
- *
- * Revision 1.23 2001/05/17 14:53:56 lavr
- * Typos corrected
- *
- * Revision 1.22 2001/03/26 21:22:51 vakatov
- * Minor cosmetics
- *
- * Revision 1.21 2001/03/13 22:43:48 vakatov
- * Made "CObject" MT-safe
- * + CObject::DoDeleteThisObject()
- *
- * Revision 1.20 2001/03/05 22:14:18 vakatov
- * Added "operator<" for CRef:: and CConstRef:: to make them usable
- * as keys in the stnadard C++ associative containers (set, map, ...)
- *
- * Revision 1.19 2001/02/21 21:16:08 grichenk
- * CRef:: Release, Reset -- reset m_Ptr BEFORE removing the reference
- *
- * Revision 1.18 2000/12/26 17:25:38 vasilche
- * CRef<> returns non const object.
- *
- * Revision 1.17 2000/12/15 19:18:36 vakatov
- * Added assignment operator for CRef<> and CConstRef<>
- *
- * Revision 1.16 2000/12/15 15:36:29 vasilche
- * Added header corelib/ncbistr.hpp for all string utility functions.
- * Optimized string utility functions.
- * Added assignment operator to CRef<> and CConstRef<>.
- * Add Upcase() and Locase() methods for automatic conversion.
- *
- * Revision 1.15 2000/12/12 14:20:14 vasilche
- * Added operator bool to CArgValue.
- * Added standard typedef element_type to CRef<> and CConstRef<>.
- * Macro iterate() now calls method end() only once and uses temporary variabl.
- * Various NStr::Compare() methods made faster.
- * Added class Upcase for printing strings to ostream with automatic conversion
- *
- * Revision 1.14 2000/11/01 20:35:01 vasilche
- * Fixed detection of heap objects.
- * Removed ECanDelete enum and related constructors.
- *
- * Revision 1.13 2000/10/13 16:25:43 vasilche
- * Added heuristic for detection of CObject allocation in heap.
- *
- * Revision 1.12 2000/09/01 13:14:25 vasilche
- * Fixed throw() declaration in CRef/CConstRef
- *
- * Revision 1.11 2000/08/15 19:42:06 vasilche
- * Changed reference counter to allow detection of more errors.
- *
- * Revision 1.10 2000/06/16 16:29:42 vasilche
- * Added SetCanDelete() method to allow to change CObject 'in heap' status
- * immediately after creation.
- *
- * Revision 1.9 2000/06/07 19:44:16 vasilche
- * Removed unneeded THROWS declaration - they lead to encreased code size.
- *
- * Revision 1.8 2000/05/09 16:36:54 vasilche
- * CObject::GetTypeInfo now moved to CObjectGetTypeInfo::GetTypeInfo to reduce
- * possible errors.
- *
- * Revision 1.7 2000/04/28 16:56:13 vasilche
- * Fixed implementation of CRef<> and CConstRef<>
- *
- * Revision 1.6 2000/03/31 17:08:07 kans
- * moved ECanDelete to public area of CObject
- *
- * Revision 1.5 2000/03/29 15:50:27 vasilche
- * Added const version of CRef - CConstRef.
- * CRef and CConstRef now accept classes inherited from CObject.
- *
- * Revision 1.4 2000/03/10 14:18:37 vasilche
- * Added CRef<>::GetPointerOrNull() method similar to std::auto_ptr<>.get()
- *
- * Revision 1.3 2000/03/08 14:18:19 vasilche
- * Fixed throws instructions.
- *
- * Revision 1.2 2000/03/07 15:25:42 vasilche
- * Fixed implementation of CRef::->
- *
- * Revision 1.1 2000/03/07 14:03:11 vasilche
- * Added CObject class as base for reference counted objects.
- * Added CRef templace for reference to CObject descendant.
- *
- * ==========================================================================
- */
- #endif /* NCBIOBJ__HPP */