CnC_Remastered_Collection

Command and Conquer: Red Alert
Log | Files | Refs | README | LICENSE

VECTOR.H (44616B)


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