home *** CD-ROM | disk | FTP | other *** search
/ Piper's Pit BBS/FTP: ibm 0040 - 0049 / ibm0040-0049 / ibm0040.tar / ibm0040 / BCPPOWL1.ZIP / CLSRC.ZIP / ABSTARRY.CPP next >
Encoding:
C/C++ Source or Header  |  1991-08-28  |  13.5 KB  |  529 lines

  1. // Borland C++ - (C) Copyright 1991 by Borland International
  2.  
  3. // Contents ----------------------------------------------------------------
  4. //
  5. //      AbstractArray::AbstractArray                        constructor
  6. //      AbstractArray::~AbstractArray                       destructor
  7. //      AbstractArray::detach                               Object
  8. //      AbstractArray::detach                               int
  9. //      AbstractArray::hashValue
  10. //      AbstractArray::reallocate
  11. //      AbstractArray::isEqual
  12. //      AbstractArray::initIterator
  13. //      AbstractArray::printContentsOn
  14. //
  15. //      ArrayIterator::operator int
  16. //      ArrayIterator::operator Object
  17. //      ArrayIterator::restart
  18. //      ArrayIterator::operator ++
  19. //
  20. // Description
  21. //
  22. //      Implementation of class AbstractArray and class ArrayIterator member
  23. //      functions.
  24. //
  25. // End ---------------------------------------------------------------------
  26.  
  27. // Interface Dependencies ---------------------------------------------------
  28.  
  29. #ifndef __STDLIB_H
  30. #include <stdlib.h>
  31. #define __STDLIB_H
  32. #endif
  33.  
  34. #ifndef __CLSDEFS_H
  35. #include <clsdefs.h>
  36. #endif
  37.  
  38. #ifndef __CLSTYPES_H
  39. #include <clstypes.h>
  40. #endif
  41.  
  42. #ifndef __OBJECT_H
  43. #include <object.h>
  44. #endif
  45.  
  46. #ifndef __CONTAIN_H
  47. #include <contain.h>
  48. #endif
  49.  
  50. #ifndef __ABSTARRY_H
  51. #include <abstarry.h>
  52. #endif
  53.  
  54. // End Interface Dependencies ------------------------------------------------
  55.  
  56. // Implementation Dependencies ----------------------------------------------
  57.  
  58. #if !defined( __ERREXIT_H )
  59. #include <errexit.h>
  60. #endif
  61.  
  62. // End Implementation Dependencies -------------------------------------------
  63.  
  64.  
  65. // Constructor //
  66.  
  67. AbstractArray::AbstractArray( int anUpper, int aLower, sizeType aDelta )
  68.  
  69. // Summary -----------------------------------------------------------------
  70. //
  71. //      Constructor for an abstract array.  An abstract array can be made
  72. //         to be either of a fixed or expanding size.  In an expanding array,
  73. //         when a reference is made to an index greater than the current upper
  74. //         bound of the array, the array will grow to allow the given index
  75. //      to reference a valid array object.  The number of elements by
  76. //      which this growth is performed is given by the parameter aDelta.
  77. //
  78. // Parameters
  79. //
  80. //      anUpper
  81. //
  82. //      The upper bound for the array.
  83. //
  84. //      aLower
  85. //
  86. //      The lower bound for the array.  The initial size of the array is
  87. //      calculated from the upper and lower bounds.
  88. //
  89. //      aDelta
  90. //
  91. //      The growth factor for the array.
  92. //
  93. // Functional Description
  94. //
  95. //      We set up the private parts of the array, allocate space for the
  96. //      pointers, then set all the allocated pointers to point to the 
  97. //      error object.
  98. //
  99. // End ---------------------------------------------------------------------
  100. {
  101.     lowerbound = whereToAdd = aLower;
  102.     upperbound = anUpper;
  103.     delta = aDelta;
  104.     theArray = new Object *[ arraySize() ];
  105.     for( int i = 0; i < arraySize(); i++ )
  106.     {
  107.         theArray[ i ] = ZERO;
  108.     } // end for
  109. }
  110. // End Constructor AbstractArray::AbstractArray //
  111.  
  112.  
  113. // Destructor //
  114.  
  115. AbstractArray::~AbstractArray()
  116.  
  117. // Summary -----------------------------------------------------------------
  118. //
  119. //      Destructor for a AbstractArray object.
  120. //
  121. // End ---------------------------------------------------------------------
  122. {
  123.     for( int i = 0; i < arraySize(); i++ )
  124.         if( theArray[ i ] != ZERO )
  125.             delete theArray[ i ];
  126.     delete [ arraySize() ] theArray;
  127. //    delete theArray;        // for C++ 2.1
  128. }
  129. // End Destructor //
  130.  
  131.  
  132. // Member Function //
  133.  
  134. void    AbstractArray::detach( const Object& toDetach, int deleteObjectToo )
  135.  
  136. // Summary -----------------------------------------------------------------
  137. //
  138. //      Detaches an object from the array.
  139. //
  140. // Parameter
  141. //
  142. //      toDetach
  143. //
  144. //      The object we are to search for and detach from the AbstractArray.
  145. //
  146. //      deleteObjectToo
  147. //
  148. //      Specifies whether we are to delete the object.
  149. //
  150. // Functional Description                     
  151. //
  152. //      If the object specified is at the lower bound of the array, we remove
  153. //      the reference right away.  Otherwise, we iterate through the array until
  154. //      we find it, then remove the reference.
  155. //
  156. // Remarks
  157. //
  158. //  warnings:
  159. //      No error condition is generated if the object which was specified
  160. //      isn't in the array.
  161. //
  162. // End ---------------------------------------------------------------------
  163. {
  164.     if ( toDetach == NOOBJECT )
  165.         return;
  166.  
  167.     for ( int i = 0; i < arraySize(); i++ )
  168.     {
  169.         if ( ( theArray[ i ] != ZERO ) && ( *theArray[ i ] == toDetach ) )
  170.         {
  171.             if ( deleteObjectToo )
  172.             {
  173.                 delete theArray[ i ];
  174.             }
  175.             theArray[ i ] = ZERO;
  176.             itemsInContainer--;
  177.             break;
  178.         }
  179.     } // end for //
  180. }
  181. // End Member Function AbstractArray::detach //
  182.  
  183.  
  184. // Member Function //
  185.  
  186. void    AbstractArray::detach( int atIndex, int deleteObjectToo )
  187.  
  188. // Summary -----------------------------------------------------------------
  189. //
  190. //      Detaches an object from the array at the given index.
  191. //
  192. // Parameter
  193. //
  194. //      toIndex
  195. //
  196. //      The index from which we are to detach the object.
  197. //
  198. //      deleteObjectToo
  199. //
  200. //      Specifies whether we are to delete the object.
  201. //
  202. // Remarks
  203. //
  204. //  warnings:
  205. //      No error condition is generated if the object which was specified
  206. //      isn't in the array.
  207. //
  208. // End ---------------------------------------------------------------------
  209. {
  210.     if ( theArray[ atIndex - lowerbound ] != ZERO )
  211.     {
  212.         if ( deleteObjectToo )
  213.         {
  214.             delete ( theArray[ atIndex - lowerbound ] );
  215.         }
  216.         theArray[ atIndex - lowerbound ] = ZERO;
  217.         itemsInContainer--;
  218.     } // end if there was an element already there in the array.
  219. }
  220. // End Member Function AbstractArray::detach //
  221.  
  222.  
  223. // Member Function //
  224.  
  225. hashValueType AbstractArray::hashValue() const
  226.  
  227. // Summary -----------------------------------------------------------------
  228. //
  229. //      Returns the hash value of a array.
  230. //
  231. // End ---------------------------------------------------------------------
  232. {
  233.     return hashValueType(0);
  234. }
  235. // End Member Function AbstractArray::hashValue //
  236.  
  237.  
  238. // Member Function //
  239.  
  240. void AbstractArray::reallocate( sizeType newSize )
  241.  
  242. // Summary -----------------------------------------------------------------
  243. //
  244. //         Reallocates the array's pointer vector to a new size.
  245. //
  246. // Parameters
  247. //
  248. //         newSize
  249. //
  250. //         The number of pointers which is to be in the new vector.
  251. //
  252. // Functional Description
  253. //
  254. //         We allocate space for a new pointer vector of the given size,
  255. //         adjusted to take into account the growth factor.  We then copy
  256. //         the old vector into the new one and fix up the pointer in the
  257. //         array object.
  258. //
  259. // Remarks
  260. //
  261. //  assumptions
  262. //         The new size of the pointer vector is greater than the
  263. //      current size.  We do "expanding-only" arrays, not accordions.
  264. //
  265. // End ---------------------------------------------------------------------
  266. {
  267.     if ( delta == 0 )
  268.         ClasslibErrorExit("Error:  Attempting to expand a fixed size array.",
  269.                           __EEXPAND);
  270.  
  271.     int i;        // Loop counter for moving the pointers from the old vector
  272.                 // to the new one.
  273.  
  274. // Body Comment
  275. //
  276. //         We assume that the new pointer vector size is greater than the
  277. //         current vector size.
  278. //
  279. // End
  280.  
  281.     if (newSize <= arraySize())
  282.         ClasslibErrorExit("Error: Invalid array size in reallocation.",
  283.             __EEXPAND);
  284.  
  285.     sizeType adjustedSize = newSize + ( delta - ( newSize % delta ) );
  286.  
  287.     Object **newArray = new Object *[ adjustedSize ];
  288.     if ( newArray == 0 )
  289.         ClasslibErrorExit("Error:  Out of Memory", __ENOMEM);
  290.  
  291.     for ( i = 0; i < arraySize(); i++ )
  292.     {
  293.         newArray[i] = theArray[i];
  294.     }
  295.     for (; i < adjustedSize; i++ )
  296.     {
  297.         newArray[i] = ZERO;
  298.     }
  299.  
  300.     delete [ arraySize() ] theArray;
  301.     theArray = newArray;
  302.     upperbound = adjustedSize + lowerbound - 1;
  303.  
  304. }
  305. // End Member Function AbstractArray::reallocate //
  306.  
  307.  
  308. // Member Function //
  309.  
  310. int AbstractArray::isEqual( const Object& testObject ) const
  311.  
  312. // Summary -----------------------------------------------------------------
  313. //
  314. //         Tests for equality of two arrays.  Two arrays are equal if they
  315. //         have the same dimensions and the same objects at the same indices.
  316. //
  317. // Parameters
  318. //
  319. //         testObject
  320. //
  321. //         The array which we will be testing against this.
  322. //
  323. // End ---------------------------------------------------------------------
  324. {
  325.  
  326.     if ( lowerbound != ((AbstractArray&)testObject).lowerbound ||
  327.          upperbound != ((AbstractArray&)testObject).upperbound )
  328.     {
  329.         return 0;
  330.     }
  331.  
  332.     for ( int i = 0; i < arraySize(); i++ )
  333.     {
  334.  
  335. // Body Comment
  336. //
  337. //         The two array elements can be null, so check that first.
  338. //         If there are really objects there, compare them for equality.
  339. //
  340. // End
  341.  
  342.         if ( theArray[i] != ZERO )
  343.         {
  344.             if ( ((AbstractArray&)testObject).theArray[i] != ZERO )
  345.             {
  346.                 if ( *theArray[i] !=
  347.                      *( ((AbstractArray &)testObject).theArray[i] ) )
  348.                 {
  349.                     return 0; // objects weren't equal.
  350.                 }
  351.             }
  352.             else // the first pointer wasn't ZERO but the second was
  353.             {
  354.                 return 0;
  355.             }
  356.         }
  357.         else
  358.             if ( ((AbstractArray&)testObject).theArray[i] != ZERO )
  359.             {
  360.                 return 0;  // first pointer was ZERO but the second wasn't
  361.             }
  362.     }  // end for each element in the array.
  363.     return 1;
  364. }
  365. // End Member Function AbstractArray::isEqual //
  366.  
  367.  
  368. // Member Function //
  369.  
  370. ContainerIterator& AbstractArray::initIterator() const
  371.  
  372. // Summary -----------------------------------------------------------------
  373. //
  374. //      Initializes an iterator for a list.
  375. //
  376. // End ---------------------------------------------------------------------
  377. {
  378.     return *( (ContainerIterator *)new ArrayIterator( *this ) );
  379. }
  380. // End Member Function AbstractArray::initIterator //
  381.  
  382.  
  383. // Member Function //
  384.  
  385. void AbstractArray::printContentsOn( ostream& outputStream ) const
  386.  
  387. // Summary -----------------------------------------------------------------
  388. //
  389. //      Displays the non-ZERO contents of an array on the given stream.
  390. //
  391. // Parameters
  392. //
  393. //      outputStream
  394. //
  395. //      The stream on which we will be writing the contents.
  396. //
  397. // Functional Description
  398. //
  399. //      We initialize an iterator, then iterator through each object,
  400. //      asking the objects to print themselves if they are not the
  401. //         error object.
  402. //
  403. // Remarks
  404. //
  405. //  warnings:
  406. //      We must be sure to delete the container iterator, since it was
  407. //      allocated on the heap.
  408. //
  409. // End ---------------------------------------------------------------------
  410. {
  411.     ContainerIterator& printIterator = initIterator();
  412.  
  413.     printHeader( outputStream );
  414.  
  415.     while( int(printIterator) != 0 )
  416.     {
  417.         Object& arrayObject = printIterator++;
  418.         if ( arrayObject != NOOBJECT )
  419.         {
  420.             arrayObject.printOn( outputStream );
  421.  
  422.             if ( int(printIterator) != 0 )
  423.             {
  424.             printSeparator( outputStream );
  425.             }
  426.             else // there are no more objects in the array.
  427.             {
  428.                 break;
  429.             }
  430.         } // end if the array object is NOOBJECT.
  431.     } // end while //
  432.  
  433.     printTrailer( outputStream );
  434.     delete &printIterator;
  435. }
  436. // End Member Function AbstractArray::printContentsOn //
  437.  
  438.  
  439. // Destructor //
  440.  
  441. ArrayIterator::~ArrayIterator()
  442.  
  443. // Summary -----------------------------------------------------------------
  444. //
  445. //      Destructor for a ArrayIterator object.
  446. //
  447. // End ---------------------------------------------------------------------
  448. {
  449. }
  450. // End Destructor //
  451.  
  452.  
  453. // Member Function //
  454.  
  455. ArrayIterator::operator int()
  456.  
  457. // Summary -----------------------------------------------------------------
  458. //
  459. //      Integer conversion for an array iterator.
  460. //
  461. // End ---------------------------------------------------------------------
  462. {
  463.     return currentIndex <= beingIterated.upperbound;
  464. }
  465. // End Member Function operator int //
  466.  
  467.  
  468. // Member Function //
  469.  
  470. ArrayIterator::operator Object&()
  471.  
  472. // Summary -----------------------------------------------------------------
  473. //
  474. //      Object reference conversion for an array iterator.
  475. //
  476. // End ---------------------------------------------------------------------
  477. {
  478.     if ( currentIndex <= beingIterated.upperbound )
  479.     {
  480.         return ( (Object&)( beingIterated.objectAt( currentIndex ) ) );
  481.     }
  482.     else // no more elements in the array.
  483.     {
  484.         return NOOBJECT;
  485.     }
  486. }
  487. // End Member Function operator Object& //
  488.  
  489.  
  490. // Member Function //
  491.  
  492. void ArrayIterator::restart()
  493.  
  494. // Summary -----------------------------------------------------------------
  495. //
  496. //      ArrayIterator restart.
  497. //
  498. // End ---------------------------------------------------------------------
  499. {
  500.     currentIndex = beingIterated.lowerbound;
  501. }
  502. // End Member Function ArrayIterator::restart //
  503.  
  504.  
  505. // Member Function //
  506.  
  507. Object& ArrayIterator::operator ++()
  508.  
  509. // Summary -----------------------------------------------------------------
  510. //
  511. //         Increments the array iterator and returns the next object.
  512. //
  513. // End ---------------------------------------------------------------------
  514. {
  515.     if ( currentIndex <= beingIterated.upperbound )
  516.     {
  517.         currentIndex++;
  518.         return ( (Object&)( beingIterated.objectAt( currentIndex - 1 ) ) );
  519.  
  520.     }
  521.     else // no more elements in the array.
  522.     {
  523.         return NOOBJECT;
  524.     }
  525.  
  526. }
  527. // End Member Function ArrayIterator::operator ++//
  528.  
  529.