home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 May / Pcwk5b98.iso / Borland / Cplus45 / BC45 / CLOBSS.PAK / ABSTARRY.CPO next >
Text File  |  1995-08-29  |  7KB  |  273 lines

  1. /*------------------------------------------------------------------------*/
  2. /*                                                                        */
  3. /*  ABSTARRY.CPP                                                          */
  4. /*                                                                        */
  5. /*  Copyright Borland International 1991, 1993                            */
  6. /*  All Rights Reserved                                                   */
  7. /*                                                                        */
  8. /*------------------------------------------------------------------------*/
  9.  
  10. #if !defined( __IOSTREAM_H )
  11. #include <iostream.h>
  12. #endif    // __IOSTREAM_H
  13.  
  14. #if !defined( __STDLIB_H )
  15. #include <stdlib.h>
  16. #endif    // __STDLIB_H
  17.  
  18. #if !defined( __MEM_H )
  19. #include <mem.h>
  20. #endif  // __MEM_H
  21.  
  22. #if !defined( __CHECKS_H )
  23. #include <checks.h>
  24. #endif  // CHECKS_H
  25.  
  26. #if !defined( __ABSTARRY_H )
  27. #include "classlib\obsolete\abstarry.h"
  28. #endif  // __ABSTARRY_H
  29.  
  30. AbstractArray::AbstractArray( int anUpper, int aLower, sizeType aDelta )
  31. {
  32.     PRECONDITION( anUpper >= aLower );
  33.     lastElementIndex = aLower - 1;
  34.     lowerbound = aLower;
  35.     upperbound = anUpper;
  36.     delta = aDelta;
  37.  
  38.     theArray = new Object *[ arraySize() ];
  39.     if( theArray == 0 )
  40.         ClassLib_error(__ENOMEM);
  41.  
  42.     for( int i = 0; i < arraySize(); i++ )
  43.         {
  44.         theArray[ i ] = ZERO;
  45.         }
  46. }
  47.  
  48. AbstractArray::~AbstractArray()
  49. {
  50.     PRECONDITION( theArray != 0 );
  51.     if( ownsElements() )
  52.         for( int i = 0; i < arraySize(); i++ )
  53.             if( theArray[ i ] != ZERO )
  54.                 delete theArray[ i ];
  55.     delete [] theArray;
  56. }
  57.  
  58. void AbstractArray::detach( Object& toDetach, DeleteType dt )
  59. {
  60.     detach( find( toDetach ), dt );
  61. }
  62.  
  63. void AbstractArray::detach( int atIndex, DeleteType dt )
  64. {
  65.     PRECONDITION( atIndex >= lowerbound &&
  66.                   atIndex <= upperbound && theArray != 0
  67.                 );
  68.  
  69.     if( ptrAt(atIndex) != ZERO )
  70.         {
  71.         if( delObj(dt) )
  72.             delete ptrAt(atIndex);
  73.         itemsInContainer--;
  74.         }
  75.     removeEntry(atIndex);
  76.     if( atIndex <= lastElementIndex )
  77.         lastElementIndex--;
  78.     CHECK( itemsInContainer != UINT_MAX );
  79. }
  80.  
  81. void AbstractArray::flush( DeleteType dt )
  82. {
  83.     if( delObj(dt) )
  84.         for( unsigned i = 0; i <= zeroBase(upperbound); i++ )
  85.             if( theArray[i] != ZERO )
  86.                 delete theArray[i];
  87.  
  88.     for( unsigned i = 0; i <= zeroBase(upperbound); i++ )
  89.         theArray[i] = ZERO;
  90.  
  91.     itemsInContainer = 0;
  92.     lastElementIndex = lowerbound-1;
  93. }
  94.  
  95. inline unsigned nextDelta( unsigned sz, unsigned delta )
  96. {
  97.     return (sz%delta) ? ((sz+delta)/delta)*delta : sz;
  98. }
  99.  
  100. void AbstractArray::reallocate( sizeType newSize )
  101. {
  102.     PRECONDITION( newSize > arraySize() );
  103.     if( delta == 0 )
  104.         ClassLib_error(__EEXPANDFS);
  105.  
  106.     sizeType adjustedSize = arraySize() +
  107.                             nextDelta( newSize - arraySize(), delta );
  108.     Object **newArray = new Object *[ adjustedSize ];
  109.     if( newArray == 0 )
  110.         ClassLib_error(__ENOMEM);
  111.  
  112.     memcpy( newArray, theArray, arraySize() * sizeof( theArray[0] ) );
  113.  
  114.     for( int i = arraySize(); i < adjustedSize; i++ )
  115.         newArray[i] = ZERO;
  116.  
  117.     delete [] theArray;
  118.     theArray = newArray;
  119.     upperbound = adjustedSize + lowerbound - 1;
  120. }
  121.  
  122. void AbstractArray::setData( int loc, Object *data )
  123. {
  124.     PRECONDITION( loc >= lowerbound && loc <= upperbound );
  125.     theArray[ zeroBase(loc) ] = data;
  126. }
  127.  
  128. void AbstractArray::insertEntry( int loc )
  129. {
  130.     PRECONDITION( loc >= lowerbound && loc <= upperbound );
  131.     memmove( theArray + zeroBase(loc) + 1,
  132.              theArray + zeroBase(loc),
  133.              (upperbound - loc)*sizeof( theArray[0] )
  134.            );
  135. }
  136.  
  137. void AbstractArray::removeEntry( int loc )
  138. {
  139.     if( loc >= lastElementIndex )
  140.         theArray[zeroBase(loc)] = ZERO;
  141.     else
  142.         squeezeEntry( zeroBase(loc) );
  143. }
  144.  
  145. void AbstractArray::squeezeEntry( int squeezePoint )
  146. {
  147.     PRECONDITION( squeezePoint >= 0 &&
  148.                   squeezePoint <= zeroBase(lastElementIndex)
  149.                 );
  150.  
  151.     memmove( theArray + squeezePoint,
  152.              theArray + squeezePoint + 1,
  153.              (zeroBase(lastElementIndex)-squeezePoint)*sizeof( theArray[0] )
  154.            );
  155.         theArray[zeroBase(lastElementIndex)] = ZERO;
  156. }
  157.  
  158. int AbstractArray::find( const Object& o )
  159. {
  160.     if( o == NOOBJECT )
  161.         return INT_MIN;
  162.  
  163.     for( int index = 0; index < arraySize(); index++ )
  164.         if( *(theArray[index]) == o )
  165.             return boundBase(index);
  166.     return INT_MIN;
  167. }
  168.  
  169. inline int isZero( const Object *o )
  170. {
  171.     return o == &NOOBJECT;
  172. }
  173.  
  174. int AbstractArray::isEqual( const Object& testObject ) const
  175. {
  176.     PRECONDITION( isA() == testObject.isA() );
  177.     AbstractArray& test = (AbstractArray&)testObject;
  178.     if( lowerbound != test.lowerbound || upperbound != test.upperbound )
  179.         return 0;
  180.  
  181.     for( int i = 0; i < arraySize(); i++ )
  182.         {
  183.         if( isZero(theArray[i]) != isZero(test.theArray[i]) )
  184.             return 0;
  185.         if( *(theArray[i]) != *(test.theArray[i]) )
  186.             return 0;
  187.         }
  188.     return 1;
  189. }
  190.  
  191. ContainerIterator& AbstractArray::initIterator() const
  192. {
  193.     return *( (ContainerIterator *)new ArrayIterator( *this ) );
  194. }
  195.  
  196. void AbstractArray::printContentsOn( ostream& outputStream ) const
  197. {
  198.     ContainerIterator& printIterator = initIterator();
  199.     printHeader( outputStream );
  200.     while( printIterator != 0 )
  201.         {
  202.         Object& arrayObject = printIterator++;
  203.         if( arrayObject != NOOBJECT )
  204.             {
  205.             arrayObject.printOn( outputStream );
  206.             if( printIterator != 0 )
  207.                 printSeparator( outputStream );
  208.             else
  209.                 break;
  210.             }
  211.         }
  212.     printTrailer( outputStream );
  213.     delete &printIterator;
  214. }
  215.  
  216. ArrayIterator::ArrayIterator( const AbstractArray& toIterate ) :
  217.     beingIterated( toIterate ),
  218.     currentIndex( toIterate.lowerbound )
  219. {
  220.     restart();
  221. }
  222.  
  223. ArrayIterator::~ArrayIterator()
  224. {
  225. }
  226.  
  227. ArrayIterator::operator int()
  228. {
  229.     return currentIndex <= beingIterated.upperbound;
  230. }
  231.  
  232. Object& ArrayIterator::current()
  233. {
  234.     if ( currentIndex <= beingIterated.upperbound )
  235.         return beingIterated.objectAt( currentIndex );
  236.     else
  237.         return NOOBJECT;
  238. }
  239.  
  240. void ArrayIterator::scan()
  241. {
  242.     if( currentIndex > beingIterated.upperbound )
  243.         return;
  244.  
  245.     while( ++currentIndex <= beingIterated.upperbound &&
  246.            beingIterated.objectAt( currentIndex ) == NOOBJECT )
  247.         ;   // empty body
  248. }
  249.  
  250. void ArrayIterator::restart()
  251. {
  252.     currentIndex = beingIterated.lowerbound;
  253.     if( beingIterated.objectAt( currentIndex ) == NOOBJECT )
  254.         scan();
  255. }
  256.  
  257. Object& ArrayIterator::operator ++ ( int )
  258. {
  259.     Object& res = (currentIndex <= beingIterated.upperbound) ?
  260.         beingIterated.objectAt( currentIndex ) : NOOBJECT;
  261.  
  262.     scan();
  263.  
  264.     return res;
  265. }
  266.  
  267. Object& ArrayIterator::operator ++ ()
  268. {
  269.     scan();
  270.     return (currentIndex <= beingIterated.upperbound) ?
  271.         beingIterated.objectAt( currentIndex ) : NOOBJECT;
  272. }
  273.