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.
 
 
 
 
 
 

622 lines
18 KiB

/*****************************************************************************
*
* (C) COPYRIGHT MICROSOFT CORPORATION, 2000
*
* TITLE: gensph.h
*
* VERSION: 1.0
*
* AUTHOR: LazarI
*
* DATE: 23-Dec-2000
*
* DESCRIPTION: generic smart pointers & smart handles templates
*
*****************************************************************************/
#ifndef _GENSPH_H_
#define _GENSPH_H_
// include the core definitions first
#include "coredefs.h"
////////////////////////////////////////////////
//
// class CGenericSP
//
// a generic smart pointer
// everything starts here -:)
//
template < class T,
class inheritorClass,
class pType = T*,
INT_PTR null = 0,
class pCType = const T* >
class CGenericSP
{
public:
// construction/destruction
CGenericSP(): m_p(GetNull()) {}
CGenericSP(pType p): m_p(GetNull()) { _Attach(p); }
~CGenericSP() { Reset(); }
// follows common smart pointer impl. -
// operators & methods
void Reset()
{
if( GetNull() != m_p )
{
_Delete(m_p);
m_p = GetNull();
}
}
void Attach(pType p)
{
Reset();
m_p = (p ? p : GetNull());
}
pType Detach()
{
pType p = GetNull();
if( GetNull() != m_p )
{
p = m_p;
m_p = GetNull();
}
return p;
}
template <class AS_TYPE>
AS_TYPE GetPtrAs() const
{
return (GetNull() == m_p) ? reinterpret_cast<AS_TYPE>(NULL) : reinterpret_cast<AS_TYPE>(m_p);
}
pType GetPtr() const
{
return GetPtrAs<pType>();
}
pType* GetPPT()
{
return static_cast<pType*>(&m_p);
}
pCType* GetPPCT()
{
return const_cast<pCType*>(&m_p);
}
void** GetPPV()
{
return reinterpret_cast<void**>(&m_p);
}
operator pType() const
{
return GetPtr();
}
T& operator*() const
{
ASSERT(GetNull() != m_p);
return *m_p;
}
pType* operator&()
{
ASSERT(GetNull() == m_p);
return GetPPT();
}
pType operator->() const
{
ASSERT(GetNull() != m_p);
return (pType)m_p;
}
pType operator=(pType p)
{
_Attach(p);
return m_p;
}
pType operator=(const int i)
{
// this operator is only for NULL assignment
ASSERT(INT2PTR(i, pType) == NULL || INT2PTR(i, pType) == GetNull());
Attach(INT2PTR(i, pType));
return m_p;
}
bool operator!() const
{
return (GetNull() == m_p);
}
bool operator<(pType p) const
{
return (m_p < p);
}
bool operator==(pType p) const
{
return (m_p == p);
}
protected:
pType m_p;
// those will be declared protected, so people won't use them directly
CGenericSP(CGenericSP<T, inheritorClass, pType, null, pCType> &sp): m_p(GetNull())
{
_Attach(sp);
}
void Attach(CGenericSP<T, inheritorClass, pType, null, pCType> &sp)
{
static_cast<inheritorClass*>(this)->Attach(static_cast<pType>(sp));
sp.Detach();
}
pType operator=(CGenericSP<T, inheritorClass, pType, null, pCType> &sp)
{
_Attach(sp);
return m_p;
}
// NULL support, use these to check for/assign NULL in inheritors
pType GetNull() const { return reinterpret_cast<pType>(null); }
bool IsNull(pType p) const { return GetNull() == p; }
bool IsntNull(pType p) const { return GetNull() != p; }
private:
void _Attach(pType p)
{
// give a chance to inheritors to override the attach
static_cast<inheritorClass*>(this)->Attach(p);
}
void _Attach(CGenericSP<T, inheritorClass, pType, null, pCType> &sp)
{
// give a chance to inheritors to override the attach
static_cast<inheritorClass*>(this)->Attach(sp);
}
void _Delete(pType p)
{
// the inheritor class defines static member called Delete(pType p)
// to destroy the object.
if( GetNull() != p )
{
inheritorClass::Delete(p);
}
}
};
// declares standard default contructor, copy constructor, attach
// contructor and assignment operators (they can't be inherited as constructors can't)
// for the CGenericSP class in an inheritor class.
#define DECLARE_GENERICSMARTPTR_CONSTRUCT(T, className) \
private: \
className(className &sp): CGenericSP< T, className >(sp) { } \
T* operator=(className &sp) \
{ return CGenericSP< T, className >::operator =(sp); } \
public: \
className() { } \
className(T *p): CGenericSP< T, className >(p) { } \
T* operator=(T *p) \
{ return CGenericSP< T, className >::operator =(p); } \
T* operator=(const int i) \
{ return CGenericSP< T, className >::operator =(i); } \
#define DECLARE_GENERICSMARTPTR_CONSTRUCT1(T, className, pType) \
private: \
className(className &sp): CGenericSP<T, className, pType>(sp) { } \
pType operator=(className &sp) \
{ return CGenericSP<T, className, pType>::operator =(sp); } \
public: \
className() { } \
className(pType p): CGenericSP<T, className, pType>(p) { } \
pType operator=(pType p) \
{ return CGenericSP<T, className, pType>::operator =(p); } \
pType operator=(const int i) \
{ return CGenericSP<T, className, pType>::operator =(i); } \
#define DECLARE_GENERICSMARTPTR_CONSTRUCT2(T, className, pType, null) \
private: \
className(className &sp): CGenericSP<T, className, pType, null>(sp) { } \
pType operator=(className &sp) \
{ return CGenericSP<T, className, pType, null>::operator =(sp); } \
public: \
className() { } \
className(pType p): CGenericSP<T, className, pType, null>(p) { } \
pType operator=(pType p) \
{ return CGenericSP<T, className, pType, null>::operator =(p); } \
pType operator=(const int i) \
{ return CGenericSP<T, className, pType, null>::operator =(i); } \
////////////////////////////////////////////////
////////// AUTO POINTERS ///////////////////////
////////////////////////////////////////////////
////////////////////////////////////////////////
//
// class CAutoPtr
//
// simple auto-pointer
// uses delete operator to free memory
//
template <class T>
class CAutoPtr: public CGenericSP< T, CAutoPtr<T> >
{
public:
DECLARE_GENERICSMARTPTR_CONSTRUCT(T, CAutoPtr<T>)
static void Delete(T *p) { delete p; }
};
////////////////////////////////////////////////
//
// class CAutoPtrArray
//
// simple auto-pointer allocated as array
// uses delete[] operator to free memory
//
template <class T>
class CAutoPtrArray: public CGenericSP< T, CAutoPtrArray<T> >
{
public:
DECLARE_GENERICSMARTPTR_CONSTRUCT(T, CAutoPtrArray<T>)
static void Delete(T *p) { delete[] p; }
};
////////////////////////////////////////////////
//
// class CAutoPtrCRT
//
// simple CRT auto-pointer - allocated with malloc/calloc
// uses free to free the memory
//
template <class T>
class CAutoPtrCRT: public CGenericSP< T, CAutoPtrCRT<T> >
{
public:
DECLARE_GENERICSMARTPTR_CONSTRUCT(T, CAutoPtrCRT<T>)
static void Delete(T *p) { free(p); }
};
////////////////////////////////////////////////
//
// class CAutoPtrSpl
//
// simple spooler auto-pointer -
// uses FreeMem to free memory
//
template <class T>
class CAutoPtrSpl: public CGenericSP< T, CAutoPtrSpl<T> >
{
public:
DECLARE_GENERICSMARTPTR_CONSTRUCT(T, CAutoPtrSpl<T>)
static void Delete(T *p) { FreeMem(p); }
};
////////////////////////////////////////////////
//
// class CAutoPtrBSTR
//
// simple BSTR auto-pointer -
// SysAllocString/SysFreeString
//
class CAutoPtrBSTR: public CGenericSP<BSTR, CAutoPtrBSTR, BSTR>
{
public:
DECLARE_GENERICSMARTPTR_CONSTRUCT1(BSTR, CAutoPtrBSTR, BSTR)
static void Delete(BSTR p) { SysFreeString(p); }
};
////////////////////////////////////////////////
//
// class CAutoPtrCOM
//
// simple smart COM pointer
//
template <class T>
class CAutoPtrCOM: public CGenericSP< T, CAutoPtrCOM<T> >
{
public:
DECLARE_GENERICSMARTPTR_CONSTRUCT(T, CAutoPtrCOM<T>)
static void Delete(T *p) { p->Release(); }
};
////////////////////////////////////////////////
//
// class CRefPtrCOM
//
// referenced smart COM pointer (ATL style)
// with improvements for robustness
//
template <class T>
class CRefPtrCOM: public CGenericSP< T, CRefPtrCOM<T> >
{
void _AddRefAttach(T *p);
public:
// special case all these
CRefPtrCOM() { }
CRefPtrCOM(const CGenericSP< T, CRefPtrCOM<T> > &sp): CGenericSP< T, CRefPtrCOM<T> >(sp) { }
T* operator=(const CRefPtrCOM<T> &sp) { return CGenericSP< T, CRefPtrCOM<T> >::operator =(sp); }
T* operator=(const int i) { return CGenericSP< T, CRefPtrCOM<T> >::operator =(i); }
// overloaded stuff
void Attach(const CRefPtrCOM<T> &sp) { _AddRefAttach(static_cast<T*>(sp)); }
static void Delete(T *p) { p->Release(); }
// use these functions instead of operators (more clear)
HRESULT CopyFrom(T *p); // AddRef p and assign to this
HRESULT CopyTo(T **ppObj); // AddRef this and assign to ppObj
HRESULT TransferTo(T **ppObj); // assign this to ppObj and assign NULL to this
HRESULT Adopt(T *p); // take ownership of p
private:
// disable contruction, assignment operator & attach from
// a raw pointer - it's not clear what exactly you want:
// to copy (AddRef) the object or to take ownership - use
// the functions above to make clear
void Attach(T* p);
CRefPtrCOM(T *p);
T* operator=(T *p);
};
////////////////////////////////////////////////
//
// class CAutoPtrShell
//
// smart shell auto pointer -
// uses shell IMalloc to free memory
//
template <class T>
class CAutoPtrShell: public CGenericSP< T, CAutoPtrShell<T> >
{
public:
DECLARE_GENERICSMARTPTR_CONSTRUCT(T, CAutoPtrShell<T>)
static void Delete(T *p)
{
CAutoPtrCOM<IMalloc> spShellMalloc;
if( SUCCEEDED(SHGetMalloc(&spShellMalloc)) )
{
spShellMalloc->Free(p);
}
}
};
////////////////////////////////////////////////
//
// class CAutoPtrPIDL
//
// smart shell ID list ptr - LPCITEMIDLIST, LPITEMIDLIST.
//
typedef CAutoPtrShell<ITEMIDLIST> CAutoPtrPIDL;
////////////////////////////////////////////////
////////// AUTO HANDLES ////////////////////////
////////////////////////////////////////////////
////////////////////////////////////////////////
//
// class CAutoHandleNT
//
// NT kernel object handle (closed with CloseHandle)
//
class CAutoHandleNT: public CGenericSP<HANDLE, CAutoHandleNT, HANDLE>
{
public:
DECLARE_GENERICSMARTPTR_CONSTRUCT1(HANDLE, CAutoHandleNT, HANDLE)
static void Delete(HANDLE h) { VERIFY(CloseHandle(h)); }
};
////////////////////////////////////////////////
//
// class CAutoHandleHLOCAL
//
// NT local heap handle (closed with LocalFree)
//
class CAutoHandleHLOCAL: public CGenericSP<HLOCAL, CAutoHandleHLOCAL, HLOCAL>
{
public:
DECLARE_GENERICSMARTPTR_CONSTRUCT1(HLOCAL, CAutoHandleHLOCAL, HLOCAL)
static void Delete(HLOCAL h) { VERIFY(NULL == LocalFree(h)); }
};
////////////////////////////////////////////////
//
// class CAutoHandleHGLOBAL
//
// NT global heap handle (closed with GlobalFree)
//
class CAutoHandleHGLOBAL: public CGenericSP<HGLOBAL, CAutoHandleHGLOBAL, HGLOBAL>
{
public:
DECLARE_GENERICSMARTPTR_CONSTRUCT1(HGLOBAL, CAutoHandleHGLOBAL, HGLOBAL)
static void Delete(HGLOBAL h) { VERIFY(NULL == GlobalFree(h)); }
};
////////////////////////////////////////////////
//
// class CAutoHandlePrinter
//
// auto printer handle
//
class CAutoHandlePrinter: public CGenericSP<HANDLE, CAutoHandlePrinter, HANDLE>
{
public:
DECLARE_GENERICSMARTPTR_CONSTRUCT1(HANDLE, CAutoHandlePrinter, HANDLE)
static void Delete(HANDLE h) { CHECK(ClosePrinter(h)); }
};
////////////////////////////////////////////////
//
// class CAutoHandlePrinterNotify
//
// printer notifications handle -
// Find[Firse/Next/Close]PrinterChangeNotification()
//
class CAutoHandlePrinterNotify: public CGenericSP<HANDLE, CAutoHandlePrinterNotify, HANDLE, -1>
{
public:
DECLARE_GENERICSMARTPTR_CONSTRUCT2(HANDLE, CAutoHandlePrinterNotify, HANDLE, -1)
static void Delete(HANDLE h) { CHECK(FindClosePrinterChangeNotification(h)); }
};
////////////////////////////////////////////////
//
// class CAutoPtrPrinterNotify
//
// printer notifications memory - spooler should free it.
// Find[Firse/Next/Close]PrinterChangeNotification()
//
class CAutoPtrPrinterNotify: public CGenericSP<PRINTER_NOTIFY_INFO, CAutoPtrPrinterNotify>
{
public:
DECLARE_GENERICSMARTPTR_CONSTRUCT(PRINTER_NOTIFY_INFO, CAutoPtrPrinterNotify)
static void Delete(PRINTER_NOTIFY_INFO *p) { CHECK(FreePrinterNotifyInfo(p)); }
};
////////////////////////////////////////////////
//
// class CAutoHandleGDI
//
// GDI auto handle (WindowsNT GDI handle wrapper)
//
template <class T>
class CAutoHandleGDI: public CGenericSP< T, CAutoHandleGDI<T>, T >
{
public:
DECLARE_GENERICSMARTPTR_CONSTRUCT1(T, CAutoHandleGDI<T>, T)
static void Delete(T hGDIObj) { VERIFY(DeleteObject(hGDIObj)); }
};
// GDI auto handles
typedef CAutoHandleGDI<HPEN> CAutoHandlePen;
typedef CAutoHandleGDI<HBRUSH> CAutoHandleBrush;
typedef CAutoHandleGDI<HFONT> CAutoHandleFont;
typedef CAutoHandleGDI<HBITMAP> CAutoHandleBitmap;
// etc...
////////////////////////////////////////////////
//
// class CAutoHandleCursor
//
// auto handle for HCURSOR
//
class CAutoHandleCursor: public CGenericSP<HCURSOR, CAutoHandleCursor, HCURSOR>
{
public:
DECLARE_GENERICSMARTPTR_CONSTRUCT1(HCURSOR, CAutoHandleCursor, HCURSOR)
static void Delete(HCURSOR h) { VERIFY(DestroyCursor(h)); }
};
////////////////////////////////////////////////
//
// class CAutoHandleIcon
//
// auto handle for HICON
//
class CAutoHandleIcon: public CGenericSP<HICON, CAutoHandleIcon, HICON>
{
public:
DECLARE_GENERICSMARTPTR_CONSTRUCT1(HICON, CAutoHandleIcon, HICON)
static void Delete(HICON h) { VERIFY(DestroyIcon(h)); }
};
////////////////////////////////////////////////
//
// class CAutoHandleMenu
//
// auto handle for HMENU
//
class CAutoHandleMenu: public CGenericSP<HMENU, CAutoHandleMenu, HMENU>
{
public:
DECLARE_GENERICSMARTPTR_CONSTRUCT1(HMENU, CAutoHandleMenu, HMENU)
static void Delete(HMENU h) { VERIFY(DestroyMenu(h)); }
};
////////////////////////////////////////////////
//
// class CAutoHandleAccel
//
// auto handle for HACCEL
//
class CAutoHandleAccel: public CGenericSP<HACCEL, CAutoHandleAccel, HACCEL>
{
public:
DECLARE_GENERICSMARTPTR_CONSTRUCT1(HACCEL, CAutoHandleAccel, HACCEL)
static void Delete(HACCEL h) { DestroyAcceleratorTable(h); }
};
#ifdef _INC_COMCTRLP
////////////////////////////////////////////////
//
// class CAutoHandleHDSA
//
// auto handle for shell HDSA
// (dynamic structure arrays)
//
class CAutoHandleHDSA: public CGenericSP<HDSA, CAutoHandleHDSA, HDSA>
{
public:
DECLARE_GENERICSMARTPTR_CONSTRUCT1(HDSA, CAutoHandleHDSA, HDSA)
static void Delete(HDSA h) { VERIFY(DSA_Destroy(h)); }
};
////////////////////////////////////////////////
//
// class CAutoHandleMRU
//
// auto handle for MRU (shell common controls)
// CreateMRUList/FreeMRUList
//
class CAutoHandleMRU: public CGenericSP<HANDLE, CAutoHandleMRU, HANDLE>
{
public:
DECLARE_GENERICSMARTPTR_CONSTRUCT1(HANDLE, CAutoHandleMRU, HANDLE)
static void Delete(HANDLE h) { FreeMRUList(h); }
};
#endif // _INC_COMCTRLP
////////////////////////////////////////////////
//
// class CAutoHandleHKEY
//
// auto handle for a Windows registry key (HKEY)
// RegCreateKeyEx/RegOpenKeyEx/RegCloseKey
//
class CAutoHandleHKEY: public CGenericSP<HKEY, CAutoHandleHKEY, HKEY>
{
public:
DECLARE_GENERICSMARTPTR_CONSTRUCT1(HKEY, CAutoHandleHKEY, HKEY)
static void Delete(HKEY h) { VERIFY(ERROR_SUCCESS == RegCloseKey(h)); }
};
////////////////////////////////////////////////
//
// class CAutoHandleHMODULE
//
// auto handle for a HMODULE
// LoadLibrary/FreeLibrary
//
class CAutoHandleHMODULE: public CGenericSP<HMODULE, CAutoHandleHMODULE, HMODULE>
{
public:
DECLARE_GENERICSMARTPTR_CONSTRUCT1(HMODULE, CAutoHandleHMODULE, HMODULE)
static void Delete(HMODULE h) { VERIFY(FreeLibrary(h)); }
};
// include the implementation of the template classes here
#include "gensph.inl"
#endif // endif _GENSPH_H_