/*=================================================================== Microsoft Denali Microsoft Confidential. Copyright 1997 Microsoft Corporation. All Rights Reserved. Component: misc File: vector.h Owner: DGottner This file contains a dynamic array ===================================================================*/ /* * This file is derived from software bearing the following * restrictions: * * Copyright 1994, David Gottner * * All Rights Reserved * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice, this permission notice and * the following disclaimer notice appear unmodified in all copies. * * I DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL I * BE LIABLE FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * */ #ifndef VECIMPL_H #define VECIMPL_H #define VEC_GROW_SIZE 64 // grow in chunks of this many items #define __vec_rounded_size(s) \ (((s) + (VEC_GROW_SIZE - 1)) & ~(VEC_GROW_SIZE - 1)) template vector::vector() : m_rgData(NULL), m_cItems(0), m_cCells(0) { } template HRESULT vector::Init(const TYPE *anArray, size_t theSize) { m_cCells = __vec_rounded_size(theSize); register size_t n = m_cItems = theSize; register TYPE * pDest = m_rgData = new TYPE[m_cCells]; register const TYPE *pSrc = anArray; if (pDest == NULL) { m_cItems = m_cCells = 0; return E_OUTOFMEMORY; } while (n--) *pDest++ = *pSrc++; return S_OK; } template HRESULT vector::Init(size_t n) { m_rgData = new TYPE[m_cCells = __vec_rounded_size(m_cItems = n)]; if (m_rgData == NULL) { m_cItems = m_cCells = 0; return E_OUTOFMEMORY; } return S_OK; } template vector::~vector() { delete[] m_rgData; } template HRESULT vector::resize(size_t cNewCells) { cNewCells = __vec_rounded_size(cNewCells); if (m_cCells == cNewCells) return S_OK; TYPE *rgData = new TYPE[cNewCells]; if (rgData == NULL) return E_OUTOFMEMORY; register size_t n = (m_cItems < cNewCells)? m_cItems : cNewCells; register TYPE * pDest = rgData; register const TYPE *pSrc = m_rgData; m_cItems = n; m_cCells = cNewCells; while (n--) *pDest++ = *pSrc++; delete[] m_rgData; m_rgData = rgData; return S_OK; } template HRESULT vector::reshape(size_t cNewItems) { HRESULT hrRet = S_OK; if (cNewItems > m_cCells) hrRet = resize(cNewItems); if (SUCCEEDED(hrRet)) m_cItems = cNewItems; return hrRet; } template HRESULT vector::insertAt(size_t pos, const TYPE &item) { Assert (pos <= m_cItems); HRESULT hrRet = S_OK; if ((m_cItems + 1) > m_cCells) hrRet = resize(m_cCells + VEC_GROW_SIZE); if (SUCCEEDED(hrRet)) { TYPE *pDest = &m_rgData[pos]; for (register TYPE *ptr = &m_rgData[m_cItems]; ptr > pDest; --ptr) *ptr = *(ptr - 1); *pDest = item; ++m_cItems; } return hrRet; } template TYPE vector::removeAt(size_t pos) { Assert (pos < m_cItems); TYPE * end = &m_rgData[--m_cItems]; register TYPE *ptr = &m_rgData[pos]; TYPE val = *ptr; for (; ptr < end; ++ptr) *ptr = *(ptr + 1); return val; } template int vector::find(const TYPE &item) const { for (register unsigned i = 0; i < m_cItems; ++i) if (item == m_rgData[i]) return i; return -1; } #endif /* VECIMPL */