VECTOR.H 45 KB

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