UTILIB TUTORIAL W. Hart, C. Phillips This is a brief tutorial on how to use array-type classes in utilib. This is just what you need to get up and running. I'll touch on implementation where necessary to explain behavior and where useful for debugging. The primary advantage of using these classes is extra safety features such as runtime bounds checking and reference counting. Also bit arrays can save a lot of space. The files BasicArray.doc and SimpleArray.doc files contain the actual function prototypes, information on packBuffers (for sending these objects between parallel processes), and details on reference counting and ownership of the data. One-dimensional arrays: The most common types of 1D arrays are bits, ints, and doubles. The syntax for doubles and ints are similar, so I'll only include examples for IntVectors. I'll indicate where BitArray syntax differs. To use these arrays, you need to include the appropriate header files: #include "BitArray.H" #include "DoubleVector.H" #include "IntVector.H" You can then declare variables as usual: IntVector IntTester; BitArray BitTester; All of these ArrayData classes have a pointer to the data in the field a->Data. You can get this pointer using the data() function. int *intarray = IntTester.data(); Ordinarily, you will not need to do this, but it can be useful for debugging. Inside a debugger like dbx, saying print *IntTester will return useful information like the data location, size, etc, and print IntTester.a->Data[i] allows you to view the ith entry in the IntVector. Constructors: The declarations above (no arguments) construct an object with a NULL data pointer. One can also specify the initial content of the IntVector: int array-of-ints[20]; IntVector IntTester(20, array-of-ints); The first argument is the length of the array and the second is a pointer to an array of the appropriate type. The data field in the IntVector will point to this array. One can construct a copy of an existing IntVector: IntVector CopiedVector(IntTester); This will allocate a new integer vector and initialize it with the contents of IntTester. The Data field in CopiedVector points to the new copy. Resizing: Frequently, one will need to use an empty constructor (i.e. start with a size-zero vector) and then put in the true data. More generally, you may want to grow and shrink the vector dynamically: IntTester.resize(100); This will allocate a new array of 100 integers and copy the old data (if any) into the beginning of the array. Do not assume anything about the uninitialized data. That is, if a 30-element array is resized to 70, the first 30 elements of the new array will be the values from the old array, and you cannot assume anything about the next 40 values (initialize or set them yourself). If an array of size 70 is resized to 30, then the last 40 elements are truncated. Getting the length: IntTester.len() returns the length of IntTester (in integers [more generally, array elements], not bytes). Making copies: The equals (=) operator allocates new space. Thus CopiedVector = IntTester; creates a new integer array and copies the contents of IntTester into that array. The Data field of CopiedVector points to the new space. If the vector already exists and you want to reuse the already-allocated space, use the << operator: ExistingIntVector << IntTester; This copies the contents of the Data array from IntTester into the array for ExistingIntVector. The allocated arrays must be of the same size or you will get an error. To copy by reference, use the &= operator. Thus Intvector SharedVector &= IntTester; will have the data of SharedVector point to the same array that the data of IntTester points to (reference counts are properly updated). Another way to initialize: The equals (=) operator is overloaded to allow (re)initialization of a vector that's already been created. intTester = 15; Sets every element of intTester to 15 (or obviously some other integer). Getting array elements: This looks like normal array references (at least for 1D arrays): int index, newvalue; IntTester[index] = newvalue; newvalue = IntTester[index]; Here's where BitArray syntax varies slightly. Instead of saying: BitTester[index] = 1; // wrong you should use BitTester.set(index); // turns the (index)th bit on BitTester.reset(index); // turns the (index)th bit off There are ways to manipulate consecutive subvectors. I haven't needed them, so I'm omitting them for now so I can get this out. However, if I ever need that (or someone else asks), I'll add it to this basic documentation.