Vector.H 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999
  1. /*
  2. ** Command & Conquer Generals(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /***********************************************************************************************
  19. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : Command & Conquer *
  23. * *
  24. * $Archive:: /Commando/Code/Library/Vector.H $*
  25. * *
  26. * $Author:: Byon_g $*
  27. * *
  28. * $Modtime:: 3/12/98 2:09p $*
  29. * *
  30. * $Revision:: 2 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * VectorClass<T>::VectorClass -- Constructor for vector class. *
  35. * VectorClass<T>::~VectorClass -- Default destructor for vector class. *
  36. * VectorClass<T>::VectorClass -- Copy constructor for vector object. *
  37. * VectorClass<T>::operator = -- The assignment operator. *
  38. * VectorClass<T>::operator == -- Equality operator for vector objects. *
  39. * VectorClass<T>::Clear -- Frees and clears the vector. *
  40. * VectorClass<T>::Resize -- Changes the size of the vector. *
  41. * DynamicVectorClass<T>::DynamicVectorClass -- Constructor for dynamic vector. *
  42. * DynamicVectorClass<T>::Resize -- Changes the size of a dynamic vector. *
  43. * DynamicVectorClass<T>::Add -- Add an element to the vector. *
  44. * DynamicVectorClass<T>::Delete -- Remove the specified object from the vector. *
  45. * DynamicVectorClass<T>::Delete -- Deletes the specified index from the vector. *
  46. * VectorClass<T>::ID -- Pointer based conversion to index number. *
  47. * VectorClass<T>::ID -- Finds object ID based on value. *
  48. * DynamicVectorClass<T>::ID -- Find matching value in the dynamic vector. *
  49. * DynamicVectorClass<T>::Uninitialized_Add -- Add an empty place to the vector. *
  50. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  51. #ifndef VECTOR_H
  52. #define VECTOR_H
  53. #include "noinit.h"
  54. #include <assert.h>
  55. #include <new.h>
  56. #include <string.h>
  57. #include <stddef.h>
  58. #include <stdlib.h>
  59. /**************************************************************************
  60. ** This is a general purpose vector class. A vector is defined by this
  61. ** class, as an array of arbitrary objects where the array can be dynamically
  62. ** sized. Because is deals with arbitrary object types, it can handle everything.
  63. ** As a result of this, it is not terribly efficient for integral objects (such
  64. ** as char or int). It will function correctly, but the copy constructor and
  65. ** equality operator could be highly optimized if the integral type were known.
  66. ** This efficiency can be implemented by deriving an integral vector template
  67. ** from this one in order to supply more efficient routines.
  68. */
  69. // Why, oh why does Visual C need this!!! It's bugged. <sigh>
  70. #pragma warning(disable : 4505)
  71. template<class T>
  72. class VectorClass
  73. {
  74. public:
  75. VectorClass(NoInitClass const &) {};
  76. VectorClass(int size=0, T const * array=0);
  77. VectorClass(VectorClass<T> const &); // Copy constructor.
  78. virtual ~VectorClass(void);
  79. T & operator[](int index) {assert(unsigned(index) < unsigned(VectorMax));return(Vector[index]);};
  80. T const & operator[](int index) const {assert(unsigned(index) < unsigned(VectorMax));return(Vector[index]);};
  81. VectorClass<T> & operator = (VectorClass<T> const &); // Assignment operator.
  82. virtual bool operator == (VectorClass<T> const &) const; // Equality operator.
  83. virtual bool Resize(int newsize, T const * array=0);
  84. virtual void Clear(void);
  85. int Length(void) const {return VectorMax;};
  86. virtual int ID(T const * ptr); // Pointer based identification.
  87. virtual int ID(T const & ptr); // Value based identification.
  88. protected:
  89. /*
  90. ** This is a pointer to the allocated vector array of elements.
  91. */
  92. T * Vector;
  93. /*
  94. ** This is the maximum number of elements allowed in this vector.
  95. */
  96. int VectorMax;
  97. /*
  98. ** This indicates if the vector is in a valid (even if empty) state.
  99. */
  100. bool IsValid;
  101. /*
  102. ** Does the vector data pointer refer to memory that this class has manually
  103. ** allocated? If so, then this class is responsible for deleting it.
  104. */
  105. bool IsAllocated;
  106. };
  107. /***********************************************************************************************
  108. * VectorClass<T>::VectorClass -- Constructor for vector class. *
  109. * *
  110. * This constructor for the vector class is passed the initial size of the vector and an *
  111. * optional pointer to a preallocated block of memory that the vector will be placed in. *
  112. * If this optional pointer is NULL (or not provided), then the vector is allocated out *
  113. * of free store (with the "new" operator). *
  114. * *
  115. * INPUT: size -- The number of elements to initialize this vector to. *
  116. * *
  117. * array -- Optional pointer to a previously allocated memory block to hold the *
  118. * vector. *
  119. * *
  120. * OUTPUT: none *
  121. * *
  122. * WARNINGS: none *
  123. * *
  124. * HISTORY: *
  125. * 03/10/1995 JLB : Created. *
  126. *=============================================================================================*/
  127. template<class T>
  128. VectorClass<T>::VectorClass(int size, T const * array) :
  129. Vector(0),
  130. VectorMax(size),
  131. IsValid(true),
  132. IsAllocated(false)
  133. {
  134. /*
  135. ** Allocate the vector. The default constructor will be called for every
  136. ** object in this vector.
  137. */
  138. if (size) {
  139. if (array) {
  140. Vector = new((void*)array) T[size];
  141. } else {
  142. Vector = new T[size];
  143. IsAllocated = true;
  144. }
  145. }
  146. }
  147. /***********************************************************************************************
  148. * VectorClass<T>::~VectorClass -- Default destructor for vector class. *
  149. * *
  150. * This is the default destructor for the vector class. It will deallocate any memory *
  151. * that it may have allocated. *
  152. * *
  153. * INPUT: none *
  154. * *
  155. * OUTPUT: none *
  156. * *
  157. * WARNINGS: none *
  158. * *
  159. * HISTORY: *
  160. * 03/10/1995 JLB : Created. *
  161. *=============================================================================================*/
  162. template<class T>
  163. VectorClass<T>::~VectorClass(void)
  164. {
  165. VectorClass<T>::Clear();
  166. }
  167. /***********************************************************************************************
  168. * VectorClass<T>::VectorClass -- Copy constructor for vector object. *
  169. * *
  170. * This is the copy constructor for the vector class. It will duplicate the provided *
  171. * vector into the new vector being created. *
  172. * *
  173. * INPUT: vector -- Reference to the vector to use as a copy. *
  174. * *
  175. * OUTPUT: none *
  176. * *
  177. * WARNINGS: none *
  178. * *
  179. * HISTORY: *
  180. * 03/10/1995 JLB : Created. *
  181. *=============================================================================================*/
  182. template<class T>
  183. VectorClass<T>::VectorClass(VectorClass<T> const & vector) :
  184. Vector(0),
  185. VectorMax(0),
  186. IsValid(true),
  187. IsAllocated(false)
  188. {
  189. *this = vector;
  190. }
  191. /***********************************************************************************************
  192. * VectorClass<T>::operator = -- The assignment operator. *
  193. * *
  194. * This the the assignment operator for vector objects. It will alter the existing lvalue *
  195. * vector to duplicate the rvalue one. *
  196. * *
  197. * INPUT: vector -- The rvalue vector to copy into the lvalue one. *
  198. * *
  199. * OUTPUT: Returns with reference to the newly copied vector. *
  200. * *
  201. * WARNINGS: none *
  202. * *
  203. * HISTORY: *
  204. * 03/10/1995 JLB : Created. *
  205. *=============================================================================================*/
  206. template<class T>
  207. VectorClass<T> & VectorClass<T>::operator =(VectorClass<T> const & vector)
  208. {
  209. if (this != &vector) {
  210. Clear();
  211. VectorMax = vector.Length();
  212. if (VectorMax) {
  213. Vector = new T[VectorMax];
  214. if (Vector) {
  215. IsAllocated = true;
  216. for (int index = 0; index < VectorMax; index++) {
  217. Vector[index] = vector[index];
  218. }
  219. }
  220. } else {
  221. Vector = 0;
  222. IsAllocated = false;
  223. }
  224. }
  225. return(*this);
  226. }
  227. /***********************************************************************************************
  228. * VectorClass<T>::operator == -- Equality operator for vector objects. *
  229. * *
  230. * This operator compares two vectors for equality. It does this by performing an object *
  231. * by object comparison between the two vectors. *
  232. * *
  233. * INPUT: vector -- The right vector expression. *
  234. * *
  235. * OUTPUT: bool; Are the two vectors essentially equal? (do they contain comparable elements *
  236. * in the same order?) *
  237. * *
  238. * WARNINGS: The equality operator must exist for the objects that this vector contains. *
  239. * *
  240. * HISTORY: *
  241. * 03/10/1995 JLB : Created. *
  242. *=============================================================================================*/
  243. template<class T>
  244. bool VectorClass<T>::operator == (VectorClass<T> const & vector) const
  245. {
  246. if (VectorMax == vector.Length()) {
  247. for (int index = 0; index < VectorMax; index++) {
  248. if (Vector[index] != vector[index]) {
  249. return(false);
  250. }
  251. }
  252. return(true);
  253. }
  254. return(false);
  255. }
  256. /***********************************************************************************************
  257. * VectorClass<T>::ID -- Pointer based conversion to index number. *
  258. * *
  259. * Use this routine to convert a pointer to an element in the vector back into the index *
  260. * number of that object. This routine ONLY works with actual pointers to object within *
  261. * the vector. For "equivalent" object index number (such as with similar integral values) *
  262. * then use the "by value" index number ID function. *
  263. * *
  264. * INPUT: pointer -- Pointer to an actual object in the vector. *
  265. * *
  266. * OUTPUT: Returns with the index number for the object pointed to by the parameter. *
  267. * *
  268. * WARNINGS: This routine is only valid for actual pointers to object that exist within *
  269. * the vector. All other object pointers will yield undefined results. *
  270. * *
  271. * HISTORY: *
  272. * 03/13/1995 JLB : Created. *
  273. *=============================================================================================*/
  274. template<class T>
  275. inline int VectorClass<T>::ID(T const * ptr)
  276. {
  277. if (!IsValid) return(0);
  278. return(((unsigned long)ptr - (unsigned long)&(*this)[0]) / sizeof(T));
  279. }
  280. /***********************************************************************************************
  281. * VectorClass<T>::ID -- Finds object ID based on value. *
  282. * *
  283. * Use this routine to find the index value of an object with equivalent value in the *
  284. * vector. Typical use of this would be for integral types. *
  285. * *
  286. * INPUT: object -- Reference to the object that is to be looked up in the vector. *
  287. * *
  288. * OUTPUT: Returns with the index number of the object that is equivalent to the one *
  289. * specified. If no matching value could be found then -1 is returned. *
  290. * *
  291. * WARNINGS: none *
  292. * *
  293. * HISTORY: *
  294. * 03/13/1995 JLB : Created. *
  295. *=============================================================================================*/
  296. template<class T>
  297. int VectorClass<T>::ID(T const & object)
  298. {
  299. if (!IsValid) return(0);
  300. for (int index = 0; index < VectorMax; index++) {
  301. if ((*this)[index] == object) {
  302. return(index);
  303. }
  304. }
  305. return(-1);
  306. }
  307. /***********************************************************************************************
  308. * VectorClass<T>::Clear -- Frees and clears the vector. *
  309. * *
  310. * Use this routine to reset the vector to an empty (non-allocated) state. A vector will *
  311. * free all allocated memory when this routine is called. In order for the vector to be *
  312. * useful after this point, the Resize function must be called to give it element space. *
  313. * *
  314. * INPUT: none *
  315. * *
  316. * OUTPUT: none *
  317. * *
  318. * WARNINGS: none *
  319. * *
  320. * HISTORY: *
  321. * 03/10/1995 JLB : Created. *
  322. *=============================================================================================*/
  323. template<class T>
  324. void VectorClass<T>::Clear(void)
  325. {
  326. if (Vector && IsAllocated) {
  327. delete[] Vector;
  328. Vector = 0;
  329. }
  330. IsAllocated = false;
  331. VectorMax = 0;
  332. }
  333. /***********************************************************************************************
  334. * VectorClass<T>::Resize -- Changes the size of the vector. *
  335. * *
  336. * This routine is used to change the size (usually to increase) the size of a vector. This *
  337. * is the only way to increase the vector's working room (number of elements). *
  338. * *
  339. * INPUT: newsize -- The desired size of the vector. *
  340. * *
  341. * array -- Optional pointer to a previously allocated memory block that the *
  342. * array will be located in. If this parameter is not supplied, then *
  343. * the array will be allocated from free store. *
  344. * *
  345. * OUTPUT: bool; Was the array resized successfully? *
  346. * *
  347. * WARNINGS: Failure to succeed could be the result of running out of memory. *
  348. * *
  349. * HISTORY: *
  350. * 03/10/1995 JLB : Created. *
  351. *=============================================================================================*/
  352. template<class T>
  353. bool VectorClass<T>::Resize(int newsize, T const * array)
  354. {
  355. if (newsize) {
  356. /*
  357. ** Allocate a new vector of the size specified. The default constructor
  358. ** will be called for every object in this vector.
  359. */
  360. T * newptr;
  361. /*
  362. ** Either create a new memory block for the object array or initialize
  363. ** an existing block as indicated by the array parameter. When creating a new
  364. ** memory block, flag that the vector object is currently in an invalid
  365. ** state. This is necessary because the default constructor for the object
  366. ** elements may look to the vector to fetch their ID number.
  367. */
  368. IsValid = false;
  369. if (!array) {
  370. newptr = new T[newsize];
  371. } else {
  372. newptr = new((void*)array) T[newsize];
  373. }
  374. IsValid = true;
  375. if (!newptr) {
  376. return(false);
  377. }
  378. /*
  379. ** If there is an old vector, then it must be copied (as much as is feasible)
  380. ** to the new vector.
  381. */
  382. if (Vector != NULL) {
  383. /*
  384. ** Copy as much of the old vector into the new vector as possible. This
  385. ** presumes that there is a functional assignment operator for each
  386. ** of the objects in the vector.
  387. */
  388. int copycount = (newsize < VectorMax) ? newsize : VectorMax;
  389. for (int index = 0; index < copycount; index++) {
  390. newptr[index] = Vector[index];
  391. }
  392. /*
  393. ** Delete the old vector. This might cause the destructors to be called
  394. ** for all of the old elements. This makes the implementation of suitable
  395. ** assignment operator very important. The default assignment operator will
  396. ** only work for the simplest of objects.
  397. */
  398. if (IsAllocated) {
  399. delete[] Vector;
  400. Vector = 0;
  401. }
  402. }
  403. /*
  404. ** Assign the new vector data to this class.
  405. */
  406. Vector = newptr;
  407. VectorMax = newsize;
  408. IsAllocated = (Vector && !array);
  409. } else {
  410. /*
  411. ** Resizing to zero is the same as clearing the vector.
  412. */
  413. Clear();
  414. }
  415. return(true);
  416. }
  417. /**************************************************************************
  418. ** This derivative vector class adds the concept of adding and deleting
  419. ** objects. The objects are packed to the beginning of the vector array.
  420. ** If this is instantiated for a class object, then the assignment operator
  421. ** and the equality operator must be supported. If the vector allocates its
  422. ** own memory, then the vector can grow if it runs out of room adding items.
  423. ** The growth rate is controlled by setting the growth step rate. A growth
  424. ** step rate of zero disallows growing.
  425. */
  426. template<class T>
  427. class DynamicVectorClass : public VectorClass<T>
  428. {
  429. public:
  430. DynamicVectorClass(unsigned size=0, T const * array=0);
  431. // Change maximum size of vector.
  432. virtual bool Resize(int newsize, T const * array=0);
  433. // Resets and frees the vector array.
  434. virtual void Clear(void) {ActiveCount = 0;VectorClass<T>::Clear();};
  435. // Fetch number of "allocated" vector objects.
  436. int Count(void) const {return(ActiveCount);};
  437. // Add object to vector (growing as necessary).
  438. bool Add(T const & object);
  439. bool Add_Head(T const & object);
  440. // Delete object just like this from vector.
  441. bool Delete(T const & object);
  442. // Delete object at this vector index.
  443. bool Delete(int index);
  444. // Deletes all objects in the vector.
  445. void Delete_All(void) {ActiveCount = 0;};
  446. // Set amount that vector grows by.
  447. int Set_Growth_Step(int step) {return(GrowthStep = step);};
  448. // Fetch current growth step rate.
  449. int Growth_Step(void) {return GrowthStep;};
  450. virtual int ID(T const * ptr) {return(VectorClass<T>::ID(ptr));};
  451. virtual int ID(T const & ptr);
  452. DynamicVectorClass<T> & operator =(DynamicVectorClass<T> const & rvalue) {
  453. VectorClass<T>::operator = (rvalue);
  454. ActiveCount = rvalue.ActiveCount;
  455. GrowthStep = rvalue.GrowthStep;
  456. return(*this);
  457. }
  458. // Uninitialized Add - does everything an Add does, except copying an
  459. // object into the 'new' spot in the array. It returns a pointer to
  460. // the 'new' spot. (NULL if the Add failed). NOTE - you must then fill
  461. // this memory area with a valid object (e.g. by using placement new),
  462. // or chaos will result!
  463. T * Uninitialized_Add(void);
  464. protected:
  465. /*
  466. ** This is a count of the number of active objects in this
  467. ** vector. The memory array often times is bigger than this
  468. ** value.
  469. */
  470. int ActiveCount;
  471. /*
  472. ** If there is insufficient room in the vector array for a new
  473. ** object to be added, then the vector will grow by the number
  474. ** of objects specified by this value. This is controlled by
  475. ** the Set_Growth_Step() function.
  476. */
  477. int GrowthStep;
  478. };
  479. /***********************************************************************************************
  480. * DynamicVectorClass<T>::DynamicVectorClass -- Constructor for dynamic vector. *
  481. * *
  482. * This is the normal constructor for the dynamic vector class. It is similar to the normal *
  483. * vector class constructor. The vector is initialized to contain the number of elements *
  484. * specified in the "size" parameter. The memory is allocated from free store unless the *
  485. * optional array parameter is provided. In this case it will place the vector at the *
  486. * memory location specified. *
  487. * *
  488. * INPUT: size -- The maximum number of objects allowed in this vector. *
  489. * *
  490. * array -- Optional pointer to the memory area to place the vector at. *
  491. * *
  492. * OUTPUT: none *
  493. * *
  494. * WARNINGS: none *
  495. * *
  496. * HISTORY: *
  497. * 03/10/1995 JLB : Created. *
  498. *=============================================================================================*/
  499. template<class T>
  500. DynamicVectorClass<T>::DynamicVectorClass(unsigned size, T const * array)
  501. : VectorClass<T>(size, array)
  502. {
  503. GrowthStep = 10;
  504. ActiveCount = 0;
  505. }
  506. /***********************************************************************************************
  507. * DynamicVectorClass<T>::Resize -- Changes the size of a dynamic vector. *
  508. * *
  509. * Use this routine to change the size of the vector. The size changed is the maximum *
  510. * number of allocated objects within this vector. If a memory buffer is provided, then *
  511. * the vector will be located there. Otherwise, the memory will be allocated out of free *
  512. * store. *
  513. * *
  514. * INPUT: newsize -- The desired maximum size of this vector. *
  515. * *
  516. * array -- Optional pointer to a previously allocated memory array. *
  517. * *
  518. * OUTPUT: bool; Was vector successfully resized according to specifications? *
  519. * *
  520. * WARNINGS: Failure to resize the vector could be the result of lack of free store. *
  521. * *
  522. * HISTORY: *
  523. * 03/10/1995 JLB : Created. *
  524. *=============================================================================================*/
  525. template<class T>
  526. bool DynamicVectorClass<T>::Resize(int newsize, T const * array)
  527. {
  528. if (VectorClass<T>::Resize(newsize, array)) {
  529. if (Length() < ActiveCount) ActiveCount = Length();
  530. return(true);
  531. }
  532. return(false);
  533. }
  534. /***********************************************************************************************
  535. * DynamicVectorClass<T>::ID -- Find matching value in the dynamic vector. *
  536. * *
  537. * Use this routine to find a matching object (by value) in the vector. Unlike the base *
  538. * class ID function of similar name, this one restricts the scan to the current number *
  539. * of valid objects. *
  540. * *
  541. * INPUT: object -- A reference to the object that a match is to be found in the *
  542. * vector. *
  543. * *
  544. * OUTPUT: Returns with the index number of the object that is equivalent to the one *
  545. * specified. If no equivalent object could be found then -1 is returned. *
  546. * *
  547. * WARNINGS: none *
  548. * *
  549. * HISTORY: *
  550. * 03/13/1995 JLB : Created. *
  551. *=============================================================================================*/
  552. template<class T>
  553. int DynamicVectorClass<T>::ID(T const & object)
  554. {
  555. for (int index = 0; index < Count(); index++) {
  556. if ((*this)[index] == object) return(index);
  557. }
  558. return(-1);
  559. }
  560. /***********************************************************************************************
  561. * DynamicVectorClass<T>::Add -- Add an element to the vector. *
  562. * *
  563. * Use this routine to add an element to the vector. The vector will automatically be *
  564. * resized to accomodate the new element IF the vector was allocated previously and the *
  565. * growth rate is not zero. *
  566. * *
  567. * INPUT: object -- Reference to the object that will be added to the vector. *
  568. * *
  569. * OUTPUT: bool; Was the object added successfully? If so, the object is added to the end *
  570. * of the vector. *
  571. * *
  572. * WARNINGS: none *
  573. * *
  574. * HISTORY: *
  575. * 03/10/1995 JLB : Created. *
  576. *=============================================================================================*/
  577. template<class T>
  578. bool DynamicVectorClass<T>::Add(T const & object)
  579. {
  580. if (ActiveCount >= Length()) {
  581. if ((IsAllocated || !VectorMax) && GrowthStep > 0) {
  582. if (!Resize(Length() + GrowthStep)) {
  583. /*
  584. ** Failure to increase the size of the vector is an error condition.
  585. ** Return with the error flag.
  586. */
  587. return(false);
  588. }
  589. } else {
  590. /*
  591. ** Increasing the size of this vector is not allowed! Bail this
  592. ** routine with the error code.
  593. */
  594. return(false);
  595. }
  596. }
  597. /*
  598. ** There is room for the new object now. Add it to the end of the object vector.
  599. */
  600. (*this)[ActiveCount++] = object;
  601. return(true);
  602. }
  603. /***********************************************************************************************
  604. * DynamicVectorClass<T>::Add_Head -- Adds element to head of the list. *
  605. * *
  606. * This routine will add the specified element to the head of the vector. If necessary, *
  607. * the vector will be expanded accordingly. *
  608. * *
  609. * INPUT: object -- Reference to the object to add to the head of this vector. *
  610. * *
  611. * OUTPUT: bool; Was the object added without error? *
  612. * *
  613. * WARNINGS: none *
  614. * *
  615. * HISTORY: *
  616. * 09/21/1995 JLB : Created. *
  617. *=============================================================================================*/
  618. template<class T>
  619. bool DynamicVectorClass<T>::Add_Head(T const & object)
  620. {
  621. if (ActiveCount >= Length()) {
  622. if ((IsAllocated || !VectorMax) && GrowthStep > 0) {
  623. if (!Resize(Length() + GrowthStep)) {
  624. /*
  625. ** Failure to increase the size of the vector is an error condition.
  626. ** Return with the error flag.
  627. */
  628. return(false);
  629. }
  630. } else {
  631. /*
  632. ** Increasing the size of this vector is not allowed! Bail this
  633. ** routine with the error code.
  634. */
  635. return(false);
  636. }
  637. }
  638. /*
  639. ** There is room for the new object now. Add it to the end of the object vector.
  640. */
  641. if (ActiveCount) {
  642. memmove(&(*this)[1], &(*this)[0], ActiveCount * sizeof(T));
  643. }
  644. (*this)[0] = object;
  645. ActiveCount++;
  646. // (*this)[ActiveCount++] = object;
  647. return(true);
  648. }
  649. /***********************************************************************************************
  650. * DynamicVectorClass<T>::Delete -- Remove the specified object from the vector. *
  651. * *
  652. * This routine will delete the object referenced from the vector. All objects in the *
  653. * vector that follow the one deleted will be moved "down" to fill the hole. *
  654. * *
  655. * INPUT: object -- Reference to the object in this vector that is to be deleted. *
  656. * *
  657. * OUTPUT: bool; Was the object deleted successfully? This should always be true. *
  658. * *
  659. * WARNINGS: Do no pass a reference to an object that is NOT part of this vector. The *
  660. * results of this are undefined and probably catastrophic. *
  661. * *
  662. * HISTORY: *
  663. * 03/10/1995 JLB : Created. *
  664. *=============================================================================================*/
  665. template<class T>
  666. bool DynamicVectorClass<T>::Delete(T const & object)
  667. {
  668. int id = ID(object);
  669. if (id != -1) {
  670. return(Delete(id));
  671. }
  672. return(false);
  673. }
  674. /***********************************************************************************************
  675. * DynamicVectorClass<T>::Delete -- Deletes the specified index from the vector. *
  676. * *
  677. * Use this routine to delete the object at the specified index from the objects in the *
  678. * vector. This routine will move all the remaining objects "down" in order to fill the *
  679. * hole. *
  680. * *
  681. * INPUT: index -- The index number of the object in the vector that is to be deleted. *
  682. * *
  683. * OUTPUT: bool; Was the object index deleted successfully? Failure might mean that the index *
  684. * specified was out of bounds. *
  685. * *
  686. * WARNINGS: none *
  687. * *
  688. * HISTORY: *
  689. * 03/10/1995 JLB : Created. *
  690. *=============================================================================================*/
  691. template<class T>
  692. bool DynamicVectorClass<T>::Delete(int index)
  693. {
  694. if (index < ActiveCount) {
  695. ActiveCount--;
  696. /*
  697. ** If there are any objects past the index that was deleted, copy those
  698. ** objects down in order to fill the hole. A simple memory copy is
  699. ** not sufficient since the vector could contain class objects that
  700. ** need to use the assignment operator for movement.
  701. */
  702. for (int i = index; i < ActiveCount; i++) {
  703. (*this)[i] = (*this)[i+1];
  704. }
  705. return(true);
  706. }
  707. return(false);
  708. }
  709. /***********************************************************************************************
  710. * DynamicVectorClass<T>::Uninitialized_Add -- Add an empty place to the vector. *
  711. * *
  712. * To avoid copying when creating an object and adding it to the vector, use this and *
  713. * immediately fill the area that the return value points to with a valid object (by hand *
  714. * for a struct or by using placement new for a class object). *
  715. * This function does everything Add does except copying an object into the new space, *
  716. * thus leaving an uninitialized area of memory. *
  717. * *
  718. * INPUT: none. *
  719. * *
  720. * OUTPUT: T *; Points to the empty space where the new object is to be created. (If the *
  721. * space was not added succesfully, returns NULL). *
  722. * *
  723. * WARNINGS: If memory area is left uninitialized, Very Bad Things will happen. *
  724. * *
  725. * HISTORY: *
  726. * 03/04/1998 NH : Created. *
  727. *=============================================================================================*/
  728. template<class T>
  729. T * DynamicVectorClass<T>::Uninitialized_Add(void)
  730. {
  731. if (ActiveCount >= Length()) {
  732. if ((IsAllocated || !VectorMax) && GrowthStep > 0) {
  733. if (!Resize(Length() + GrowthStep)) {
  734. /*
  735. ** Failure to increase the size of the vector is an error condition.
  736. ** Return with the error value.
  737. */
  738. return(NULL);
  739. }
  740. } else {
  741. /*
  742. ** Increasing the size of this vector is not allowed! Bail this
  743. ** routine with the error value.
  744. */
  745. return(NULL);
  746. }
  747. }
  748. /*
  749. ** There is room for the new space now. Add it to the end of the object
  750. ** vector. and return a pointer to it.
  751. */
  752. return &((*this)[ActiveCount++]);
  753. }
  754. void Set_Bit(void * array, int bit, int value);
  755. int Get_Bit(void const * array, int bit);
  756. int First_True_Bit(void const * array);
  757. int First_False_Bit(void const * array);
  758. /**************************************************************************
  759. ** This is a derivative of a vector class that supports boolean flags. Since
  760. ** a boolean flag can be represented by a single bit, this class packs the
  761. ** array of boolean flags into an array of bytes containing 8 boolean values
  762. ** each. For large boolean arrays, this results in an 87.5% savings. Although
  763. ** the indexing "[]" operator is supported, DO NOT pass pointers to sub elements
  764. ** of this bit vector class. A pointer derived from the indexing operator is
  765. ** only valid until the next call. Because of this, only simple
  766. ** direct use of the "[]" operator is allowed.
  767. */
  768. class BooleanVectorClass
  769. {
  770. public:
  771. BooleanVectorClass(unsigned size=0, unsigned char * array=0);
  772. BooleanVectorClass(BooleanVectorClass const & vector);
  773. // Assignment operator.
  774. BooleanVectorClass & operator =(BooleanVectorClass const & vector);
  775. // Equivalency operator.
  776. bool operator == (BooleanVectorClass const & vector);
  777. // Fetch number of boolean objects in vector.
  778. int Length(void) {return BitCount;};
  779. // Set all boolean values to false;
  780. void Reset(void);
  781. // Set all boolean values to true.
  782. void Set(void);
  783. // Resets vector to zero length (frees memory).
  784. void Clear(void);
  785. // Change size of this boolean vector.
  786. int Resize(unsigned size);
  787. // Fetch reference to specified index.
  788. bool const & operator[](int index) const {
  789. if (LastIndex != index) Fixup(index);
  790. return(Copy);
  791. };
  792. bool & operator[](int index) {
  793. if (LastIndex != index) Fixup(index);
  794. return(Copy);
  795. };
  796. // Quick check on boolean state.
  797. bool Is_True(int index) const {
  798. if (index == LastIndex) return(Copy);
  799. return(Get_Bit(&BitArray[0], index) != 0);
  800. };
  801. // Find first index that is false.
  802. int First_False(void) const {
  803. if (LastIndex != -1) Fixup(-1);
  804. int retval = First_False_Bit(&BitArray[0]);
  805. if (retval < BitCount) return(retval);
  806. /*
  807. ** Failure to find a false boolean value in the vector. Return this
  808. ** fact in the form of an invalid index number.
  809. */
  810. return(-1);
  811. }
  812. // Find first index that is true.
  813. int First_True(void) const {
  814. if (LastIndex != -1) Fixup(-1);
  815. int retval = First_True_Bit(&BitArray[0]);
  816. if (retval < BitCount) return(retval);
  817. /*
  818. ** Failure to find a true boolean value in the vector. Return this
  819. ** fact in the form of an invalid index number.
  820. */
  821. return(-1);
  822. }
  823. private:
  824. void Fixup(int index=-1) const;
  825. /*
  826. ** This is the number of boolean values in the vector. This value is
  827. ** not necessarily a multiple of 8, even though the underlying character
  828. ** vector contains a multiple of 8 bits.
  829. */
  830. int BitCount;
  831. /*
  832. ** This is a referential copy of an element in the bit vector. The
  833. ** purpose of this copy is to allow normal reference access to this
  834. ** object (for speed reasons). This hides the bit packing scheme from
  835. ** the user of this class.
  836. */
  837. bool Copy;
  838. /*
  839. ** This records the index of the value last fetched into the reference
  840. ** boolean variable. This index is used to properly restore the value
  841. ** when the reference copy needs updating.
  842. */
  843. int LastIndex;
  844. /*
  845. ** This points to the allocated bitfield array.
  846. */
  847. VectorClass<unsigned char> BitArray;
  848. };
  849. template<class T>
  850. int Pointer_Vector_Add(T * ptr, VectorClass<T *> & vec)
  851. {
  852. int id = 0;
  853. bool foundspot = false;
  854. for (int index = 0; index < vec.Length(); index++) {
  855. if (vec[index] == NULL) {
  856. id = index;
  857. foundspot = true;
  858. break;
  859. }
  860. }
  861. if (!foundspot) {
  862. id = vec.Length();
  863. vec.Resize((vec.Length()+1) * 2);
  864. for (int index = id; index < vec.Length(); index++) {
  865. vec[index] = NULL;
  866. }
  867. }
  868. vec[id] = ptr;
  869. return(id);
  870. }
  871. template<class T>
  872. bool Pointer_Vector_Remove(T const * ptr, VectorClass<T *> & vec)
  873. {
  874. int id = vec.ID((T *)ptr);
  875. if (id != -1) {
  876. vec[id] = NULL;
  877. return(true);
  878. }
  879. return(false);
  880. }
  881. #endif