____________________

VarArray.pas	Release 1
____________________
Created by Michael Rynn
    1998 Nov 11

	michrynn@ozemail.com.au
____________________

This unit supplies a base type, TVarArray,for manipulation of
dynamic arrays of fixed size elements. Its probably not much different from other
dynamic array units you may have seen, except its pretty basic.


The distinguished property of the TVarArray
is that  member elements which require futher initialization and/or additional
dynamic storage can be "constructed" and "destructed" via the protected virtual
methods of ConstructItem and DestructItem. Resizing, insertions and deletions
are supported, in which ConstructItem and DestructItem are called appropriately.

An example of this is given below with the class TStrStrVArray, a sorted array
which stores a record type with 2 strings, one being a variable name
and the other its value.

ConstructItem and DestructItem will be called if the TVarArray is
constructed  with CreateBase(itemsize, initItems = TRUE). If initItems is false,
the ConstructItem and DestructItem will not be called.  Please note the base
constructor CreateBase does not allocate any memory for the array. This is done
in derived class constructors by setting the Count propery.

TIntVArray, TDoubleVArray subclass the TVarArray for integer and double types,
without really adding much else.

TIntVArray associates an integer with a Delphi long string type. There doesn't seem
to be much use for it, but I have used it for one project.

____________________
The System ReallocMem routine is used for array re-sizing.
A hidden array element at index (-1) supports a generic element swap.
Because of this, setting count to zero does not deallocate the block,
which can only be freed by setting Count := -1; // done in Destroy

Reallocation changes the BlockPtr (which points to the zeroth element,
not the start of the allocated memory block).
Access to a type-specific pointer is facilitated in sub-classes
by setting FBlockHdl as a pointer to your type-specific pointer, so that
it will always be automatically updated after a ReallocMem call.
____________________
GetItemIndex and Sort routines both use the CompareItems method.
____________________
If setting capacity in advance, turn AutoShrink off so that capacity will not
shrink again after the first change to count eg by insertion or deletion.
Capacity cannot be reduced to below count size.
____________________
Packed record types

eg
{$A+}
   TArrayElement = record
		byte1, byte2, byte3 : Byte;   {4 bytes}
   end;

   TArray = array[0..n] of TArrayElement {400 bytes}

Note that if the word packed is used in the record

  TArrayElement = packed record
		byte1, byte2, byte3 : Byte;    {3 bytes}
   end;

It doesn't seem to matter to the compiler if the array type is
declared as packed or not. But as TVarArray always treats the
memory block as a packed array of type, it should probably be
always declared as such.

TArray = packed array[0..99] of TArrayElement ;  {300 bytes}
TArray = array[0..99] of TArrayElement ;  {300 bytes}

Significant memory savings can sometimes be made with packed record types,
the trade off being the alignment access efficiency.
_____________________
History
MR
May 98:  A quick and dirty array type created for a project, and it grew a little
July 98: Use Assert. TStrStrVArray added. Insert and Delete Items for TVarArray
Sept 98: Delphi 1 support code added
Nov  98: Revised & documented for release 1

