windows-nt/Source/XPSP1/NT/windows/richedit/re41/dynarray.h
2020-09-26 16:20:57 +08:00

137 lines
3.3 KiB
C++

/*
* @doc INTERNAL
*
* @module DYNARRAY.H -- CDynamicArray class which is used to complement
* the CLstBxWndHost object.
*
* Original Author:
* Jerry Kim
*
* History: <nl>
* 12/15/97 - v-jerrki Created
*
* Copyright (c) 1997-2000 Microsoft Corporation. All rights reserved.
*/
#include "_w32sys.h"
#ifndef __DYNARRAY_H__
#define __DYNARRAY_H__
#define DYNARRAY_ARRAY_SIZE 128
#define DYNARRAY_ARRAY_SLOT 256
template<class T>
class CDynamicArray
{
protected:
T* _rg[DYNARRAY_ARRAY_SLOT];
int _nMax; //indicate maximum valid index
public:
static T _sDummy; // dummy struct if invalid index is requested
public:
CDynamicArray() : _nMax(0) { memset(_rg, 0, sizeof(T*) * DYNARRAY_ARRAY_SLOT); }
~CDynamicArray() { Clear(); }
//==========================================================================
// Reinitializes the class to its construction state
//==========================================================================
void Clear()
{
// Start removing all items from the list
// Start removing items from the list
for (int i = ((_nMax - 1) / DYNARRAY_ARRAY_SIZE); i >= 0; i--)
{
if (_rg[i])
delete _rg[i];
}
_nMax = 0;
memset(_rg, 0, sizeof(T*) * DYNARRAY_ARRAY_SLOT);
}
const T& Get(int i);
T& operator[](int i);
};
//==========================================================================
// The function returns the requested index. if the requested index is
// invalid then return dummy variable
//==========================================================================
template <class T>
const T& CDynamicArray<T>::Get(int i)
{
// If item is negative or equal to zero, for efficiency reasons,
// then just return the item in the head of array
Assert(i >= 0);
Assert(i < DYNARRAY_ARRAY_SLOT * DYNARRAY_ARRAY_SIZE);
// Get the number of links we have to travel
int nSlot = i / DYNARRAY_ARRAY_SIZE;
int nIdx = i % DYNARRAY_ARRAY_SIZE;
// That link doesn't exist so just pass dummy struct
Assert(nSlot < DYNARRAY_ARRAY_SLOT);
if (i >= _nMax || nSlot >= DYNARRAY_ARRAY_SLOT || _rg[nSlot] == NULL)
{
_sDummy._fSelected = 0;
_sDummy._lparamData = 0;
_sDummy._uHeight = 0;
return _sDummy;
}
//return value at requested index
return _rg[nSlot][nIdx];
}
//==========================================================================
// The function will be called if a l-value is requested therefore
// the index does not necessarily have to be valid
//==========================================================================
template <class T>
T& CDynamicArray<T>::operator[](int i)
{
Assert(i >= 0);
// Get the slot number and index
int nSlot = i / DYNARRAY_ARRAY_SIZE;
int nIdx = i % DYNARRAY_ARRAY_SIZE;
// Check if the slot exists
Assert(nSlot < DYNARRAY_ARRAY_SLOT);
if (nSlot >= DYNARRAY_ARRAY_SLOT)
return _sDummy;
if (_rg[nSlot] == NULL)
{
//Need to allocate memory for this
T* prg = new T[DYNARRAY_ARRAY_SIZE];
if (!prg)
{
_sDummy._fSelected = 0;
_sDummy._lparamData = 0;
_sDummy._uHeight = 0;
return _sDummy;
}
memset(prg, 0, sizeof(T) * DYNARRAY_ARRAY_SIZE);
_rg[nSlot] = prg;
if (nSlot >= _nMax / DYNARRAY_ARRAY_SIZE)
_nMax = (nSlot + 1) * DYNARRAY_ARRAY_SIZE;
}
//return value at requested index
return _rg[nSlot][nIdx];
}
#endif //__DYNARRAY_H__