/* Copyright (c) 2002-2012 Croteam Ltd. This program is free software; you can redistribute it and/or modify it under the terms of version 2 of the GNU General Public License as published by the Free Software Foundation This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef SE_INCL_DYNAMICSTACKARRAY_CPP #define SE_INCL_DYNAMICSTACKARRAY_CPP #ifdef PRAGMA_ONCE #pragma once #endif #include #include /* * Default constructor. */ template inline CDynamicStackArray::CDynamicStackArray(void) : CDynamicArray() { da_ctUsed=0; da_ctAllocationStep = 256; // lock the array on construction CDynamicArray::Lock(); } /* * Destructor. */ template inline CDynamicStackArray::~CDynamicStackArray(void) { // lock the array on destruction CDynamicArray::Unlock(); }; /* Destroy all objects, and reset the array to initial (empty) state. */ template inline void CDynamicStackArray::Clear(void) { CDynamicArray::Clear(); da_ctUsed = 0; } /* * Set how many elements to allocate when stack overflows. */ template inline void CDynamicStackArray::SetAllocationStep(INDEX ctStep) { ASSERT(ctStep>0); da_ctAllocationStep = ctStep; }; /* * Add new object(s) on top of stack. */ template inline Type &CDynamicStackArray::Push(void) { // if there are no free elements in the array if (CDynamicArray::Count()-da_ctUsed<1) { // alocate a new block CDynamicArray::New(da_ctAllocationStep); } // get the new element da_ctUsed++; ASSERT(da_ctUsed <= CDynamicArray::Count()); return CDynamicArray::operator[](da_ctUsed-1); } template inline Type *CDynamicStackArray::Push(INDEX ct) { // if there are no free elements in the array while(CDynamicArray::Count()-da_ctUsed::New(da_ctAllocationStep); } // get new elements da_ctUsed+=ct; ASSERT(da_ctUsed <= CDynamicArray::Count()); return &CDynamicArray::operator[](da_ctUsed-ct); } /* * Remove all objects from stack, but keep stack space. */ template inline void CDynamicStackArray::PopAll(void) { // if there is only one block allocated if ( da_BlocksList.IsEmpty() || &da_BlocksList.Head()==&da_BlocksList.Tail()) { // just clear the counter da_ctUsed = 0; // if there is more than one block allocated } else { // remember how much was allocated, rounded up to allocation step INDEX ctUsedBefore = CDynamicArray::Count(); // free all memory CDynamicArray::Clear(); // allocate one big block CDynamicArray::New(ctUsedBefore); da_ctUsed = 0; } } /* * Random access operator. */ template inline Type &CDynamicStackArray::operator[](INDEX i) { ASSERT(this!=NULL); ASSERT(i::operator[](i); } template inline const Type &CDynamicStackArray::operator[](INDEX i) const { ASSERT(this!=NULL); ASSERT(i::operator[](i); } /* * Get number of elements in array. */ template INDEX CDynamicStackArray::Count(void) const { ASSERT(this!=NULL); return da_ctUsed; } /* * Get index of a member from it's pointer */ template INDEX CDynamicStackArray::Index(Type *ptMember) { ASSERT(this!=NULL); INDEX i = CDynamicArray::Index(ptMember); ASSERTMSG(i::Index(): Not a member of this array!"); return i; } /* * Get array of pointers to elements (used for sorting elements by sorting pointers). */ template Type **CDynamicStackArray::GetArrayOfPointers(void) { return da_Pointers; } /* * Assignment operator. */ template CDynamicStackArray &CDynamicStackArray::operator=(CDynamicStackArray &arOriginal) { ASSERT(this!=NULL); ASSERT(&arOriginal!=NULL); ASSERT(this!=&arOriginal); // copy stack arrays CDynamicArray::operator=(arOriginal); // copy used count da_ctUsed = arOriginal.da_ctUsed; return *this; } #endif /* include-once check. */