/*++ Copyright (C) Microsoft Corporation, 1995 - 1999 Module Name: dynarray Abstract: This header file implements a Dynamic Array. Author: Doug Barlow (dbarlow) 10/5/1995 Environment: Win32, C++ /w Exception Handling Notes: --*/ #ifndef _DYNARRAY_H_ #define _DYNARRAY_H_ // //============================================================================== // // CDynamicArray // template class CDynamicArray { public: // Constructors & Destructor CDynamicArray(void) { m_Max = m_Mac = 0; m_pvList = NULL; }; virtual ~CDynamicArray() { Clear(); }; // Properties // Methods void Clear(void) { if (NULL != m_pvList) { delete[] m_pvList; m_pvList = NULL; m_Max = 0; m_Mac = 0; } }; void Empty(void) { m_Mac = 0; }; T * Set( IN int nItem, IN T *pvItem); T * Insert( IN int nItem, IN T *pvItem); T * Add( IN T *pvItem); T * const Get( IN int nItem) const; DWORD Count(void) const { return m_Mac; }; T ** const Array(void) const { return m_pvList; }; // Operators T * const operator[](int nItem) const { return Get(nItem); }; protected: // Properties DWORD m_Max, // Number of element slots available. m_Mac; // Number of element slots used. T ** m_pvList; // The elements. // Methods }; /*++ Set: This routine sets an item in the collection array. If the array isn't that big, it is expanded with NULL elements to become that big. Arguments: nItem - Supplies the index value to be set. pvItem - Supplies the value to be set into the given index. Return Value: The value of the inserted value, or NULL on errors. Author: Doug Barlow (dbarlow) 7/13/1995 --*/ template inline T * CDynamicArray::Set( IN int nItem, IN T * pvItem) { DWORD index; // // Make sure the array is big enough. // if ((DWORD)nItem >= m_Max) { int newSize = (0 == m_Max ? 4 : m_Max); while (nItem >= newSize) newSize *= 2; T **newList = new T*[newSize]; if (NULL == newList) throw (DWORD)ERROR_OUTOFMEMORY; for (index = 0; index < m_Mac; index += 1) newList[index] = m_pvList[index]; if (NULL != m_pvList) delete[] m_pvList; m_pvList = newList; m_Max = newSize; } // // Make sure intermediate elements are filled in. // if ((DWORD)nItem >= m_Mac) { for (index = m_Mac; index < (DWORD)nItem; index += 1) m_pvList[index] = NULL; m_Mac = (DWORD)nItem + 1; } // // Fill in the list element. // m_pvList[(DWORD)nItem] = pvItem; return pvItem; } /*++ Insert: This routine inserts an element in the array by moving all elements above it up one, then inserting the new element. Arguments: nItem - Supplies the index value to be inserted. pvItem - Supplies the value to be set into the given index. Return Value: The value of the inserted value, or NULL on errors. Author: Doug Barlow (dbarlow) 10/10/1995 --*/ template inline T * CDynamicArray::Insert( IN int nItem, IN T * pvItem) { DWORD index; for (index = nItem; index < m_Mac; index += 1) if (NULL == Set(index + 1, Get(index))) return NULL; // Only the first one can fail, so no change // happens on errors. return Set(nItem, pvItem); } /*++ Add: This method adds an element to the end of the dynamic array. Arguments: pvItem - Supplies the value to be added to the list. Return Value: The value of the added value, or NULL on errors. Author: Doug Barlow (dbarlow) 10/10/1995 --*/ template inline T * CDynamicArray::Add( IN T *pvItem) { return Set(Count(), pvItem); } /*++ Get: This method returns the element at the given index. If there is no element previously stored at that element, it returns NULL. It does not expand the array. Arguments: nItem - Supplies the index into the list. Return Value: The value stored at that index in the list, or NULL if nothing has ever been stored there. Author: Doug Barlow (dbarlow) 7/13/1995 --*/ template inline T * const CDynamicArray::Get( int nItem) const { if (m_Mac <= (DWORD)nItem) return NULL; else return m_pvList[nItem]; } #endif // _DYNARRAY_H_