123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274 |
- /* 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_STATICARRAY_CPP
- #define SE_INCL_STATICARRAY_CPP
- #ifdef PRAGMA_ONCE
- #pragma once
- #endif
- #define FOREACHINSTATICARRAY(array, type, iter) \
- for(CStaticArrayIterator<type> iter(array); !iter.IsPastEnd(); iter.MoveToNext() )
- #include <Engine/Base/Console.h>
- #include <Engine/Templates/StaticArray.h>
- /*
- * Default constructor.
- */
- template<class Type>
- inline CStaticArray<Type>::CStaticArray(void) {
- sa_Count=0;
- sa_Array=NULL;
- }
- /*
- * Destructor.
- */
- template<class Type>
- inline CStaticArray<Type>::~CStaticArray(void) {
- // if some objects were allocated
- if (sa_Count!=0) {
- // destroy them
- Delete();
- }
- };
- /* Random access operator. */
- template<class Type>
- inline void CStaticArray<Type>::operator=(const CStaticArray<Type> &arOriginal) {
- CopyArray(arOriginal);
- }
- template<class Type>
- /* Destroy all objects, and reset the array to initial (empty) state. */
- inline void CStaticArray<Type>::Clear(void) {
- if (sa_Count!=0) Delete();
- }
- /*
- * Create a given number of objects.
- */
- template<class Type>
- inline void CStaticArray<Type>::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<class Type>
- inline void CStaticArray<Type>::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<sa_Count; iOld++) {
- ptNewArray[iOld] = sa_Array[iOld];
- }
- // free old array
- delete[] sa_Array;
- // remember the new array
- sa_Count = iNewCount;
- sa_Array = ptNewArray;
- }
- }
- /*
- * Destroy all objects.
- */
- template<class Type>
- inline void CStaticArray<Type>::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<class Type>
- inline Type &CStaticArray<Type>::operator[](INDEX i) {
- ASSERT(this!=NULL);
- ASSERT(i>=0 && i<sa_Count); // check bounds
- return sa_Array[i];
- }
- template<class Type>
- inline const Type &CStaticArray<Type>::operator[](INDEX i) const {
- ASSERT(this!=NULL);
- ASSERT(i>=0 && i<sa_Count); // check bounds
- return sa_Array[i];
- }
- /*
- * Get number of elements in array.
- */
- template<class Type>
- INDEX CStaticArray<Type>::Count(void) const {
- ASSERT(this!=NULL);
- return sa_Count;
- }
- /*
- * Get index of a member from it's pointer
- */
- template<class Type>
- INDEX CStaticArray<Type>::Index(Type *ptMember) {
- ASSERT(this!=NULL);
- INDEX i = ptMember-sa_Array;
- ASSERT(i>=0 && i<sa_Count);
- return i;
- }
- /*
- * Assignment operator.
- */
- template<class Type>
- /* Copy all elements of another array into this one. */
- void CStaticArray<Type>::CopyArray(const CStaticArray<Type> &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<ctOriginal; iNew++) {
- sa_Array[iNew] = arOriginal[iNew];
- }
- }
- /* Move all elements of another array into this one. */
- template<class Type>
- void CStaticArray<Type>::MoveArray(CStaticArray<Type> &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 Type>
- class CStaticArrayIterator {
- private:
- INDEX sai_Index; // index of current element
- CStaticArray<Type> &sai_Array; // reference to array
- public:
- /* Constructor for given array. */
- inline CStaticArrayIterator(CStaticArray<Type> &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<class Type>
- inline CStaticArrayIterator<Type>::CStaticArrayIterator(CStaticArray<Type> &sa) : sai_Array(sa) {
- sai_Index = 0;
- }
- /*
- * Destructor.
- */
- template<class Type>
- inline CStaticArrayIterator<Type>::~CStaticArrayIterator(void) {
- sai_Index = -1;
- }
- /*
- * Move to next object.
- */
- template<class Type>
- inline void CStaticArrayIterator<Type>::MoveToNext(void) {
- ASSERT(this!=NULL);
- sai_Index++;
- }
- /*
- * Check if finished.
- */
- template<class Type>
- inline BOOL CStaticArrayIterator<Type>::IsPastEnd(void) {
- ASSERT(this!=NULL);
- return sai_Index>=sai_Array.sa_Count;
- }
- #endif /* include-once check. */
|