//////////////////////////////////////////////////////////////////////////// // class CArray - an array containing 'TYPE' elements, // passed in parameters as ARG_TYPE // // NOTE: ARG_TYPE must be either an lvalue or a reference type; no pointers; // that is, the type of &ARG_TYPE must be the same as &TYPE. // //////////////////////////////////////////////////////////////////////////// //$DECLARE_TEMPLATE //////////////////////////////////////////////////////////////////////////// template class FAR CArray { public: // Construction CArray(DWORD memctx = MEMCTX_SAME) : m_afv(memctx, sizeof(TYPE)) { } ~CArray() { } // Attributes int GetSize() const { return m_afv.GetSize(); } int GetUpperBound() const { return m_afv.GetSize()-1; } BOOL SetSize(int nNewSize, int nGrowBy = -1) { return m_afv.SetSize(nNewSize, nGrowBy); } int GetSizeValue() const { return m_afv.GetSizeValue(); } // Operations // Clean up void FreeExtra() { m_afv.FreeExtra(); } void RemoveAll() { m_afv.SetSize(0); } // return pointer to element; index must be in range TYPE GetAt(int nIndex) const { return *(TYPE FAR*)m_afv.GetAt(nIndex); } TYPE FAR& ElementAt(int nIndex) { return (TYPE FAR&)*(TYPE FAR*)m_afv.GetAt(nIndex); } // overloaded operator helpers TYPE operator[](int nIndex) const { return GetAt(nIndex); } TYPE FAR& operator[](int nIndex) { return ElementAt(nIndex); } // set element; index must be in range void SetAt(int nIndex, ARG_TYPE value) { m_afv.SetAt(nIndex, (LPVOID)&value); } // find element given part of one; offset is offset into value; returns // -1 if element not found; use IndexOf(NULL, cb, offset) to find zeros; // will be optimized for appropriate value size and param combinations int IndexOf(LPVOID pData, UINT cbData, UINT offset) { return m_afv.IndexOf(pData, cbData, offset); } // set/add element; Potentially growing the array; return FALSE/-1 if // not possible (due to OOM) BOOL SetAtGrow(int nIndex, ARG_TYPE value) { return m_afv.SetAtGrow(nIndex, (LPVOID)&value); } int Add(ARG_TYPE value) { int nIndex = GetSize(); return SetAtGrow(nIndex, value) ? nIndex : -1; } // Operations that move elements around BOOL InsertAt(int nIndex, ARG_TYPE value, int nCount = 1) { return m_afv.InsertAt(nIndex, (LPVOID)&value, nCount); } void RemoveAt(int nIndex, int nCount = 1) { m_afv.RemoveAt(nIndex, nCount); } void AssertValid() const { m_afv.AssertValid(); } // Implementation private: CArrayFValue m_afv; };