/****************************************************************************** @File PVRTArray.h @Title PVRTArray @Version @Copyright Copyright (c) Imagination Technologies Limited. All Rights Reserved. Strictly Confidential. @Platform ANSI compatible @Description Expanding array template class. Allows appending and direct access. Mixing access methods should be approached with caution. ******************************************************************************/ #ifndef __PVRTARRAY_H__ #define __PVRTARRAY_H__ //ACS: PVRTGlobal.h was dragging in too much stuff (like windows.h & crtdbg.h) // so I split the relevant stuff out into a new file, PVRTTypes.h //#include "PVRTGlobal.h" #include "PVRTTypes.h" #include "PVRTError.h" /*!**************************************************************************** Class ******************************************************************************/ /*!*************************************************************************** * @Class CPVRTArray * @Brief Expanding array template class. * @Description Expanding array template class. *****************************************************************************/ template class CPVRTArray { public: /*!*************************************************************************** @Function CPVRTArray @Description Blank constructor. Makes a default sized array. *****************************************************************************/ CPVRTArray() : m_uiSize(0), m_uiCapacity(GetDefaultSize()) { m_pArray = new T[m_uiCapacity]; } /*!*************************************************************************** @Function CPVRTArray @Input uiSize intial size of array @Description Constructor taking initial size of array in elements. *****************************************************************************/ CPVRTArray(const unsigned int uiSize) : m_uiSize(0), m_uiCapacity(uiSize) { _ASSERT(uiSize != 0); m_pArray = new T[uiSize]; } /*!*************************************************************************** @Function CPVRTArray @Input original the other dynamic array @Description Copy constructor. *****************************************************************************/ CPVRTArray(const CPVRTArray& original) : m_uiSize(original.m_uiSize), m_uiCapacity(original.m_uiCapacity) { m_pArray = new T[m_uiCapacity]; for(unsigned int i=0;i= m_uiSize) // Are we adding to the end uiIndex = Append(addT); else { unsigned int uiNewCapacity = 0; T* pArray = m_pArray; if(m_uiSize > m_uiCapacity) { uiNewCapacity = m_uiCapacity + 10; // Expand the array by 10. pArray = new T[uiNewCapacity]; // New Array if(!pArray) return -1; // Failed to allocate memory! // Copy the first half to the new array for(unsigned int i = 0; i < pos; ++i) { pArray[i] = m_pArray[i]; } } // Copy last half to the new array for(unsigned int i = m_uiSize; i > pos; --i) { pArray[i] = m_pArray[i - 1]; } // Insert our new element pArray[pos] = addT; uiIndex = pos; // Increase our size ++m_uiSize; // Switch pointers and free memory if needed if(pArray != m_pArray) { m_uiCapacity = uiNewCapacity; delete[] m_pArray; m_pArray = pArray; } } return uiIndex; } /*!*************************************************************************** @Function Append @Input addT The element to append @Return The index of the new item. @Description Appends an element to the end of the array, expanding it if necessary. *****************************************************************************/ unsigned int Append(const T& addT) { unsigned int uiIndex = Append(); m_pArray[uiIndex] = addT; return uiIndex; } /*!*************************************************************************** @Function Append @Return The index of the new item. @Description Creates space for a new item, but doesn't add. Instead returns the index of the new item. *****************************************************************************/ unsigned int Append() { unsigned int uiIndex = m_uiSize; SetCapacity(m_uiSize+1); m_uiSize++; return uiIndex; } /*!*************************************************************************** @Function Clear @Description Clears the array. *****************************************************************************/ void Clear() { m_uiSize = 0U; } /*!*************************************************************************** @Function Resize @Input uiSize New size of array @Description Changes the array to the new size *****************************************************************************/ EPVRTError Resize(const unsigned int uiSize) { EPVRTError err = SetCapacity(uiSize); if(err != PVR_SUCCESS) return err; m_uiSize = uiSize; return PVR_SUCCESS; } /*!*************************************************************************** @Function SetCapacity @Input uiSize New capacity of array @Description Expands array to new capacity *****************************************************************************/ EPVRTError SetCapacity(const unsigned int uiSize) { if(uiSize <= m_uiCapacity) return PVR_SUCCESS; // nothing to be done unsigned int uiNewCapacity; if(uiSize < m_uiCapacity*2) { uiNewCapacity = m_uiCapacity*2; // Ignore the new size. Expand to twice the previous size. } else { uiNewCapacity = uiSize; } T* pNewArray = new T[uiNewCapacity]; // New Array if(!pNewArray) return PVR_FAIL; // Failed to allocate memory! // Copy source data to new array for(unsigned int i = 0; i < m_uiSize; ++i) { pNewArray[i] = m_pArray[i]; } // Switch pointers and free memory m_uiCapacity = uiNewCapacity; T* pOldArray = m_pArray; m_pArray = pNewArray; delete [] pOldArray; return PVR_SUCCESS; } /*!*************************************************************************** @Function Copy @Input other The CPVRTArray needing copied @Description A copy function. Will attempt to copy from other CPVRTArrays if this is possible. *****************************************************************************/ template void Copy(const CPVRTArray& other) { T* pNewArray = new T[other.GetCapacity()]; if(pNewArray) { // Copy data for(unsigned int i = 0; i < other.GetSize(); i++) { pNewArray[i] = other[i]; } // Free current array if(m_pArray) delete [] m_pArray; // Swap pointers m_pArray = pNewArray; m_uiCapacity = other.GetCapacity(); m_uiSize = other.GetSize(); } } /*!*************************************************************************** @Function = @Input other The CPVRTArray needing copied @Description assignment operator. *****************************************************************************/ CPVRTArray& operator=(const CPVRTArray& other) { if(&other != this) Copy(other); return *this; } /*!*************************************************************************** @Function operator+= @Input other the array to append. @Description appends an existing CPVRTArray on to this one. *****************************************************************************/ CPVRTArray& operator+=(const CPVRTArray& other) { if(&other != this) { for(unsigned int uiIndex = 0; uiIndex < other.GetSize(); ++uiIndex) { Append(other[uiIndex]); } } return *this; } /*!*************************************************************************** @Function [] @Input uiIndex index of element in array @Return the element indexed @Description indexed access into array. Note that this has no error checking whatsoever *****************************************************************************/ T& operator[](const unsigned int uiIndex) { _ASSERT(uiIndex < m_uiCapacity); return m_pArray[uiIndex]; } /*!*************************************************************************** @Function [] @Input uiIndex index of element in array @Return The element indexed @Description Indexed access into array. Note that this has no error checking whatsoever *****************************************************************************/ const T& operator[](const unsigned int uiIndex) const { _ASSERT(uiIndex < m_uiCapacity); return m_pArray[uiIndex]; } /*!*************************************************************************** @Function GetSize @Return Size of array @Description Gives current size of array/number of elements *****************************************************************************/ unsigned int GetSize() const { return m_uiSize; } /*!*************************************************************************** @Function GetDefaultSize @Return Default size of array @Description Gives the default size of array/number of elements *****************************************************************************/ static unsigned int GetDefaultSize() { return 16U; } /*!*************************************************************************** @Function GetCapacity @Return Capacity of array @Description Gives current allocated size of array/number of elements *****************************************************************************/ unsigned int GetCapacity() const { return m_uiCapacity; } /*!*************************************************************************** @Function Contains @Input object The object to check in the array @Return true if object is contained in this array. @Description Indicates whether the given object resides inside the array. *****************************************************************************/ bool Contains(const T& object) const { for(unsigned int uiIndex = 0; uiIndex < m_uiSize; ++uiIndex) { if(m_pArray[uiIndex] == object) return true; } return false; } /*!*************************************************************************** @Function Find @Input object The object to check in the array @Return pointer to the found object or NULL. @Description Attempts to find the object in the array and returns a pointer if it is found, or NULL if not found. The time taken is O(N). *****************************************************************************/ T* Find(const T& object) const { for(unsigned int uiIndex = 0; uiIndex < m_uiSize; ++uiIndex) { if(m_pArray[uiIndex] == object) return &m_pArray[uiIndex]; } return NULL; } /*!*************************************************************************** @Function Sort @Input predicate The object which defines "bool operator()" @Description Simple bubble-sort of the array. Pred should be an object that defines a bool operator(). *****************************************************************************/ template void Sort(Pred predicate) { bool bSwap; for(unsigned int i=0; i < m_uiSize; ++i) { bSwap = false; for(unsigned int j=0; j < m_uiSize-1; ++j) { if(predicate(m_pArray[j], m_pArray[j+1])) { PVRTswap(m_pArray[j], m_pArray[j+1]); bSwap = true; } } if(!bSwap) return; } } /*!*************************************************************************** @Function Remove @Input uiIndex The index to remove @Return success or failure @Description Removes an element from the array. *****************************************************************************/ virtual EPVRTError Remove(unsigned int uiIndex) { _ASSERT(uiIndex < m_uiSize); if(m_uiSize == 0) return PVR_FAIL; if(uiIndex == m_uiSize-1) { return RemoveLast(); } m_uiSize--; // Copy the data. memmove will only work for built-in types. for(unsigned int uiNewIdx = uiIndex; uiNewIdx < m_uiSize; ++uiNewIdx) { m_pArray[uiNewIdx] = m_pArray[uiNewIdx+1]; } return PVR_SUCCESS; } /*!*************************************************************************** @Function RemoveLast @Return success or failure @Description Removes the last element. Simply decrements the size value *****************************************************************************/ virtual EPVRTError RemoveLast() { if(m_uiSize > 0) { m_uiSize--; return PVR_SUCCESS; } else { return PVR_FAIL; } } protected: unsigned int m_uiSize; /*! current size of contents of array */ unsigned int m_uiCapacity; /*! currently allocated size of array */ T *m_pArray; /*! the actual array itself */ }; // note "this" is required for ISO standard C++ and gcc complains otherwise // http://lists.apple.com/archives/Xcode-users//2005/Dec/msg00644.html template class CPVRTArrayManagedPointers : public CPVRTArray { public: virtual ~CPVRTArrayManagedPointers() { if(this->m_pArray) { for(unsigned int i=0;im_uiSize;i++) { delete(this->m_pArray[i]); } } } /*!*************************************************************************** @Function Remove @Input uiIndex The index to remove @Return success or failure @Description Removes an element from the array. *****************************************************************************/ virtual EPVRTError Remove(unsigned int uiIndex) { _ASSERT(uiIndex < this->m_uiSize); if(this->m_uiSize == 0) return PVR_FAIL; if(uiIndex == this->m_uiSize-1) { return this->RemoveLast(); } unsigned int uiSize = (this->m_uiSize - (uiIndex+1)) * sizeof(T*); delete this->m_pArray[uiIndex]; memmove(this->m_pArray + uiIndex, this->m_pArray + (uiIndex+1), uiSize); this->m_uiSize--; return PVR_SUCCESS; } /*!*************************************************************************** @Function RemoveLast @Return success or failure @Description Removes the last element. Simply decrements the size value *****************************************************************************/ virtual EPVRTError RemoveLast() { if(this->m_uiSize > 0 && this->m_pArray) { delete this->m_pArray[this->m_uiSize-1]; this->m_uiSize--; return PVR_SUCCESS; } else { return PVR_FAIL; } } }; #endif // __PVRTARRAY_H__ /***************************************************************************** End of file (PVRTArray.h) *****************************************************************************/