// // This file contains proprietary information of Borland International. // Copying or reproduction without prior written approval is prohibited. // // Copyright (c) 1990 // Borland International // 1800 Scotts Valley Dr. // Scotts Valley, CA 95066 // (408) 438-8400 // // Contents ---------------------------------------------------------------- // // AbstractArray::AbstractArray constructor // AbstractArray::~AbstractArray destructor // AbstractArray::detach Object // AbstractArray::detach int // AbstractArray::hashValue // AbstractArray::reallocate // AbstractArray::isEqual // AbstractArray::initIterator // AbstractArray::printContentsOn // // ArrayIterator::operator int // ArrayIterator::operator Object // ArrayIterator::restart // ArrayIterator::operator ++ // // Description // // Implementation of class AbstractArray and class ArrayIterator member // functions. // // End --------------------------------------------------------------------- // Interface Dependencies --------------------------------------------------- #ifndef __IOSTREAM_H #include #define __IOSTREAM_H #endif #ifndef __STDLIB_H #include #define __STDLIB_H #endif #ifndef __ASSERT_H #include #define __ASSERT_H #endif #ifndef __CLSDEFS_H #include #endif #ifndef __CLSTYPES_H #include #endif #ifndef __OBJECT_H #include #endif #ifndef __CONTAIN_H #include #endif #ifndef __ABSTARRY_H #include #endif // End Interface Dependencies ------------------------------------------------ // Implementation Dependencies ---------------------------------------------- // End Implementation Dependencies ------------------------------------------- // Constructor // AbstractArray::AbstractArray( int anUpper, int aLower, sizeType aDelta ) // Summary ----------------------------------------------------------------- // // Constructor for an abstract array. An abstract array can be made // to be either of a fixed or expanding size. In an expanding array, // when a reference is made to an index greater than the current upper // bound of the array, the array will grow to allow the given index // to reference a valid array object. The number of elements by // which this growth is performed is given by the parameter aDelta. // // Parameters // // anUpper // // The upper bound for the array. // // aLower // // The lower bound for the array. The initial size of the array is // calculated from the upper and lower bounds. // // aDelta // // The growth factor for the array. // // Functional Description // // We set up the private parts of the array, allocate space for the // pointers, then set all the allocated pointers to point to the // error object. // // End --------------------------------------------------------------------- { lowerbound = whereToAdd = aLower; upperbound = anUpper; delta = aDelta; theArray = new Object *[ arraySize() ]; for( int i = 0; i < arraySize(); i++ ) { theArray[ i ] = ZERO; } // end for } // End Constructor AbstractArray::AbstractArray // // Destructor // AbstractArray::~AbstractArray() // Summary ----------------------------------------------------------------- // // Destructor for a AbstractArray object. // // End --------------------------------------------------------------------- { for( int i = 0; i < arraySize(); i++ ) if( theArray[ i ] != ZERO ) delete theArray[ i ]; delete [ arraySize() ] theArray; } // End Destructor // // Member Function // void AbstractArray::detach( const Object& toDetach, int deleteObjectToo ) // Summary ----------------------------------------------------------------- // // Detaches an object from the array. // // Parameter // // toDetach // // The object we are to search for and detach from the AbstractArray. // // deleteObjectToo // // Specifies whether we are to delete the object. // // Functional Description // // If the object specified is at the lower bound of the array, we remove // the reference right away. Otherwise, we iterate through the array until // we find it, then remove the reference. // // Remarks // // warnings: // No error condition is generated if the object which was specified // isn't in the array. // // End --------------------------------------------------------------------- { if ( toDetach == NOOBJECT ) return; for ( int i = 0; i < arraySize(); i++ ) { if ( ( theArray[ i ] != ZERO ) && ( *theArray[ i ] == toDetach ) ) { if ( deleteObjectToo ) { delete theArray[ i ]; } theArray[ i ] = ZERO; itemsInContainer--; break; } } // end for // } // End Member Function AbstractArray::detach // // Member Function // void AbstractArray::detach( int atIndex, int deleteObjectToo ) // Summary ----------------------------------------------------------------- // // Detaches an object from the array at the given index. // // Parameter // // toIndex // // The index from which we are to detach the object. // // deleteObjectToo // // Specifies whether we are to delete the object. // // Remarks // // warnings: // No error condition is generated if the object which was specified // isn't in the array. // // End --------------------------------------------------------------------- { if ( theArray[ atIndex - lowerbound ] != ZERO ) { if ( deleteObjectToo ) { delete ( theArray[ atIndex - lowerbound ] ); } theArray[ atIndex - lowerbound ] = ZERO; itemsInContainer--; } // end if there was an element already there in the array. } // End Member Function AbstractArray::detach // // Member Function // hashValueType AbstractArray::hashValue() const // Summary ----------------------------------------------------------------- // // Returns the hash value of a array. // // End --------------------------------------------------------------------- { return hashValueType(0); } // End Member Function AbstractArray::hashValue // // Member Function // void AbstractArray::reallocate( sizeType newSize ) // Summary ----------------------------------------------------------------- // // Reallocates the array's pointer vector to a new size. // // Parameters // // newSize // // The number of pointers which is to be in the new vector. // // Functional Description // // We allocate space for a new pointer vector of the given size, // adjusted to take into account the growth factor. We then copy // the old vector into the new one and fix up the pointer in the // array object. // // Remarks // // assumptions // Asserts that the new size of the pointer vector is greater than // the current size. We do "expanding-only" arrays, not accordions. // // End --------------------------------------------------------------------- { if ( delta == 0 ) { cerr << "Error: Attempting to expand a fixed size array."; exit(__EEXPAND); } int i; // Loop counter for moving the pointers from the old vector // to the new one. // Body Comment // // We assume that the new pointer vector size is greater than the // current vector size. // // End assert ( newSize > arraySize() ); sizeType adjustedSize = newSize + ( delta - ( newSize % delta ) ); Object **newArray = new Object *[ adjustedSize ]; if ( newArray == 0 ) { cerr << "Error: Out of Memory"; exit(__ENOMEM); } for ( i = 0; i < arraySize(); i++ ) { newArray[i] = theArray[i]; } for (; i < adjustedSize; i++ ) { newArray[i] = ZERO; } delete [ arraySize() ] theArray; theArray = newArray; upperbound = adjustedSize + lowerbound - 1; } // End Member Function AbstractArray::reallocate // // Member Function // int AbstractArray::isEqual( const Object& testObject ) const // Summary ----------------------------------------------------------------- // // Tests for equality of two arrays. Two arrays are equal if they // have the same dimensions and the same objects at the same indices. // // Parameters // // testObject // // The array which we will be testing against this. // // End --------------------------------------------------------------------- { if ( lowerbound != ((AbstractArray&)testObject).lowerbound || upperbound != ((AbstractArray&)testObject).upperbound ) { return 0; } for ( int i = 0; i < arraySize(); i++ ) { // Body Comment // // The two array elements can be null, so check that first. // If there are really objects there, compare them for equality. // // End if ( theArray[i] != ZERO ) { if ( ((AbstractArray&)testObject).theArray[i] != ZERO ) { if ( *theArray[i] != *( ((AbstractArray &)testObject).theArray[i] ) ) { return 0; // objects weren't equal. } } else // the first pointer wasn't ZERO but the second was { return 0; } } else if ( ((AbstractArray&)testObject).theArray[i] != ZERO ) { return 0; // first pointer was ZERO but the second wasn't } } // end for each element in the array. return 1; } // End Member Function AbstractArray::isEqual // // Member Function // ContainerIterator& AbstractArray::initIterator() const // Summary ----------------------------------------------------------------- // // Initializes an iterator for a list. // // End --------------------------------------------------------------------- { return *( (ContainerIterator *)new ArrayIterator( *this ) ); } // End Member Function AbstractArray::initIterator // // Member Function // void AbstractArray::printContentsOn( ostream& outputStream ) const // Summary ----------------------------------------------------------------- // // Displays the non-ZERO contents of an array on the given stream. // // Parameters // // outputStream // // The stream on which we will be writing the contents. // // Functional Description // // We initialize an iterator, then iterator through each object, // asking the objects to print themselves if they are not the // error object. // // Remarks // // warnings: // We must be sure to delete the container iterator, since it was // allocated on the heap. // // End --------------------------------------------------------------------- { ContainerIterator& printIterator = initIterator(); printHeader( outputStream ); while( int(printIterator) != 0 ) { Object& arrayObject = printIterator++; if ( arrayObject != NOOBJECT ) { arrayObject.printOn( outputStream ); if ( int(printIterator) != 0 ) { printSeparator( outputStream ); } else // there are no more objects in the array. { break; } } // end if the array object is NOOBJECT. } // end while // printTrailer( outputStream ); delete &printIterator; } // End Member Function AbstractArray::printContentsOn // // Destructor // ArrayIterator::~ArrayIterator() // Summary ----------------------------------------------------------------- // // Destructor for a ArrayIterator object. // // End --------------------------------------------------------------------- { } // End Destructor // // Member Function // ArrayIterator::operator int() // Summary ----------------------------------------------------------------- // // Integer conversion for an array iterator. // // End --------------------------------------------------------------------- { return currentIndex <= beingIterated.upperbound; } // End Member Function operator int // // Member Function // ArrayIterator::operator Object&() // Summary ----------------------------------------------------------------- // // Object reference conversion for an array iterator. // // End --------------------------------------------------------------------- { if ( currentIndex <= beingIterated.upperbound ) { return ( (Object&)( beingIterated.objectAt( currentIndex ) ) ); } else // no more elements in the array. { return NOOBJECT; } } // End Member Function operator Object& // // Member Function // void ArrayIterator::restart() // Summary ----------------------------------------------------------------- // // ArrayIterator restart. // // End --------------------------------------------------------------------- { currentIndex = beingIterated.lowerbound; } // End Member Function ArrayIterator::restart // // Member Function // Object& ArrayIterator::operator ++() // Summary ----------------------------------------------------------------- // // Increments the array iterator and returns the next object. // // End --------------------------------------------------------------------- { if ( currentIndex <= beingIterated.upperbound ) { currentIndex++; return ( (Object&)( beingIterated.objectAt( currentIndex - 1 ) ) ); } else // no more elements in the array. { return NOOBJECT; } } // End Member Function ArrayIterator::operator ++//