281 lines
6.2 KiB
C
281 lines
6.2 KiB
C
|
/***********************************************************************
|
||
|
*
|
||
|
* 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.
|
||
|
*
|
||
|
* Author: Juan Carlos Luciani <jluciani@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((unsigned long*)&m_Count);
|
||
|
}
|
||
|
|
||
|
bool DecRefCount(void)
|
||
|
{
|
||
|
if ((m_Count > 0) && (InterlockedDecrement((unsigned long*)&m_Count) == 0))
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
unsigned int GetRefCount(void) const
|
||
|
{
|
||
|
return m_Count;
|
||
|
}
|
||
|
|
||
|
//---------------------------------------------------------------------------
|
||
|
// Private data
|
||
|
//
|
||
|
private:
|
||
|
|
||
|
// BUGBUG!! - Need to put a lock in here so the count can be updated atomically.
|
||
|
// or use an interlocked inc/dec if one exists.
|
||
|
mutable unsigned int 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
|
||
|
/******************************************************************************/
|
||
|
/******************************************************************************/
|
||
|
|