aboutsummaryrefslogtreecommitdiff
path: root/sp/src/public/tier1/smartptr.h
diff options
context:
space:
mode:
authorJoe Ludwig <[email protected]>2013-06-26 15:22:04 -0700
committerJoe Ludwig <[email protected]>2013-06-26 15:22:04 -0700
commit39ed87570bdb2f86969d4be821c94b722dc71179 (patch)
treeabc53757f75f40c80278e87650ea92808274aa59 /sp/src/public/tier1/smartptr.h
downloadsource-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz
source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip
First version of the SOurce SDK 2013
Diffstat (limited to 'sp/src/public/tier1/smartptr.h')
-rw-r--r--sp/src/public/tier1/smartptr.h279
1 files changed, 279 insertions, 0 deletions
diff --git a/sp/src/public/tier1/smartptr.h b/sp/src/public/tier1/smartptr.h
new file mode 100644
index 00000000..a0065e5a
--- /dev/null
+++ b/sp/src/public/tier1/smartptr.h
@@ -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