You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
189 lines
4.0 KiB
189 lines
4.0 KiB
/*===================================================================
|
|
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 <class TYPE>
|
|
vector<TYPE>::vector() : m_rgData(NULL), m_cItems(0), m_cCells(0)
|
|
{
|
|
}
|
|
|
|
|
|
template <class TYPE>
|
|
HRESULT vector<TYPE>::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 <class TYPE>
|
|
HRESULT vector<TYPE>::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 <class TYPE>
|
|
vector<TYPE>::~vector()
|
|
{
|
|
delete[] m_rgData;
|
|
}
|
|
|
|
|
|
template <class TYPE>
|
|
HRESULT vector<TYPE>::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 <class TYPE>
|
|
HRESULT vector<TYPE>::reshape(size_t cNewItems)
|
|
{
|
|
HRESULT hrRet = S_OK;
|
|
if (cNewItems > m_cCells)
|
|
hrRet = resize(cNewItems);
|
|
|
|
if (SUCCEEDED(hrRet))
|
|
m_cItems = cNewItems;
|
|
|
|
return hrRet;
|
|
}
|
|
|
|
|
|
template <class TYPE>
|
|
HRESULT vector<TYPE>::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 <class TYPE>
|
|
TYPE vector<TYPE>::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 <class TYPE>
|
|
int vector<TYPE>::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 */
|