|
#ifndef __OBJPOOL_H__
#define __OBJPOOL_H__
#pragma once // WATCOM special to include a header only once
class clsCrit
{
private:
CRITICAL_SECTION _Crit;
clsCrit(const clsCrit&) // NO NO NO NO! No copy constructor!!!
{
}
public:
clsCrit(void)
{
InitializeCriticalSection(&_Crit);
}
~clsCrit(void)
{
DeleteCriticalSection(&_Crit);
}
void Enter(void) const
{
EnterCriticalSection(const_cast<CRITICAL_SECTION*>(&_Crit));
}
void Leave(void) const
{
LeaveCriticalSection(const_cast<CRITICAL_SECTION*>(&_Crit));
}
};
class clsCritObj
{
private:
const clsCrit* _pCrit;
public:
clsCritObj(const clsCrit& Sync)
{
(_pCrit = &Sync)->Enter();
}
~clsCritObj(void)
{
_pCrit->Leave();
}
};
typedef void* _CHK_PVOID;
template<int S>
class clsPointerArray
{
private:
_CHK_PVOID* _Array;
int _nEntriesAllocated;
int _nEntriesUsed;
public:
clsPointerArray(void)
{
_Array = NULL;
_nEntriesUsed = 0;
_nEntriesAllocated = 0;
}
virtual ~clsPointerArray(void)
{
if (_nEntriesUsed)
_chk_utildebug(TEXT("WRN: objects left in pool!"));
}
void* Get(void)
{
if (_nEntriesUsed <= 0)
return(NULL);
return(_Array[--_nEntriesUsed]);
}
void Add(void* p)
{
if (_nEntriesUsed + 1 > _nEntriesAllocated)
{
_CHK_PVOID* pNew = ::new _CHK_PVOID[_nEntriesAllocated + S];
memcpy(pNew,_Array,_nEntriesUsed * sizeof(_CHK_PVOID));
_nEntriesAllocated += S;
delete[] _Array;
_Array = pNew;
}
_Array[_nEntriesUsed++] = p;
}
};
template <class T, int S = 16> // S = size increment in pool allocation
class clsObjectPool
{
private:
#if !_OBJPOOL_NO_MULTITHREADING
static clsCrit& CS(void)
{
static clsCrit __Crit;
return(__Crit);
}
#endif
static clsPointerArray<S>& List(void)
{
static clsPointerArray<S> __FreeItems;
return(__FreeItems);
}
public:
clsObjectPool()
{
}
virtual ~clsObjectPool()
{
}
void* operator new(size_t stAllocateBlock)
{
#if !_OBJPOOL_NO_MULTITHREADING
clsCritObj CO(CS());
#endif
clsPointerArray<S>& VList(T::List());
void* pNewObject(VList.Get());
if (pNewObject == NULL)
pNewObject = ::new T;
return(pNewObject);
}
void operator delete(void *p)
{
#if !_OBJPOOL_NO_MULTITHREADING
clsCritObj CO(CS());
#endif
clsPointerArray<S>& VList(T::List());
VList.Add(p);
}
void Clear(void)
{
#if !_OBJPOOL_NO_MULTITHREADING
clsCritObj CO(CS());
#endif
clsPointerArray<S>& VList(T::List());
while (true)
{
void* pObject(VList.Get());
if (pObject == NULL)
break;
::delete reinterpret_cast<T*>(pObject);
}
}
};
#endif
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.