/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ #ifndef SE_INCL_ALLOCATIONARRAY_CPP #define SE_INCL_ALLOCATIONARRAY_CPP #ifdef PRAGMA_ONCE #pragma once #endif #include #include #include extern BOOL _bAllocationArrayParanoiaCheck; /* * Default constructor. */ template inline CAllocationArray::CAllocationArray(void) : CStaticArray(), aa_aiFreeElements() { aa_ctAllocationStep = 256; } /* * Destructor. */ template inline CAllocationArray::~CAllocationArray(void) { }; /* Destroy all objects, and reset the array to initial (empty) state. */ template inline void CAllocationArray::Clear(void) { // delete the objects themselves CStaticArray::Clear(); // clear array of free indices aa_aiFreeElements.Clear(); } /* * Set how many elements to allocate when stack overflows. */ template inline void CAllocationArray::SetAllocationStep(INDEX ctStep) { ASSERT(ctStep>0); aa_ctAllocationStep = ctStep; }; /* * Create a given number of objects. */ template inline void CAllocationArray::New(INDEX iCount) { // never call this! ASSERT(FALSE); }; /* * Destroy all objects. */ template inline void CAllocationArray::Delete(void) { // never call this! ASSERT(FALSE); } /* Alocate a new object. */ template inline INDEX CAllocationArray::Allocate(void) { // if there are no more free indices if (aa_aiFreeElements.Count()==0) { // remember old size INDEX ctOldSize = CStaticArray::Count(); // expand the array by the allocation step Expand(ctOldSize+aa_ctAllocationStep); // create new free indices INDEX *piNewFree = aa_aiFreeElements.Push(aa_ctAllocationStep); // fill them up for(INDEX iNew=0; iNew inline void CAllocationArray::Free(INDEX iToFree) { #ifndef NDEBUG // must be within pool limits ASSERT(iToFree>=0 && iToFree::Count()); // must not be free if (_bAllocationArrayParanoiaCheck) { ASSERT(IsAllocated(iToFree)); } #endif // push its index on top of the free stack aa_aiFreeElements.Push() = iToFree; } /* Free all objects, but keep pool space. */ template inline void CAllocationArray::FreeAll(void) { // clear the free array aa_aiFreeElements.PopAll(); // push as much free elements as there is pool space INDEX ctSize = CStaticArray::Count(); INDEX *piNewFree = aa_aiFreeElements.Push(ctSize); // fill them up for(INDEX iNew=0; iNew inline BOOL CAllocationArray::IsAllocated(INDEX i) { // must be within pool limits ASSERT(i>=0 && i::Count()); // for each free index INDEX ctFree = aa_aiFreeElements.Count(); for(INDEX iFree=0; iFree inline Type &CAllocationArray::operator[](INDEX iObject) { #ifndef NDEBUG ASSERT(this!=NULL); // must be within pool limits ASSERT(iObject>=0 && iObject::Count()); // must not be free if (_bAllocationArrayParanoiaCheck) { ASSERT(IsAllocated(iObject)); } #endif return CStaticArray::operator[](iObject); } template inline const Type &CAllocationArray::operator[](INDEX iObject) const { #ifndef NDEBUG ASSERT(this!=NULL); // must be within pool limits ASSERT(iObject>=0 && iObject::Count()); // must not be free if (_bAllocationArrayParanoiaCheck) { ASSERT(IsAllocated(iObject)); } #endif return CStaticArray::operator[](iObject); } /* Get number of allocated objects in array. */ template INDEX CAllocationArray::Count(void) const { ASSERT(this!=NULL); // it is pool size without the count of free elements return CStaticArray::Count()-aa_aiFreeElements.Count(); } /* Get index of a object from it's pointer. */ template INDEX CAllocationArray::Index(Type *ptObject) { ASSERT(this!=NULL); INDEX i = CStaticArray::Index(ptMember); ASSERT(IsAllocated(i)); return i; } /* Assignment operator. */ template CAllocationArray &CAllocationArray::operator=( const CAllocationArray &aaOriginal) { ASSERT(this!=NULL); (CStaticArray&)(*this) = (CStaticArray&)aaOriginal; aa_aiFreeElements = aaOriginal.aa_aiFreeElements; aa_ctAllocationStep = aaOriginal.aa_ctAllocationStep; } #endif /* include-once check. */