|
|
/*++
Copyright (C) 1996-2001 Microsoft Corporation
Module Name:
ARRTEMPL.H
Abstract:
This file defines a simple template for an array of arbitrary pointers. Actual growing array functionality is provided by CFlexArray.
Classes defined:
template CPointerArray
History:
11/27/96 a-levn Compiles.
--*/
#ifndef __ARRAY_TEMPLATE__H_
#define __ARRAY_TEMPLATE__H_
#pragma warning(disable:4786)
#include <map>
#include <strutils.h>
using namespace std; class wcsless : public binary_function<LPWSTR, LPWSTR, bool> { public: bool operator()(const LPWSTR& wcs1, const LPWSTR& wcs2) const {return wcscmp(wcs1, wcs2) < 0;} };
class wcsiless : public binary_function<LPWSTR, LPWSTR, bool> { public: bool operator()(const LPWSTR& wcs1, const LPWSTR& wcs2) const {return wbem_wcsicmp(wcs1, wcs2) < 0;} };
class CReleaseMe { protected: IUnknown* m_pUnk;
public: CReleaseMe(IUnknown* pUnk) : m_pUnk(pUnk){} ~CReleaseMe() { release();} void release() { if(m_pUnk) m_pUnk->Release(); m_pUnk=0;} };
template<class T> class CTemplateReleaseMe { protected: T* m_p;
public: CTemplateReleaseMe(T* p) : m_p(p){} ~CTemplateReleaseMe() { release();} void release(){ if(m_p) m_p->Release();m_p=0;} };
template<class T> class CDeleteMe { protected: T* m_p;
public: CDeleteMe(T* p = NULL) : m_p(p){} ~CDeleteMe() {delete m_p;}
// overwrites the previous pointer, does NOT delete it
void operator= (T* p) {m_p = p;} };
class CCloseMe { protected: HANDLE m_h; public: CCloseMe(HANDLE hToClose){m_h = hToClose;}; ~CCloseMe(){if(m_h && m_h != INVALID_HANDLE_VALUE)CloseHandle(m_h);}; };
class CfcloseMe { protected: FILE * m_h; public: CfcloseMe(FILE * ToClose){m_h = ToClose;}; ~CfcloseMe(){if(m_h != NULL)fclose(m_h);}; };
typedef CCloseMe CCloseHandle;
class CRegCloseMe { protected: HKEY m_h; public: CRegCloseMe(HKEY hToClose){m_h = hToClose;}; ~CRegCloseMe(){if(m_h)RegCloseKey(m_h);}; };
template<class T> class CVectorDeleteMe { protected: T* m_p; T** m_pp;
public: CVectorDeleteMe(T* p) : m_p(p), m_pp(NULL){} CVectorDeleteMe(T** pp) : m_p(NULL), m_pp(pp){} ~CVectorDeleteMe() {if(m_p) delete [] m_p; else if(m_pp) delete [] *m_pp;} };
class CClearMe { protected: VARIANT* m_pv;
public: CClearMe(VARIANT* pv) : m_pv(pv){} ~CClearMe() {VariantClear(m_pv);} };
class CSysFreeMe { protected: BSTR m_str;
public: CSysFreeMe(BSTR str) : m_str(str){} ~CSysFreeMe() { if ( NULL != m_str ) SysFreeString(m_str);} };
class CUnaccessMe { protected: SAFEARRAY* m_psa; public: CUnaccessMe(SAFEARRAY* psa) : m_psa(psa){} ~CUnaccessMe() {SafeArrayUnaccessData(m_psa);} };
class CMemFreeMe { protected: void* m_pMem; public: CMemFreeMe( void* pMem ) : m_pMem(pMem){} ~CMemFreeMe() { if ( NULL != m_pMem ) CoTaskMemFree(m_pMem);} };
#include <arena.h>
#include <flexarry.h>
#include <flexq.h>
#include <smallarr.h>
//*****************************************************************************
//
// class CPointerArray
//
// Array of pointers to TMember, where TMember is any class. See CFlexArray
// in coredll\flexarry.h/cpp for documentation.
//
//*****************************************************************************
template <class TMember> class CNullManager { public: void AddRefElement(TMember*){} void ReleaseElement(TMember*){} };
template <class TMember, class TManager = CNullManager<TMember>, class TArray = CFlexArray> class CPointerArray { protected: TArray m_Array; TManager m_Manager; public: CPointerArray(const TManager& Manager = TManager()) : m_Manager(Manager){} ~CPointerArray();
int GetSize() const {return m_Array.Size();} void SetSize(int nNewSize) {m_Array.SetSize(nNewSize);} const TMember* GetAt(int nIndex) const {return (TMember*)m_Array.GetAt(nIndex);} TMember* GetAt(int nIndex) {return (TMember*)m_Array.GetAt(nIndex);} const TMember* operator[](int nIndex) const {return (TMember*)m_Array.GetAt(nIndex);} TMember* operator[](int nIndex) {return (TMember*)m_Array.GetAt(nIndex);} void SetAt(int nIndex, TMember* pElement, TMember** ppOld = NULL); void Discard(int nIndex); bool RemoveAt(int nIndex, TMember** ppOld = NULL); bool InsertAt(int nIndex, TMember* pElement); int Add(TMember* pElement); TMember** GetArrayPtr(); TMember** UnbindPtr(); void RemoveAll(); void Swap(int nIndex1, int nIndex2); void Trim() {m_Array.Trim();}
protected: void AddRefElement(TMember* p){m_Manager.AddRefElement(p);} void ReleaseElement(TMember* p){m_Manager.ReleaseElement(p);} };
template<class TMember> class CPointerSmallArray : public CPointerArray<TMember, CNullManager<TMember>, CSmallArray> { };
//*****************************************************************************
//
// class CPointerQueue
//
// Queue of pointers to TMember, where TMember is any class. See CFlexQueue
// in coredll\flexq.h/cpp for documentation.
//
//*****************************************************************************
template <class TMember, class TManager = CNullManager<TMember> > class CPointerQueue { protected: CFlexQueue m_Queue; TManager m_Manager; public: CPointerQueue(int nInitialSize = 1, const TManager& Manager = TManager()) : m_Manager(Manager), m_Queue(nInitialSize){} void Clear(); ~CPointerQueue() {Clear();}
inline int GetQueueSize() const {return m_Queue.GetQueueSize();}
bool Enqueue(TMember* pNew) { AddRefElement(pNew); return m_Queue.Enqueue(pNew); } TMember* Dequeue() { TMember* p = (TMember*)m_Queue.Dequeue(); return p; } bool Requeue(TMember* pNew) { AddRefElement(pNew); return m_Queue.Requeue(pNew); } TMember* Unqueue() { TMember* p = (TMember*)m_Queue.Unqueue(); AddRefElement(p); return p; } protected: void AddRefElement(TMember* p){m_Manager.AddRefElement(p);} void ReleaseElement(TMember* p){m_Manager.ReleaseElement(p);} };
//*****************************************************************************
//
// UNIQUE POINTER ARRAY
//
//*****************************************************************************
template <class TMember> class CUniqueManager { public: void AddRefElement(TMember*){} void ReleaseElement(TMember* pMember) {delete pMember;} };
template<class TMember> class CUniquePointerArray : public CPointerArray<TMember, CUniqueManager<TMember> > { };
template<class TMember> class CUniquePointerSmallArray : public CPointerArray<TMember, CUniqueManager<TMember>, CSmallArray> { };
template<class TMember> class CUniquePointerQueue : public CPointerQueue<TMember, CUniqueManager<TMember> > { public: CUniquePointerQueue<TMember>(int nInitialSize = 1) : CPointerQueue<TMember, CUniqueManager<TMember> >(nInitialSize) {} };
//*****************************************************************************
//
// REFED POINTER ARRAY
//
//*****************************************************************************
template <class TMember> class CReferenceManager { public: void AddRefElement(TMember* pMember) {if(pMember)pMember->AddRef();} void ReleaseElement(TMember* pMember) {if(pMember)pMember->Release();} };
template<class TMember> class CRefedPointerArray : public CPointerArray<TMember, CReferenceManager<TMember> > { };
template<class TMember> class CRefedPointerSmallArray : public CPointerArray<TMember, CReferenceManager<TMember>, CSmallArray> { };
template<class TMember> class CRefedPointerQueue : public CPointerQueue<TMember, CReferenceManager<TMember> > { public: CRefedPointerQueue(int nInitialSize = 1) : CPointerQueue<TMember, CReferenceManager<TMember> >(nInitialSize) {} };
//*****************************************************************************
//
// ARRAY OF UNIQUE ARRAYS
//
//*****************************************************************************
template <class TMember> class CUniqueArrayManager { void AddRefElement(TMember**){} void ReleaseElement(TMember** pMember) {delete [] pMember;} }; template<class TMember> class CUniqueArrayArray : public CPointerArray<TMember, CUniqueArrayManager<TMember> > { };
//*****************************************************************************
//
// IMPLEMENTATION
//
//*****************************************************************************
template <class TMember, class TManager, class TArray> CPointerArray<TMember, TManager, TArray>::~CPointerArray() { RemoveAll(); }
template <class TMember, class TManager, class TArray> void CPointerArray<TMember, TManager, TArray>::RemoveAll() { for(int i = 0; i < m_Array.Size(); i++) { //
// Remove it from array before releasing --- otherwise for a moment
// there we have a garbage pointer in array!
//
TMember* p = GetAt(i); m_Array.SetAt(i, NULL); ReleaseElement(p); } m_Array.Empty(); }
template <class TMember, class TManager, class TArray> void CPointerArray<TMember, TManager, TArray>::SetAt(int nIndex, TMember* pElement, TMember** ppOld) { AddRefElement(pElement);
//
// Remove it from array before releasing --- otherwise for a moment
// there we have a garbage pointer in array!
//
TMember* pOld = GetAt(nIndex); m_Array.SetAt(nIndex, (void*)pElement); if(ppOld == NULL) ReleaseElement(pOld); else *ppOld = pOld; }
template <class TMember, class TManager, class TArray> void CPointerArray<TMember, TManager, TArray>::Discard(int nIndex) { m_Array.SetAt(nIndex, NULL); }
template <class TMember, class TManager, class TArray> bool CPointerArray<TMember, TManager, TArray>::RemoveAt(int nIndex, TMember** ppOld) { //
// Remove it from array before releasing --- otherwise for a moment
// there we have a garbage pointer in array!
//
TMember* pOld = GetAt(nIndex); if(m_Array.RemoveAt(nIndex) != CFlexArray::no_error) return false;
if(ppOld == NULL) ReleaseElement(pOld); else *ppOld = pOld;
return true; }
template <class TMember, class TManager, class TArray> bool CPointerArray<TMember, TManager, TArray>::InsertAt(int nIndex, TMember* pElement) { if(m_Array.InsertAt(nIndex, (void*)pElement) != CFlexArray::no_error) return false;
AddRefElement(pElement); return true; }
template <class TMember, class TManager, class TArray> int CPointerArray<TMember, TManager, TArray>::Add(TMember* pElement) { if(m_Array.Add((void*)pElement) != CFlexArray::no_error) return -1;
AddRefElement(pElement); return m_Array.Size()-1; }
template <class TMember, class TManager, class TArray> TMember** CPointerArray<TMember, TManager, TArray>::GetArrayPtr() { return (TMember**)m_Array.GetArrayPtr(); }
template <class TMember, class TManager, class TArray> TMember** CPointerArray<TMember, TManager, TArray>::UnbindPtr() { return (TMember**)m_Array.UnbindPtr(); }
template <class TMember, class TManager, class TArray> void CPointerArray<TMember, TManager, TArray>::Swap(int nIndex1, int nIndex2) { void* pTemp = m_Array[nIndex1]; m_Array.SetAt(nIndex1, m_Array[nIndex2]); m_Array.SetAt(nIndex2, pTemp); }
template <class TMember, class TManager> void CPointerQueue<TMember, TManager>::Clear() { TMember* p; while(p = (TMember*)m_Queue.Dequeue()) { ReleaseElement(p); } }
#endif
|