You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nvidia-texture-tools/extern/pvrtextool/Include/PVRTArray.h

569 lines
17 KiB
C++

/******************************************************************************
@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<typename T>
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;i++)
{
m_pArray[i]=original.m_pArray[i];
}
}
/*!***************************************************************************
@Function CPVRTArray
@Input pArray an ordinary array
@Input uiSize number of elements passed
@Description constructor from ordinary array.
*****************************************************************************/
CPVRTArray(const T* const pArray, const unsigned int uiSize) : m_uiSize(uiSize),
m_uiCapacity(uiSize)
{
_ASSERT(uiSize != 0);
m_pArray = new T[uiSize];
for(unsigned int i=0;i<m_uiSize;i++)
{
m_pArray[i]=pArray[i];
}
}
/*!***************************************************************************
@Function CPVRTArray
@Input uiSize initial capacity
@Input val value to populate with
@Description constructor from a capacity and initial value.
*****************************************************************************/
CPVRTArray(const unsigned int uiSize, const T& val) : m_uiSize(uiSize),
m_uiCapacity(uiSize)
{
_ASSERT(uiSize != 0);
m_pArray = new T[uiSize];
for(unsigned int uiIndex = 0; uiIndex < m_uiSize; ++uiIndex)
{
m_pArray[uiIndex] = val;
}
}
/*!***************************************************************************
@Function ~CPVRTArray
@Description Destructor.
*****************************************************************************/
virtual ~CPVRTArray()
{
if(m_pArray)
delete [] m_pArray;
}
/*!***************************************************************************
@Function Insert
@Input pos The position to insert the new element at
@Input addT The element to insert
@Return The index of the new item or -1 on failure.
@Description Inserts an element into the array, expanding it
if necessary.
*****************************************************************************/
int Insert(const unsigned int pos, const T& addT)
{
unsigned int uiIndex = pos;
if(pos >= 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<typename T2>
void Copy(const CPVRTArray<T2>& 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<T>& 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<T>& 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<class Pred>
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<typename T>
class CPVRTArrayManagedPointers : public CPVRTArray<T*>
{
public:
virtual ~CPVRTArrayManagedPointers()
{
if(this->m_pArray)
{
for(unsigned int i=0;i<this->m_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)
*****************************************************************************/