#ifndef __DYNAMICARRAY_H__ #define __DYNAMICARRAY_H__ // This should really be called "GrowableArray" because it // only grows, it doesn't shrink. #include "genlib.h" template class CDynamicArrayIter; template class CDynamicArray { ////////////////////////////////////////////////// // Friends // friend class CDynamicArrayIter; ////////////////////////////////////////////////// // Enumerated Types // ////////////////////////////////////////////////// // Initialization // public: inline CDynamicArray(); inline ~CDynamicArray(); inline VOID Init(); inline VOID Init(UINT_32); inline VOID Init(UINT_32, Type *); VOID Expand(UINT_32); ////////////////////////////////////////////////// // Input functions // public: inline VOID AddItemToEnd(Type item); inline VOID AddItem(Type item, UINT_32 index); inline VOID SetLastIndex(UINT_32); inline VOID Sort(int (*compar)(const void *, const void *)); ////////////////////////////////////////////////// // Output Functions // public: inline VOID DisplayAll() const; ////////////////////////////////////////////////// // Accessor Functions // public: inline Type *GetItem(UINT_32); inline UINT_32 GetLastIndex() const; inline UINT_32 GetSize() const; inline Type *GetDataPtr() const; ////////////////////////////////////////////////// // Class Variables // ////////////////////////////////////////////////// // Member Variables // protected: UINT_32 m_uiSize; UINT_32 m_uiLast; Type *m_pTData; }; template inline CDynamicArray::CDynamicArray() { m_uiSize = 0; m_uiLast = 0; m_pTData = NULL; } template inline CDynamicArray::~CDynamicArray() { delete [] m_pTData; } template inline VOID CDynamicArray::Init() { m_uiSize = 0; m_uiLast = 0; m_pTData = NULL; } template inline VOID CDynamicArray::Init(UINT_32 uiSize) { ASSERT (uiSize > 0); m_uiSize = uiSize; m_pTData = new Type[uiSize]; UINT_32 i; for (i=0; i < uiSize; i++) { m_pTData[i] = NULL; } } template inline VOID CDynamicArray::Init(UINT_32 uiSize, Type *array) { m_uiSize = uiSize; m_pTData = array; m_uiLast = uiSize; } template inline VOID CDynamicArray::Expand(UINT_32 uiNewSize) { // We hope that we started with a size > 0, or standard practice // of doubling it will make this assertion fail (as it should) ASSERT (uiNewSize > m_uiSize); Type *pNewData; pNewData = new Type[uiNewSize]; // Is there some block copy we could use? UINT_32 i; for (i = 0; i < m_uiSize; i++) { pNewData[i] = m_pTData[i]; } for (i = m_uiSize; i < uiNewSize; i++) { pNewData[i] = NULL; } delete [] m_pTData; m_pTData = pNewData; m_uiSize = uiNewSize; } template inline VOID CDynamicArray::AddItem(Type item, UINT_32 index) { if (index >= m_uiSize) Expand(2*index); m_pTData[index] = item; if (index > m_uiLast) m_uiLast = index; } template inline VOID CDynamicArray::AddItemToEnd(Type item) { if (m_uiLast >= m_uiSize) Expand(2*m_uiSize); m_pTData[m_uiLast++] = item; } // I assume that Last is number actually written (i.e. that no one // has called setLast to change it). template inline VOID CDynamicArray:: Sort(int (*compar)(const void *, const void *)) { qsort((void *)(m_pTData), m_uiLast, sizeof(Type), compar); } template inline VOID CDynamicArray::SetLastIndex(UINT_32 Index) { m_uiLast = Index; } template inline UINT_32 CDynamicArray::GetLastIndex() const { return m_uiLast; } template inline UINT_32 CDynamicArray::GetSize() const { return m_uiSize; } template inline Type *CDynamicArray::GetItem(UINT_32 Index) { if (Index >= m_uiSize) Expand(2*Index); return &(m_pTData[Index]); } template inline VOID CDynamicArray::DisplayAll() const { UINT_32 i; for (i = 0; i < m_uiLast; i++) { cout << m_pTData[i] << "\n"; } } template inline Type *CDynamicArray::GetDataPtr() const { return (m_pTData); } template class CDynamicArrayIter { public: inline CDynamicArrayIter(); inline ~CDynamicArrayIter(); inline VOID Init(CDynamicArray *pCDynamicArray); inline VOID Uninit(); inline BOOL Valid(); public: // Iteration Functions inline Type *PeekFirstItem(); inline Type *PeekNextItem(); protected: UINT_32 m_uiCurr; CDynamicArray *m_pCDynamicArray; }; template inline CDynamicArrayIter::CDynamicArrayIter() { m_uiCurr = 0; m_pCDynamicArray = NULL; } template inline CDynamicArrayIter::~CDynamicArrayIter() { } template inline VOID CDynamicArrayIter::Init(CDynamicArray *pCDynamicArray) { m_pCDynamicArray = pCDynamicArray; m_uiCurr = 0; } template inline VOID CDynamicArrayIter::Uninit() { } template inline BOOL CDynamicArrayIter::Valid() { if (!m_pCDynamicArray) return FALSE; if (m_uiCurr < m_pCDynamicArray->GetLastIndex()) return TRUE; else return FALSE; } template inline Type *CDynamicArrayIter::PeekFirstItem() { m_uiCurr = 0; return m_pCDynamicArray->GetItem(m_uiCurr); } template inline Type *CDynamicArrayIter::PeekNextItem() { return m_pCDynamicArray->GetItem(m_uiCurr++); } #endif // __DYNAMICARRAY_H__