windows-nt/Source/XPSP1/NT/inetsrv/iis/svcs/cmp/asp51/vecimpl.h
2020-09-26 16:20:57 +08:00

190 lines
3.8 KiB
C++

/*===================================================================
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 */