145 lines
3.8 KiB
C++
145 lines
3.8 KiB
C++
/* @doc INTERNAL
|
|
*
|
|
* @module _ARRAY.H Generic Array Class |
|
|
*
|
|
* This module declares a generic array class for constant sized
|
|
* elements (although the elements themselves may be of any size).
|
|
*
|
|
* Original Author: <nl>
|
|
* Christian Fortini
|
|
*
|
|
* History: <nl>
|
|
* 6/25/95 alexgo Cleanup and Commenting
|
|
*
|
|
* Copyright (c) 1995-1997, Microsoft Corporation. All rights reserved.
|
|
*/
|
|
|
|
#ifndef _ARRAY_H
|
|
#define _ARRAY_H
|
|
|
|
class CFormatRunPtr;
|
|
|
|
/*
|
|
* ArrayFlag
|
|
*
|
|
* @enum Defines flags used with the array class
|
|
*/
|
|
enum tagArrayFlag
|
|
{
|
|
AF_KEEPMEM = 1, //@emem Don't delete any memory
|
|
AF_DELETEMEM = 2, //@emem Delete as much memory as possible
|
|
};
|
|
|
|
//@type ArrayFlag | flags controlling the usage of generic arrays
|
|
//(and specifically how memory is handled)
|
|
typedef enum tagArrayFlag ArrayFlag;
|
|
|
|
|
|
/*
|
|
* CArrayBase
|
|
*
|
|
* @class The CArrayBase class implements a generic array class. It should
|
|
* never be used directly; use the type-safe template, <c CArray>, instead.
|
|
*
|
|
* @devnote There are exactly two legal states for an array: empty or not.
|
|
* If an array is empty, the following must be true:
|
|
*
|
|
* <md CArrayBase::_prgel> == NULL; <nl>
|
|
* <md CArrayBase::_cel> == 0; <nl>
|
|
* <md CArrayBase::_celMax> == 0;
|
|
*
|
|
* Otherwise, the following must be true:
|
|
*
|
|
* <md CArrayBase::_prgel> != NULL; <nl>
|
|
* <md CArrayBase::_cel> <lt>= <md CArrayBase::_celMax>; <nl>
|
|
* <md CArrayBase::_celMax> <gt> 0;
|
|
*
|
|
*
|
|
* An array starts empty, transitions to not-empty as elements are inserted
|
|
* and will transistion back to empty if all of the array elements are
|
|
* removed.
|
|
*
|
|
*/
|
|
class CArrayBase
|
|
{
|
|
//@access Public Methods
|
|
public:
|
|
|
|
#ifdef DEBUG
|
|
BOOL Invariant() const; //@cmember Validates state consistentency
|
|
void* Elem(LONG iel) const; //@cmember Get ptr to <p iel>'th run
|
|
#else
|
|
void* Elem(LONG iel) const {return _prgel + iel*_cbElem;}
|
|
#endif
|
|
|
|
CArrayBase (LONG cbElem); //@cmember Constructor
|
|
~CArrayBase () {Clear(AF_DELETEMEM);}
|
|
|
|
void Clear (ArrayFlag flag); //@cmember Delete all runs in array
|
|
LONG Count() const {return _cel;}//@cmember Get count of runs in array
|
|
//@cmember Remove <p celFree> runs from
|
|
// array, starting at run <p ielFirst>
|
|
void Remove(LONG ielFirst, LONG celFree);
|
|
//@cmember Replace runs <p iel> through
|
|
// <p iel+cel-1> with runs from <p par>
|
|
BOOL Replace (LONG iel, LONG cel, CArrayBase *par);
|
|
|
|
LONG Size() const {return _cbElem;}//@cmember Get size of a run
|
|
|
|
//@access Protected Methods
|
|
protected:
|
|
void* ArAdd (LONG cel, LONG *pielIns); //@cmember Add <p cel> runs
|
|
void* ArInsert(LONG iel, LONG celIns); //@cmember Insert <p celIns>
|
|
// runs
|
|
|
|
//@access Protected Data
|
|
protected:
|
|
char* _prgel; //@cmember Pointer to actual array data
|
|
LONG _cel; //@cmember Count of used entries in array
|
|
LONG _celMax; //@cmember Count of allocated entries in array
|
|
LONG _cbElem; //@cmember Byte count of an individual array element
|
|
};
|
|
|
|
/*
|
|
* CArray
|
|
*
|
|
* @class
|
|
* An inline template class providing type-safe access to CArrayBase
|
|
*
|
|
* @tcarg class | ELEM | the class or struct to be used as array elements
|
|
*/
|
|
|
|
template <class ELEM>
|
|
class CArray : public CArrayBase
|
|
{
|
|
//@access Public Methods
|
|
public:
|
|
|
|
CArray () //@cmember Constructor
|
|
: CArrayBase(sizeof(ELEM))
|
|
{}
|
|
|
|
ELEM * Elem(LONG iel) const //@cmember Get ptr to <p iel>'th
|
|
{ // element
|
|
return (ELEM *)CArrayBase::Elem(iel);
|
|
}
|
|
|
|
ELEM& GetAt(LONG iel) const //@cmember Get <p iel>'th element
|
|
{
|
|
return *(ELEM *)CArrayBase::Elem(iel);
|
|
}
|
|
|
|
ELEM* Add (LONG cel, LONG *pielIns) //@cmember Adds <p cel> elements
|
|
{ // to end of array
|
|
return (ELEM*)ArAdd(cel, pielIns);
|
|
}
|
|
|
|
ELEM* Insert (LONG iel, LONG celIns) //@cmember Insert <p celIns>
|
|
{ // elements at index <p iel>
|
|
return (ELEM*)ArInsert(iel, celIns);
|
|
}
|
|
|
|
};
|
|
|
|
#endif
|