/* Copyright (c) 2002-2012 Croteam Ltd. All rights reserved. */ #ifndef SE_INCL_STATICARRAY_CPP #define SE_INCL_STATICARRAY_CPP #ifdef PRAGMA_ONCE #pragma once #endif #define FOREACHINSTATICARRAY(array, type, iter) \ for(CStaticArrayIterator iter(array); !iter.IsPastEnd(); iter.MoveToNext() ) #include #include /* * Default constructor. */ template inline CStaticArray::CStaticArray(void) { sa_Count=0; sa_Array=NULL; } /* * Destructor. */ template inline CStaticArray::~CStaticArray(void) { // if some objects were allocated if (sa_Count!=0) { // destroy them Delete(); } }; /* Random access operator. */ template inline void CStaticArray::operator=(const CStaticArray &arOriginal) { CopyArray(arOriginal); } template /* Destroy all objects, and reset the array to initial (empty) state. */ inline void CStaticArray::Clear(void) { if (sa_Count!=0) Delete(); } /* * Create a given number of objects. */ template inline void CStaticArray::New(INDEX iCount) { ASSERT(this!=NULL && iCount>=0); // if no new members are needed in fact if (iCount==0) { // do nothing return; } //ASSERT(sa_Count==0 && sa_Array==NULL); #ifndef NDEBUG if(!(sa_Count==0 && sa_Array==NULL)) { if(sa_Array == NULL) { CPrintF("CStaticArray array not set!\n"); } else { CPrintF("CStaticArray new(%d) called while already holding %d elements!\n", iCount, sa_Count); } } #endif sa_Count = iCount; sa_Array = new Type[iCount+1]; //(+1 for cache-prefetch opt) }; /* Expand stack size but keep old objects. */ template inline void CStaticArray::Expand(INDEX iNewCount) { ASSERT(this!=NULL && iNewCount>sa_Count); // if not already allocated if (sa_Count==0) { // just allocate New(iNewCount); return; // if already allocated } else { ASSERT(sa_Count!=0 && sa_Array!=NULL); // allocate new array with more space Type *ptNewArray = new Type[iNewCount+1]; //(+1 for cache-prefetch opt) // copy old objects for (INDEX iOld=0; iOld inline void CStaticArray::Delete(void) { ASSERT(this!=NULL); ASSERT(sa_Count!=0 && sa_Array!=NULL); delete[] sa_Array; sa_Count = 0; sa_Array = NULL; } /* * Random access operator. */ template inline Type &CStaticArray::operator[](INDEX i) { ASSERT(this!=NULL); ASSERT(i>=0 && i inline const Type &CStaticArray::operator[](INDEX i) const { ASSERT(this!=NULL); ASSERT(i>=0 && i INDEX CStaticArray::Count(void) const { ASSERT(this!=NULL); return sa_Count; } /* * Get index of a member from it's pointer */ template INDEX CStaticArray::Index(Type *ptMember) { ASSERT(this!=NULL); INDEX i = ptMember-sa_Array; ASSERT(i>=0 && i /* Copy all elements of another array into this one. */ void CStaticArray::CopyArray(const CStaticArray &arOriginal) { ASSERT(this!=NULL); ASSERT(&arOriginal!=NULL); ASSERT(this!=&arOriginal); // clear previous contents Clear(); // get count of elements in original array INDEX ctOriginal = arOriginal.Count(); // if the other array has no elements if (ctOriginal ==0) { return; } // create that much elements New(ctOriginal); // copy them all for (INDEX iNew=0; iNew void CStaticArray::MoveArray(CStaticArray &arOther) { ASSERT(this!=NULL); ASSERT(&arOther!=NULL); ASSERT(this!=&arOther); // clear previous contents Clear(); // if the other array has no elements if (arOther.Count()==0) { // no assignment return; } // move data from the other array into this one and clear the other one sa_Count = arOther.sa_Count; sa_Array = arOther.sa_Array; arOther.sa_Count = 0; arOther.sa_Array = NULL; } ///////////////////////////////////////////////////////////////////// // CStaticArrayIterator /* * Template class for iterating static array. */ template class CStaticArrayIterator { private: INDEX sai_Index; // index of current element CStaticArray &sai_Array; // reference to array public: /* Constructor for given array. */ inline CStaticArrayIterator(CStaticArray &sa); /* Destructor. */ inline ~CStaticArrayIterator(void); /* Move to next object. */ inline void MoveToNext(void); /* Check if finished. */ inline BOOL IsPastEnd(void); /* Get current element. */ Type &Current(void) { return sai_Array[sai_Index]; } Type &operator*(void) { return sai_Array[sai_Index]; } operator Type *(void) { return &sai_Array[sai_Index]; } Type *operator->(void) { return &sai_Array[sai_Index]; } }; /* * Constructor for given array. */ template inline CStaticArrayIterator::CStaticArrayIterator(CStaticArray &sa) : sai_Array(sa) { sai_Index = 0; } /* * Destructor. */ template inline CStaticArrayIterator::~CStaticArrayIterator(void) { sai_Index = -1; } /* * Move to next object. */ template inline void CStaticArrayIterator::MoveToNext(void) { ASSERT(this!=NULL); sai_Index++; } /* * Check if finished. */ template inline BOOL CStaticArrayIterator::IsPastEnd(void) { ASSERT(this!=NULL); return sai_Index>=sai_Array.sa_Count; } #endif /* include-once check. */