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