1
This commit is contained in:
279
public/tier1/smartptr.h
Normal file
279
public/tier1/smartptr.h
Normal file
@ -0,0 +1,279 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef SMARTPTR_H
|
||||
#define SMARTPTR_H
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
class CRefCountAccessor
|
||||
{
|
||||
public:
|
||||
template< class T >
|
||||
static void AddRef( T *pObj )
|
||||
{
|
||||
pObj->AddRef();
|
||||
}
|
||||
|
||||
template< class T >
|
||||
static void Release( T *pObj )
|
||||
{
|
||||
pObj->Release();
|
||||
}
|
||||
};
|
||||
|
||||
// This can be used if your objects use AddReference/ReleaseReference function names.
|
||||
class CRefCountAccessorLongName
|
||||
{
|
||||
public:
|
||||
template< class T >
|
||||
static void AddRef( T *pObj )
|
||||
{
|
||||
pObj->AddReference();
|
||||
}
|
||||
|
||||
template< class T >
|
||||
static void Release( T *pObj )
|
||||
{
|
||||
pObj->ReleaseReference();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// CPlainAutoPtr
|
||||
// is a smart wrapper for a pointer on the stack that performs "delete" upon destruction.
|
||||
//
|
||||
// No reference counting is performed, copying is prohibited "s_p2.Attach( s_p1.Detach() )" should be used
|
||||
// for readability and ease of maintenance.
|
||||
//
|
||||
// Auto pointer supports an "arrow" operator for invoking methods on the pointee and a "dereference" operator
|
||||
// for getting a pointee reference.
|
||||
//
|
||||
// No automatic casting to bool/ptrtype is performed to avoid bugs and problems (read on "safe bool idiom"
|
||||
// if casting to bool or pointer happens to be useful).
|
||||
//
|
||||
// Test for validity with "IsValid", get the pointer with "Get".
|
||||
//
|
||||
template < typename T >
|
||||
class CPlainAutoPtr
|
||||
{
|
||||
public:
|
||||
explicit CPlainAutoPtr( T *p = NULL ) : m_p( p ) {}
|
||||
~CPlainAutoPtr( void ) { Delete(); }
|
||||
|
||||
public:
|
||||
void Delete( void ) { delete Detach(); }
|
||||
|
||||
private: // Disallow copying, use Detach() instead to avoid ambiguity
|
||||
CPlainAutoPtr( CPlainAutoPtr const &x );
|
||||
CPlainAutoPtr & operator = ( CPlainAutoPtr const &x );
|
||||
|
||||
public:
|
||||
void Attach( T *p ) { m_p = p; }
|
||||
T * Detach( void ) { T * p( m_p ); m_p = NULL; return p; }
|
||||
|
||||
public:
|
||||
bool IsValid( void ) const { return m_p != NULL; }
|
||||
T * Get( void ) const { return m_p; }
|
||||
T * operator -> ( void ) const { return Get(); }
|
||||
T & operator * ( void ) const { return *Get(); }
|
||||
|
||||
private:
|
||||
T * m_p;
|
||||
};
|
||||
|
||||
//
|
||||
// CArrayAutoPtr
|
||||
// is a smart wrapper for an array pointer on the stack that performs "delete []" upon destruction.
|
||||
//
|
||||
// No reference counting is performed, copying is prohibited "s_p2.Attach( s_p1.Detach() )" should be used
|
||||
// for readability and ease of maintenance.
|
||||
//
|
||||
// Auto pointer supports an "indexing" operator for accessing array elements.
|
||||
//
|
||||
// No automatic casting to bool/ptrtype is performed to avoid bugs and problems (read on "safe bool idiom"
|
||||
// if casting to bool or pointer happens to be useful).
|
||||
//
|
||||
// Test for validity with "IsValid", get the array pointer with "Get".
|
||||
//
|
||||
template < typename T >
|
||||
class CArrayAutoPtr : public CPlainAutoPtr < T > // Warning: no polymorphic destructor (delete on base class will be a mistake)
|
||||
{
|
||||
public:
|
||||
explicit CArrayAutoPtr( T *p = NULL ) { this->Attach( p ); }
|
||||
~CArrayAutoPtr( void ) { this->Delete(); }
|
||||
|
||||
public:
|
||||
void Delete( void ) { delete [] CPlainAutoPtr < T >::Detach(); }
|
||||
|
||||
public:
|
||||
T & operator [] ( int k ) const { return CPlainAutoPtr < T >::Get()[ k ]; }
|
||||
};
|
||||
|
||||
|
||||
// Smart pointers can be used to automatically free an object when nobody points
|
||||
// at it anymore. Things contained in smart pointers must implement AddRef and Release
|
||||
// functions. If those functions are private, then the class must make
|
||||
// CRefCountAccessor a friend.
|
||||
template<class T, class RefCountAccessor=CRefCountAccessor>
|
||||
class CSmartPtr
|
||||
{
|
||||
public:
|
||||
CSmartPtr();
|
||||
CSmartPtr( T *pObj );
|
||||
CSmartPtr( const CSmartPtr<T,RefCountAccessor> &other );
|
||||
~CSmartPtr();
|
||||
|
||||
T* operator=( T *pObj );
|
||||
void operator=( const CSmartPtr<T,RefCountAccessor> &other );
|
||||
const T* operator->() const;
|
||||
T* operator->();
|
||||
bool operator!() const;
|
||||
bool operator==( const T *pOther ) const;
|
||||
bool IsValid() const; // Tells if the pointer is valid.
|
||||
T* GetObject() const; // Get temporary object pointer, don't store it for later reuse!
|
||||
void MarkDeleted();
|
||||
|
||||
private:
|
||||
T *m_pObj;
|
||||
};
|
||||
|
||||
|
||||
template< class T, class RefCountAccessor >
|
||||
inline CSmartPtr<T,RefCountAccessor>::CSmartPtr()
|
||||
{
|
||||
m_pObj = NULL;
|
||||
}
|
||||
|
||||
template< class T, class RefCountAccessor >
|
||||
inline CSmartPtr<T,RefCountAccessor>::CSmartPtr( T *pObj )
|
||||
{
|
||||
m_pObj = NULL;
|
||||
*this = pObj;
|
||||
}
|
||||
|
||||
template< class T, class RefCountAccessor >
|
||||
inline CSmartPtr<T,RefCountAccessor>::CSmartPtr( const CSmartPtr<T,RefCountAccessor> &other )
|
||||
{
|
||||
m_pObj = NULL;
|
||||
*this = other;
|
||||
}
|
||||
|
||||
template< class T, class RefCountAccessor >
|
||||
inline CSmartPtr<T,RefCountAccessor>::~CSmartPtr()
|
||||
{
|
||||
if ( m_pObj )
|
||||
{
|
||||
RefCountAccessor::Release( m_pObj );
|
||||
}
|
||||
}
|
||||
|
||||
template< class T, class RefCountAccessor >
|
||||
inline T* CSmartPtr<T,RefCountAccessor>::operator=( T *pObj )
|
||||
{
|
||||
if ( pObj == m_pObj )
|
||||
return pObj;
|
||||
|
||||
if ( pObj )
|
||||
{
|
||||
RefCountAccessor::AddRef( pObj );
|
||||
}
|
||||
if ( m_pObj )
|
||||
{
|
||||
RefCountAccessor::Release( m_pObj );
|
||||
}
|
||||
m_pObj = pObj;
|
||||
return pObj;
|
||||
}
|
||||
|
||||
template< class T, class RefCountAccessor >
|
||||
inline void CSmartPtr<T,RefCountAccessor>::MarkDeleted()
|
||||
{
|
||||
m_pObj = NULL;
|
||||
}
|
||||
|
||||
template< class T, class RefCountAccessor >
|
||||
inline void CSmartPtr<T,RefCountAccessor>::operator=( const CSmartPtr<T,RefCountAccessor> &other )
|
||||
{
|
||||
*this = other.m_pObj;
|
||||
}
|
||||
|
||||
template< class T, class RefCountAccessor >
|
||||
inline const T* CSmartPtr<T,RefCountAccessor>::operator->() const
|
||||
{
|
||||
return m_pObj;
|
||||
}
|
||||
|
||||
template< class T, class RefCountAccessor >
|
||||
inline T* CSmartPtr<T,RefCountAccessor>::operator->()
|
||||
{
|
||||
return m_pObj;
|
||||
}
|
||||
|
||||
template< class T, class RefCountAccessor >
|
||||
inline bool CSmartPtr<T,RefCountAccessor>::operator!() const
|
||||
{
|
||||
return !m_pObj;
|
||||
}
|
||||
|
||||
template< class T, class RefCountAccessor >
|
||||
inline bool CSmartPtr<T,RefCountAccessor>::operator==( const T *pOther ) const
|
||||
{
|
||||
return m_pObj == pOther;
|
||||
}
|
||||
|
||||
template< class T, class RefCountAccessor >
|
||||
inline bool CSmartPtr<T,RefCountAccessor>::IsValid() const
|
||||
{
|
||||
return m_pObj != NULL;
|
||||
}
|
||||
|
||||
template< class T, class RefCountAccessor >
|
||||
inline T* CSmartPtr<T,RefCountAccessor>::GetObject() const
|
||||
{
|
||||
return m_pObj;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// CAutoPushPop
|
||||
// allows you to set value of a variable upon construction and destruction.
|
||||
// Constructors:
|
||||
// CAutoPushPop x( myvar )
|
||||
// saves the value and restores upon destruction.
|
||||
// CAutoPushPop x( myvar, newvalue )
|
||||
// saves the value, assigns new value upon construction, restores saved value upon destruction.
|
||||
// CAutoPushPop x( myvar, newvalue, restorevalue )
|
||||
// assigns new value upon construction, assignes restorevalue upon destruction.
|
||||
//
|
||||
template < typename T >
|
||||
class CAutoPushPop
|
||||
{
|
||||
public:
|
||||
explicit CAutoPushPop( T& var ) : m_rVar( var ), m_valPop( var ) {}
|
||||
CAutoPushPop( T& var, T const &valPush ) : m_rVar( var ), m_valPop( var ) { m_rVar = valPush; }
|
||||
CAutoPushPop( T& var, T const &valPush, T const &valPop ) : m_rVar( var ), m_valPop( var ) { m_rVar = valPush; }
|
||||
|
||||
~CAutoPushPop() { m_rVar = m_valPop; }
|
||||
|
||||
private: // forbid copying
|
||||
CAutoPushPop( CAutoPushPop const &x );
|
||||
CAutoPushPop & operator = ( CAutoPushPop const &x );
|
||||
|
||||
public:
|
||||
T & Get() { return m_rVar; }
|
||||
|
||||
private:
|
||||
T &m_rVar;
|
||||
T m_valPop;
|
||||
};
|
||||
|
||||
|
||||
#endif // SMARTPTR_H
|
Reference in New Issue
Block a user