Source code of Windows XP (NT5)
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
#pragma once
#include <atlbase.h>
#include <utility>
#include <assert.h>
#include "dexception.h"
// AutoPtrBase
//
// Safe pointer class that knows to delete the referrent object when
// the pointer goes out of scope or is replaced, etc.
template<class _TYPE> class AutoPtrBase { protected:
mutable BOOL m_bOwns; _TYPE * m_pRaw;
public:
// Create from raw pointer. This auto pointer now owns the data.
AutoPtrBase(_TYPE * pRaw = NULL) { m_bOwns = (pRaw != NULL); m_pRaw = pRaw;
assert( !m_bOwns || m_pRaw ); }
// Create from other auto pointer. Other auto pointer disowns the data.
AutoPtrBase(const AutoPtrBase<_TYPE> & ptrOther) { m_bOwns = ptrOther.m_bOwns; m_pRaw = (_TYPE *) const_cast<AutoPtrBase<_TYPE> &>(ptrOther)._disownptr(); }
AutoPtrBase<_TYPE> & take(_TYPE * pRawIn) { if (m_pRaw != pRawIn) { if (m_bOwns) nukeit(); } m_bOwns = (pRawIn != NULL); m_pRaw = pRawIn;
assert( !m_bOwns || m_pRaw ); return *this; }
virtual ~AutoPtrBase() { }
virtual void nukeit() { delete m_pRaw; }
AutoPtrBase<_TYPE> & operator=(_TYPE * pRawIn) { take(pRawIn); return *this; }
// Assignment of other auto pointer to ourselves. If we are not the
// same object, we take ownership of the data, first releasing any
// we already own.
AutoPtrBase<_TYPE> & operator=(const AutoPtrBase<_TYPE> & ptrOther) { if ((void *)this != (void *)&ptrOther) { _TYPE * pRaw = const_cast<AutoPtrBase<_TYPE>&>(ptrOther)._disownptr(); take(pRaw); } return *this; }
AutoPtrBase<_TYPE> & replace(const AutoPtrBase<_TYPE>& ptrOtherIn) { return *this = ptrOtherIn; }
virtual operator _TYPE*() { return get(); }
virtual operator const _TYPE*() const { return get(); }
/* Not allowed, since void * wouldn't worl
_TYPE& operator*() const { return (*get()); } */
_TYPE ** operator&() { return _getoutptr(); }
// Will produce errors if applied using infix notation
//#pragma warning(disable:4284)
// _TYPE *operator->() const
// {
// return (get());
// }
//#pragma warning(default:4284)
_TYPE *get() const { return (m_pRaw); }
_TYPE * _disownptr() { m_bOwns = FALSE; return m_pRaw; }
_TYPE ** _getoutptr() { if (m_bOwns) nukeit(); m_bOwns = TRUE; return (&m_pRaw); } };
// AutoHLOCK
//
template<class _TYPE> class AutoHLOCK : public AutoPtrBase<_TYPE> { private:
protected:
HGLOBAL m_hGlobal;
virtual void nukeit() { // If the memory object is still locked after decrementing the lock count,
// the return value is a nonzero value. If the function fails, the return
// value is zero. To get extended error information, we call GetLastError.
// If GetLastError returns NO_ERROR, the memory object is unlocked.
if (0 == GlobalUnlock( m_hGlobal) ) assert(NO_ERROR == GetLastError()); }
public:
AutoHLOCK<_TYPE>& operator=(HGLOBAL _H) { if (m_hGlobal != _H) { if (m_bOwns) nukeit(); m_pRaw = _H ? ((_TYPE*) GlobalLock(_H)) : NULL; m_bOwns = (NULL != m_pRaw);
m_hGlobal = _H;
assert( !m_bOwns || m_pRaw ); } return *this; }
~AutoHLOCK() { if (m_bOwns) this->nukeit(); }
AutoHLOCK(HGLOBAL _H = 0) : m_hGlobal(NULL) { *this = _H; } };
// AutoHPALETTE (HPALETTE)
//
class AutoHPALETTE : public AutoPtrBase<struct HPALETTE__> { virtual void nukeit() { DeleteObject((HPALETTE)m_pRaw); }
public:
~AutoHPALETTE() { if (m_bOwns) this->nukeit(); }
AutoHPALETTE(HPALETTE pRawIn = 0) : AutoPtrBase<struct HPALETTE__>(pRawIn) { }
};
/*
// AutoHPROPSHEETPAGE
//
class AutoHPROPSHEETPAGE : public AutoPtrBase<struct _PSP> { virtual void nukeit() { DestroyPropertySheetPage((HPROPSHEETPAGE)m_pRaw); }
public:
~AutoHPROPSHEETPAGE() { if (m_bOwns) this->nukeit(); }
AutoHPROPSHEETPAGE(HPROPSHEETPAGE pRawIn = 0) : AutoPtrBase<struct _PSP>(pRawIn) { }
}; */
//
// AutoHKEY (HKEY)
//
class AutoHKEY : public AutoPtrBase<struct HKEY__> { virtual void nukeit() { RegCloseKey((HKEY)m_pRaw); }
public:
~AutoHKEY() { if (m_bOwns) this->nukeit(); }
AutoHKEY(HKEY pRawIn = 0) : AutoPtrBase<struct HKEY__>(pRawIn) { }
};
// AutoHICON (HICON)
//
class AutoHICON : public AutoPtrBase<struct HICON__> { virtual void nukeit() { DestroyIcon((HICON)m_pRaw); }
public:
~AutoHICON() { if (m_bOwns) this->nukeit(); }
AutoHICON& operator=(struct HICON__ * pRawIn) { take(pRawIn); return *this; }
AutoHICON(HICON pRawIn = 0) : AutoPtrBase<struct HICON__>(pRawIn) { }
};
// AutoHBITMAP (HBITMAP)
//
class AutoHBITMAP : public AutoPtrBase<struct HBITMAP__> { virtual void nukeit() { DeleteObject((HBITMAP)m_pRaw); }
public:
~AutoHBITMAP() { if (m_bOwns) this->nukeit(); }
AutoHBITMAP& operator=(struct HBITMAP__ * pRawIn) { take(pRawIn); return *this; }
AutoHBITMAP(HBITMAP pRawIn = 0) : AutoPtrBase<struct HBITMAP__>(pRawIn) { }
};
// AutoHDC (HDC)
//
typedef pair<HDC, HWND> WindowDCPair;
class AutoHDC : public AutoPtrBase<WindowDCPair> { // If this was from GetDC() call, we'll have the handle of the
// window against which we will need to release it. If not,
// we assume we need to actually DeleteDC() on it.
virtual void nukeit() { if (get()->second) ReleaseDC(get()->second, get()->first); else DeleteDC(get()->first); }
protected:
HDC m_hDC;
public:
~AutoHDC() { if (m_bOwns) this->nukeit(); }
AutoHDC& operator=(HDC pRawIn) { take( &WindowDCPair(pRawIn, NULL) ); return *this; }
AutoHDC& operator=( WindowDCPair in) { take(&in); return *this; } AutoHDC(HDC hdc = NULL, HWND hwndFrom = NULL) : AutoPtrBase<WindowDCPair>( &WindowDCPair(hdc, hwndFrom) ) { }
AutoHDC(HWND hwndFrom) : AutoPtrBase<WindowDCPair>( &WindowDCPair(GetDC(hwndFrom), hwndFrom) ) { if (NULL == get()->first) throw new win32error; }
operator HDC() { return get()->first; }
operator const HDC() const { return get()->first; }
};
// AutoHGLOBAL (HGLOBAL)
//
class AutoHGLOBAL : public AutoPtrBase<void> { virtual void nukeit() { GlobalFree((HGLOBAL)m_pRaw); }
public:
~AutoHGLOBAL() { if (m_bOwns) this->nukeit(); }
AutoHGLOBAL(HGLOBAL pRawIn = 0) : AutoPtrBase<void>(pRawIn) { }
};
class AutoFindHandle { public: AutoFindHandle(HANDLE handle = INVALID_HANDLE_VALUE) : m_handle(handle), m_bOwns(INVALID_HANDLE_VALUE != handle) { }
AutoFindHandle(const AutoFindHandle& rhs) : m_handle(INVALID_HANDLE_VALUE), m_bOwns(false) { *this = rhs; }
~AutoFindHandle(void) { Close(); }
void Close(void);
HANDLE Detach(void) const { m_bOwns = false; return m_handle; }
void Attach(HANDLE handle) { Close(); m_handle = handle; m_bOwns = true; }
operator HANDLE() const { return m_handle; }
bool IsValid(void) const { return INVALID_HANDLE_VALUE != m_handle; }
AutoFindHandle& operator = (HANDLE handle) { Attach(handle); return *this; }
AutoFindHandle& operator = (const AutoFindHandle& rhs);
private: mutable HANDLE m_handle; mutable bool m_bOwns; };
// AutoPtr
//
template<class _TYPE> class AutoPtr : public AutoPtrBase<_TYPE> { virtual void nukeit() { delete m_pRaw; }
public:
~AutoPtr() { if (m_bOwns) this->nukeit(); }
AutoPtr(_TYPE *pRawIn = 0) : AutoPtrBase<_TYPE>(pRawIn) { }
AutoPtr<_TYPE> & operator=(const AutoPtr<_TYPE> & ptrOther) { if (this != &ptrOther) { AutoPtr<_TYPE> * pptrOther = const_cast<AutoPtr<_TYPE> *>(&ptrOther); m_bOwns = pptrOther->m_bOwns; m_pRaw = (_TYPE *) (pptrOther->_disownptr()); } return *this; }
AutoPtr(const AutoPtr<_TYPE> & ptrOther) { *this = ptrOther; }
// AutoPtr<_TYPE> & operator=(_TYPE * pRawIn)
AutoPtr<_TYPE> & operator=(_TYPE * pRawIn) { take(pRawIn); return *this; } };
// AutoComPtr
//
// Smart pointer that calls _disownptr() on the referent when the pointer itself
// goes out of scope
template <class _TYPE> class AutoComPtr : public CComPtr<_TYPE> { public: AutoComPtr(void) { }
AutoComPtr(_TYPE *p) : CComPtr<_TYPE>(p) { }
AutoComPtr(const AutoComPtr<_TYPE>& rhs) : CComPtr<_TYPE>(rhs.p) { }
AutoComPtr& operator = (const AutoComPtr& rhs) { if (this != &rhs) { CComPtr<_TYPE>::operator = (rhs); } return *this; }
//
// Retrieve the address of the contained interface ptr.
// ptr._getoutptr() is equivalent to &ptr.p
//
_TYPE **_getoutptr(void) { return &p; }
_TYPE * _disownptr(void) { return Detach(); }
//
// WARNING: This hides the CComPtr implementation of operator&().
// It's intentional. Otherwise you can't pass the address
// of an AutoComPtr to a function and get the expected semantics.
// CComPtr's implementation returns the address of the contained
// pointer. If this is what you want, use AutoComtPtr::_getoutptr().
//
AutoComPtr *operator& (void) { return this; } };
#ifdef USE_SHELL_AUTOPTR
#include <cshalloc.h>
// App must declare a global instance of this class
extern CSHAlloc g_SHAlloc;
// AutoShellPtr
//
// Smart pointer that manually runs the referent's destructor and then
// calls the shell's task allocator to free the object's memory footprint
template<class _TYPE> class AutoShellPtr : virtual public AutoPtrBase<_TYPE> { virtual void nukeit() { if (m_pRaw) { m_pRaw->~_TYPE(); g_SHAlloc.Free(m_pRaw); } }
public:
~AutoShellPtr() { if (m_bOwns) this->nukeit(); }
AutoShellPtr(_TYPE *pRawIn = 0) : AutoPtrBase<_TYPE>(pRawIn) { }
AutoShellPtr<_TYPE> & operator=(_TYPE * pRawIn) { take(pRawIn); return *this; }
}; #endif
|