Leaked source code of windows server 2003
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.
 
 
 
 
 
 

208 lines
5.6 KiB

/**************************************************************************++
Copyright (c) 2001 Microsoft Corporation
Module name:
cfgarray.h
$Header: $
Abstract:
Author:
marcelv 5/9/2001 12:28:08 Initial Release
Revision History:
--**************************************************************************/
#ifndef __CFGARRAY_H__
#define __CFGARRAY_H__
#pragma once
template <class T>
class CCfgArray
{
public:
CCfgArray () : m_aData(0), m_cElements(0), m_cSize(0) {}
~CCfgArray ()
{
delete [] m_aData;
m_aData = 0;
}
ULONG Count () const
{
return m_cElements;
}
ULONG AllocSize () const
{
return m_cSize;
}
HRESULT SetAllocSize (ULONG i_iNewSize)
{
return AllocNewSize (i_NewSize);
}
HRESULT Append (const T& i_NewElement)
{
return InsertAt (i_NewElement, m_cElements);
}
HRESULT Prepend (const T& i_NewElement)
{
return InsertAt (i_NewElement, 0);
}
HRESULT InsertAt (const T& i_NewElement, ULONG i_idx)
{
HRESULT hr = S_OK;
if (m_cElements==m_cSize)
{
hr = AllocNewSize (m_cSize==0?1:2*m_cSize);
if (FAILED (hr))
{
return hr;
}
}
// move the data in the array. Note that you cannot use
// memmove, because when you have an array of objects that are
// refcounted, you have to call the copy constructor, else you
// get very weird behavior (program crash, etc).
for (ULONG jdx = m_cElements; jdx > i_idx; --jdx)
{
m_aData[jdx] = m_aData[jdx-1];
}
m_aData[i_idx] = i_NewElement;
m_cElements++;
return hr;
}
T& operator[] (ULONG idx) const
{
return m_aData[idx];
};
//=================================================================================
// The Iterator class is used to navigate through the elements in the linked list. Call
// List::Begin to get an iterator pointing to the first element in the list, and call
// Next to get the next element in the list. List::End can be used if we are at the end
// of the list
//=================================================================================
class Iterator
{
private:
void operator =(const Iterator&);
friend class CCfgArray<T>;
public:
//=================================================================================
// Function: Next
//
// Synopsis: get iterator to next element in the list
//=================================================================================
void Next () { m_curIdx++;}
//=================================================================================
// Function: Value
//
// Synopsis: Returns value of element that iterator points to
//=================================================================================
T& Value () const
{
return m_aData[m_curIdx];
}
bool operator== (const Iterator& rhs) const {return m_curIdx == rhs.m_curIdx;}
bool operator!= (const Iterator& rhs) const {return m_curIdx != rhs.m_curIdx;}
private:
Iterator (const CCfgArray<T> * i_paData, ULONG iStart) : m_aData(*i_paData), m_curIdx (iStart) {} // only list can create these
ULONG m_curIdx;
const CCfgArray<T>& m_aData;
};
//=================================================================================
// Function: Begin
//
// Synopsis: Returns an iterator to the beginning of the list
//=================================================================================
const Iterator Begin () const
{
return Iterator (this, 0);
}
//=================================================================================
// Function: End
//
// Synopsis: Returns an iterator one past the end of the list (like STL does)
//=================================================================================
const Iterator End () const
{
return Iterator (this, m_cElements);
}
// returns index of place to insert element in sorted array
ULONG BinarySearch (const T& i_ElemToSearch) const
{
ULONG iLow = 0;
ULONG iHigh = m_cElements;
while (iLow < iHigh)
{
// (low + high) / 2 might overflow
ULONG iMid = iLow + (iHigh - iLow) / 2;
if (m_aData[iMid] > i_ElemToSearch)
{
iHigh = iMid;
}
else
{
iLow = iMid + 1;
}
}
return iLow;
}
private:
HRESULT AllocNewSize (ULONG i_NewSize)
{
T * aNewData = new T [i_NewSize];
if (aNewData == 0)
{
return E_OUTOFMEMORY;
}
// copy the data from the old array in the new array.
// you have to use the copy constructor (and not memcpy), to avoid
// all kind of weird errors. When you use memcpy, you are not updating
// possible refcounts that are part of type T, and thus you get possible
// crashes
for (ULONG idx=0; idx < m_cSize; ++idx)
{
aNewData[idx] = m_aData[idx];
}
delete[] m_aData;
m_aData = aNewData;
m_cSize = i_NewSize;
return S_OK;
}
// we don't allow copies
CCfgArray (const CCfgArray<T>& );
CCfgArray<T>& operator=(const CCfgArray<T>& );
T * m_aData;
ULONG m_cSize;
ULONG m_cElements;
};
#endif