windows-nt/Source/XPSP1/NT/multimedia/directx/dxg/ref8/inc/templarr.hpp
2020-09-26 16:20:57 +08:00

224 lines
5.6 KiB
C++

///////////////////////////////////////////////////////////////////////////////
// Copyright (C) Microsoft Corporation, 1998.
//
// temparr.hpp
//
// Template class used by Direct3D RefDev for stateset and so on.
//
// The following error codes should be defined before included this file:
// DDERR_OUTOFMEMORY
// D3D_OK
// DDERR_INVALIDPARAMS
///////////////////////////////////////////////////////////////////////////////
#ifndef _TEMPLARR_HPP
#define _TEMPLARR_HPP
//--------------------------------------------------------------------------
//
// Template for growable arrays
//
//--------------------------------------------------------------------------
template <class ARRAY_ELEMENT>
class GArrayT
{
public:
GArrayT()
{
m_pArray = NULL;
m_dwArraySize = 0;
m_dwGrowSize = 8;
}
~GArrayT()
{
char tmp[256];
wsprintf( tmp, "m_dwArraySize = %d, m_pArray = %08x\n", m_dwArraySize,
m_pArray );
_ASSERT( !((m_dwArraySize == 0)^(m_pArray == NULL)), tmp );
if( m_pArray ) delete[] m_pArray;
}
virtual void SetGrowSize( DWORD dwGrowSize)
{
m_dwGrowSize = dwGrowSize;
}
virtual HRESULT Grow( DWORD dwIndex )
{
if( dwIndex < m_dwArraySize ) return S_OK;
DWORD dwNewArraySize = (dwIndex/m_dwGrowSize + 1) * m_dwGrowSize;
ARRAY_ELEMENT *pNewArray = AllocArray( dwNewArraySize );
if( pNewArray == NULL ) return DDERR_OUTOFMEMORY;
for( DWORD i = 0; i<m_dwArraySize; i++ )
pNewArray[i] = m_pArray[i];
delete[] m_pArray;
m_pArray = pNewArray;
m_dwArraySize = dwNewArraySize;
return S_OK;
}
virtual HRESULT Grow( DWORD dwIndex, BOOL* pRealloc )
{
if( dwIndex < m_dwArraySize )
{
if( pRealloc ) *pRealloc = FALSE;
return S_OK;
}
if( pRealloc ) *pRealloc = TRUE;
DWORD dwNewArraySize = m_dwArraySize;
while( dwNewArraySize <= dwIndex ) dwNewArraySize += m_dwGrowSize;
ARRAY_ELEMENT *pNewArray = AllocArray( dwNewArraySize );
if( pNewArray == NULL ) return DDERR_OUTOFMEMORY;
for( DWORD i = 0; i<m_dwArraySize; i++ )
pNewArray[i] = m_pArray[i];
delete[] m_pArray;
m_pArray = pNewArray;
m_dwArraySize = dwNewArraySize;
return S_OK;
}
virtual ARRAY_ELEMENT *AllocArray( DWORD dwSize ) const
{
return new ARRAY_ELEMENT[dwSize];
}
virtual ARRAY_ELEMENT& operator []( DWORD dwIndex ) const
{
char tmp[256];
wsprintf( tmp, "dwIndex = %d, m_dwArraySize = %d\n", dwIndex,
m_dwArraySize );
_ASSERT(dwIndex < m_dwArraySize, tmp);
return m_pArray[dwIndex];
}
virtual BOOL IsValidIndex( DWORD dwIndex ) const
{
return (dwIndex < m_dwArraySize);
}
virtual DWORD GetSize() const
{
return m_dwArraySize;
}
virtual DWORD GetGrowSize() const
{
return m_dwGrowSize;
}
protected:
ARRAY_ELEMENT *m_pArray;
DWORD m_dwArraySize;
DWORD m_dwGrowSize;
};
//--------------------------------------------------------------------------
//
// A more powerful template for a growable array
//
//--------------------------------------------------------------------------
template <class T> class TemplArray
{
public:
TemplArray( void );
~TemplArray( void );
// It is the user of this operator who makes sure 0<=iIndex<m_dwArraySize.
T& operator []( int iIndex );
HRESULT CheckAndGrow( DWORD iIndex, DWORD dwGrowDelta = 16 );
HRESULT CheckRange ( DWORD iIndex );
// The user needs to make sure 0<=m_dwCurrent<m_dwArraySize.
inline T CurrentItem(void) { return m_pArray[m_dwCurrent];};
inline void SetCurrentItem(T item) { m_pArray[m_dwCurrent] = item;};
inline DWORD CurrentIndex(void) { return m_dwCurrent;};
inline void SetCurrentIndex(DWORD dwIdx) {m_dwCurrent = dwIdx;};
inline DWORD ArraySize(void) { return m_dwArraySize;};
private:
T *m_pArray;
DWORD m_dwArraySize;
// Index to the current item or the size of data stored in the array
DWORD m_dwCurrent;
};
template <class T>
TemplArray< T >::TemplArray( void )
{
m_pArray = NULL;
m_dwArraySize = 0;
m_dwCurrent = 0;
}
template <class T>
TemplArray< T >::~TemplArray( void )
{
if (m_pArray != NULL)
delete m_pArray;
m_dwArraySize = 0;
}
template <class T> T&
TemplArray< T >::operator[]( int iIndex )
{
return m_pArray[iIndex];
}
template <class T> HRESULT
TemplArray< T >::CheckAndGrow( DWORD iIndex, DWORD dwGrowDelta )
{
if (iIndex >= m_dwArraySize)
{
DWORD dwNewArraySize = m_dwArraySize + dwGrowDelta;
while (iIndex >= dwNewArraySize)
dwNewArraySize += dwGrowDelta;
T *pTmpArray = new T[dwNewArraySize];
if (pTmpArray == NULL)
return DDERR_OUTOFMEMORY;
memset(pTmpArray, 0, sizeof(T) * dwNewArraySize);
if (m_pArray != NULL)
{
_ASSERT(m_dwArraySize != 0,
"CheckAndGrow: Array size cannot be NULL" );
// Copy existing stuff into new array
memcpy(pTmpArray, m_pArray, m_dwArraySize * sizeof(T));
// Free up existing array
delete [] m_pArray;
}
// Assign new array
m_pArray = pTmpArray;
m_dwArraySize = dwNewArraySize;
}
return D3D_OK;
}
template <class T> HRESULT
TemplArray< T >::CheckRange( DWORD iIndex )
{
if (iIndex >= m_dwArraySize)
{
return DDERR_INVALIDPARAMS;
}
return D3D_OK;
}
#endif _TEMPLARR_HPP