/*********************************************************************** * * Copyright (C) 2006 Novell, Inc. All Rights Reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; version 2.1 * of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, Novell, Inc. * * To contact Novell about this file by physical or electronic mail, * you may find current contact information at www.novell.com. * ***********************************************************************/ #ifndef SMARTPTR_H #define SMARTPTR_H /******************************************************************************* * Include Files *******************************************************************************/ /******************************************************************************* * Definitions *******************************************************************************/ /******************************************************************************* * Types and Classes *******************************************************************************/ //------------------------------------------------------------------------------ // Reference Object // // In order to use the SmartPtr<> class, the object type used to instantiate // the SmartPtr template must inheirit from the ObjRef class. // //------------------------------------------------------------------------------ class ObjRef { //--------------------------------------------------------------------------- // Public interface // public: ObjRef() : m_Count(0) {} void IncRefCount(void) { InterlockedIncrement(&m_Count); } bool DecRefCount(void) { if ((m_Count > 0) && (InterlockedDecrement(&m_Count) == 0)) { return true; } else { return false; } } unsigned int GetRefCount(void) const { return m_Count; } //--------------------------------------------------------------------------- // Private data // private: mutable unsigned long m_Count; }; //------------------------------------------------------------------------------ // SmartPtr Object // //------------------------------------------------------------------------------ template class SmartPtr { //--------------------------------------------------------------------------- // Public interface // public: SmartPtr(); SmartPtr(T* ptr); SmartPtr(const SmartPtr& ref); virtual ~SmartPtr(); operator bool (void) const; bool operator! (void) const; bool operator== (SmartPtr& ref) const; bool operator!= (SmartPtr& ref) const; SmartPtr& operator= (const SmartPtr& ref); SmartPtr& operator= (T* ptr); T& operator* (void) const; T* operator-> (void) const; operator T* (void) const; //--------------------------------------------------------------------------- // Private interface // private: void deleteObject(void); void resetPtr(T* newPtr); //--------------------------------------------------------------------------- // Private data // private: T* m_Ptr; }; template inline SmartPtr::SmartPtr() : m_Ptr(0) { } // End of SmartPtr::SmartPtr() template inline SmartPtr::SmartPtr(T* ptr) : m_Ptr(0) { resetPtr(ptr); } // End of SmartPtr::SmartPtr() template inline SmartPtr::SmartPtr(const SmartPtr& ref) : m_Ptr(0) { resetPtr(ref.m_Ptr); } // End of SmartPtr::SmartPtr() template inline SmartPtr::~SmartPtr() { deleteObject(); } // End of SmartPtr::~SmartPtr() template inline SmartPtr::operator bool (void) const { return m_Ptr != 0; } // End of SmartPtr::operator bool() template inline bool SmartPtr::operator! (void) const { return m_Ptr == 0; } // End of SmartPtr::operator!() template inline bool SmartPtr::operator== (SmartPtr& ref) const { return m_Ptr == ref.m_Ptr; } // End of SmartPtr::operator==() template inline bool SmartPtr::operator!= (SmartPtr& ref) const { return m_Ptr != ref.m_Ptr; } // End of SmartPtr::operator==() template inline SmartPtr& SmartPtr::operator= (const SmartPtr& ref) { resetPtr(ref.m_Ptr); return *this; } // End of SmartPtr::operator=() template inline SmartPtr& SmartPtr::operator= (T* ptr) { resetPtr(ptr); return *this; } // End of SmartPtr::operator=() template inline T& SmartPtr::operator* (void) const { return *m_Ptr; } // End of SmartPtr::operator*() template inline T* SmartPtr::operator-> (void) const { return m_Ptr; } // End of SmartPtr::operator->() template inline SmartPtr::operator T* (void) const { return m_Ptr; } // End of SmartPtr::operator T*() template inline void SmartPtr::deleteObject(void) { if (m_Ptr && m_Ptr->DecRefCount()) { delete m_Ptr; m_Ptr = 0; } } // End of SmartPtr::deleteObject() template inline void SmartPtr::resetPtr(T* newPtr) { if (m_Ptr != newPtr) { deleteObject(); m_Ptr = newPtr; if (m_Ptr) { // New object reference. m_Ptr->IncRefCount(); } } } // End of SmartPtr::resetPtr() #endif // SMARTPTR_H /******************************************************************************/ /******************************************************************************/