/*********************************************************************** * * 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 T> class SmartPtr { //--------------------------------------------------------------------------- // Public interface // public: SmartPtr(); SmartPtr(T* ptr); SmartPtr(const SmartPtr<T>& ref); virtual ~SmartPtr(); operator bool (void) const; bool operator! (void) const; bool operator== (SmartPtr<T>& ref) const; bool operator!= (SmartPtr<T>& ref) const; SmartPtr<T>& operator= (const SmartPtr<T>& ref); SmartPtr<T>& 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<class T> inline SmartPtr<T>::SmartPtr() : m_Ptr(0) { } // End of SmartPtr::SmartPtr() template<class T> inline SmartPtr<T>::SmartPtr(T* ptr) : m_Ptr(0) { resetPtr(ptr); } // End of SmartPtr::SmartPtr() template<class T> inline SmartPtr<T>::SmartPtr(const SmartPtr<T>& ref) : m_Ptr(0) { resetPtr(ref.m_Ptr); } // End of SmartPtr::SmartPtr() template<class T> inline SmartPtr<T>::~SmartPtr() { deleteObject(); } // End of SmartPtr::~SmartPtr() template<class T> inline SmartPtr<T>::operator bool (void) const { return m_Ptr != 0; } // End of SmartPtr::operator bool() template<class T> inline bool SmartPtr<T>::operator! (void) const { return m_Ptr == 0; } // End of SmartPtr::operator!() template<class T> inline bool SmartPtr<T>::operator== (SmartPtr<T>& ref) const { return m_Ptr == ref.m_Ptr; } // End of SmartPtr::operator==() template<class T> inline bool SmartPtr<T>::operator!= (SmartPtr<T>& ref) const { return m_Ptr != ref.m_Ptr; } // End of SmartPtr::operator==() template<class T> inline SmartPtr<T>& SmartPtr<T>::operator= (const SmartPtr<T>& ref) { resetPtr(ref.m_Ptr); return *this; } // End of SmartPtr::operator=() template<class T> inline SmartPtr<T>& SmartPtr<T>::operator= (T* ptr) { resetPtr(ptr); return *this; } // End of SmartPtr::operator=() template<class T> inline T& SmartPtr<T>::operator* (void) const { return *m_Ptr; } // End of SmartPtr::operator*() template<class T> inline T* SmartPtr<T>::operator-> (void) const { return m_Ptr; } // End of SmartPtr::operator->() template<class T> inline SmartPtr<T>::operator T* (void) const { return m_Ptr; } // End of SmartPtr::operator T*() template<class T> inline void SmartPtr<T>::deleteObject(void) { if (m_Ptr && m_Ptr->DecRefCount()) { delete m_Ptr; m_Ptr = 0; } } // End of SmartPtr::deleteObject() template<class T> inline void SmartPtr<T>::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 /******************************************************************************/ /******************************************************************************/