VECTOR.CPP (39442B)
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: /CounterStrike/VECTOR.CPP 1 3/03/97 10:26a 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.CPP * 24 * * 25 * Programmer : Joe L. Bostic * 26 * * 27 * Start Date : 02/19/95 * 28 * * 29 * Last Update : September 21, 1995 [JLB] * 30 * * 31 *---------------------------------------------------------------------------------------------* 32 * Functions: * 33 * BooleanVectorClass::BooleanVectorClass -- Copy constructor for boolean array. * 34 * BooleanVectorClass::BooleanVectorClass -- Explicit data buffer constructor. * 35 * BooleanVectorClass::Clear -- Resets boolean vector to empty state. * 36 * BooleanVectorClass::Fixup -- Updates the boolean vector to a known state. * 37 * BooleanVectorClass::Reset -- Clear all boolean values in array. * 38 * BooleanVectorClass::Resize -- Resizes a boolean vector object. * 39 * BooleanVectorClass::Set -- Forces all boolean elements to true. * 40 * BooleanVectorClass::operator = -- Assignment operator. * 41 * BooleanVectorClass::operator == -- Comparison operator for boolean vector. * 42 * VectorClass<T>::Clear -- Frees and clears the vector. * 43 * VectorClass<T>::ID -- Finds object ID based on value. * 44 * VectorClass<T>::ID -- Pointer based conversion to index number. * 45 * VectorClass<T>::Resize -- Changes the size of the vector. * 46 * VectorClass<T>::VectorClass -- Constructor for vector class. * 47 * VectorClass<T>::VectorClass -- Copy constructor for vector object. * 48 * VectorClass<T>::operator = -- The assignment operator. * 49 * VectorClass<T>::operator == -- Equality operator for vector objects. * 50 * VectorClass<T>::~VectorClass -- Default destructor for vector class. * 51 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 52 53 #include "function.h" 54 #ifdef WINSOCK_IPX 55 #include "WSProto.h" 56 #include "WSPUDP.h" 57 #endif //WINSOCK_IPX 58 #include "vector.h" 59 //#include <mem.h> 60 #include <stdio.h> 61 62 /* 63 ** The following template function can be located here ONLY if all the instantiations are 64 ** declared in a header file this module includes. By placing the template functions here, 65 ** it speeds up compiler operation and reduces object module size. 66 */ 67 #if (0) 68 /*********************************************************************************************** 69 * VectorClass<T>::VectorClass -- Constructor for vector class. * 70 * * 71 * This constructor for the vector class is passed the initial size of the vector and an * 72 * optional pointer to a preallocated block of memory that the vector will be placed in. * 73 * If this optional pointer is NULL (or not provided), then the vector is allocated out * 74 * of free store (with the "new" operator). * 75 * * 76 * INPUT: size -- The number of elements to initialize this vector to. * 77 * * 78 * array -- Optional pointer to a previously allocated memory block to hold the * 79 * vector. * 80 * * 81 * OUTPUT: none * 82 * * 83 * WARNINGS: none * 84 * * 85 * HISTORY: * 86 * 03/10/1995 JLB : Created. * 87 *=============================================================================================*/ 88 template<class T> 89 VectorClass<T>::VectorClass(unsigned size, T const * array) : 90 Vector(0), 91 VectorMax(size), 92 IsAllocated(false) 93 { 94 /* 95 ** Allocate the vector. The default constructor will be called for every 96 ** object in this vector. 97 */ 98 if (size) { 99 if (array) { 100 Vector = new((void*)array) T[size]; 101 } else { 102 Vector = new T[size]; 103 IsAllocated = true; 104 } 105 } 106 } 107 108 109 /*********************************************************************************************** 110 * VectorClass<T>::~VectorClass -- Default destructor for vector class. * 111 * * 112 * This is the default destructor for the vector class. It will deallocate any memory * 113 * that it may have allocated. * 114 * * 115 * INPUT: none * 116 * * 117 * OUTPUT: none * 118 * * 119 * WARNINGS: none * 120 * * 121 * HISTORY: * 122 * 03/10/1995 JLB : Created. * 123 *=============================================================================================*/ 124 template<class T> 125 VectorClass<T>::~VectorClass(void) 126 { 127 VectorClass<T>::Clear(); 128 } 129 130 131 /*********************************************************************************************** 132 * VectorClass<T>::VectorClass -- Copy constructor for vector object. * 133 * * 134 * This is the copy constructor for the vector class. It will duplicate the provided * 135 * vector into the new vector being created. * 136 * * 137 * INPUT: vector -- Reference to the vector to use as a copy. * 138 * * 139 * OUTPUT: none * 140 * * 141 * WARNINGS: none * 142 * * 143 * HISTORY: * 144 * 03/10/1995 JLB : Created. * 145 *=============================================================================================*/ 146 template<class T> 147 VectorClass<T>::VectorClass(VectorClass<T> const & vector) : 148 Vector(0), 149 VectorMax(0), 150 IsAllocated(false) 151 { 152 *this = vector; 153 } 154 155 156 /*********************************************************************************************** 157 * VectorClass<T>::operator = -- The assignment operator. * 158 * * 159 * This the the assignment operator for vector objects. It will alter the existing lvalue * 160 * vector to duplicate the rvalue one. * 161 * * 162 * INPUT: vector -- The rvalue vector to copy into the lvalue one. * 163 * * 164 * OUTPUT: Returns with reference to the newly copied vector. * 165 * * 166 * WARNINGS: none * 167 * * 168 * HISTORY: * 169 * 03/10/1995 JLB : Created. * 170 *=============================================================================================*/ 171 template<class T> 172 VectorClass<T> & VectorClass<T>::operator =(VectorClass<T> const & vector) 173 { 174 if (this != &vector) { 175 Clear(); 176 VectorMax = vector.Length(); 177 if (VectorMax) { 178 Vector = new T[VectorMax]; 179 if (Vector) { 180 IsAllocated = true; 181 for (int index = 0; index < (int)VectorMax; index++) { 182 Vector[index] = vector[index]; 183 } 184 } 185 } else { 186 Vector = 0; 187 IsAllocated = false; 188 } 189 } 190 return(*this); 191 } 192 193 194 /*********************************************************************************************** 195 * VectorClass<T>::operator == -- Equality operator for vector objects. * 196 * * 197 * This operator compares two vectors for equality. It does this by performing an object * 198 * by object comparison between the two vectors. * 199 * * 200 * INPUT: vector -- The right vector expression. * 201 * * 202 * OUTPUT: bool; Are the two vectors essentially equal? (do they contain comparable elements * 203 * in the same order?) * 204 * * 205 * WARNINGS: The equality operator must exist for the objects that this vector contains. * 206 * * 207 * HISTORY: * 208 * 03/10/1995 JLB : Created. * 209 *=============================================================================================*/ 210 template<class T> 211 int VectorClass<T>::operator == (VectorClass<T> const & vector) const 212 { 213 if (VectorMax == vector.Length()) { 214 for (int index = 0; index < (int)VectorMax; index++) { 215 if (Vector[index] != vector[index]) { 216 return(false); 217 } 218 } 219 return(true); 220 } 221 return(false); 222 } 223 224 225 /*********************************************************************************************** 226 * VectorClass<T>::ID -- Pointer based conversion to index number. * 227 * * 228 * Use this routine to convert a pointer to an element in the vector back into the index * 229 * number of that object. This routine ONLY works with actual pointers to object within * 230 * the vector. For "equivalent" object index number (such as with similar integral values) * 231 * then use the "by value" index number ID function. * 232 * * 233 * INPUT: pointer -- Pointer to an actual object in the vector. * 234 * * 235 * OUTPUT: Returns with the index number for the object pointed to by the parameter. * 236 * * 237 * WARNINGS: This routine is only valid for actual pointers to object that exist within * 238 * the vector. All other object pointers will yield undefined results. * 239 * * 240 * HISTORY: * 241 * 03/13/1995 JLB : Created. * 242 *=============================================================================================*/ 243 template<class T> 244 inline int VectorClass<T>::ID(T const * ptr) 245 { 246 return(((unsigned long)ptr - (unsigned long)&(*this)[0]) / sizeof(T)); 247 } 248 249 250 /*********************************************************************************************** 251 * VectorClass<T>::ID -- Finds object ID based on value. * 252 * * 253 * Use this routine to find the index value of an object with equivalent value in the * 254 * vector. Typical use of this would be for integral types. * 255 * * 256 * INPUT: object -- Reference to the object that is to be looked up in the vector. * 257 * * 258 * OUTPUT: Returns with the index number of the object that is equivalent to the one * 259 * specified. If no matching value could be found then -1 is returned. * 260 * * 261 * WARNINGS: none * 262 * * 263 * HISTORY: * 264 * 03/13/1995 JLB : Created. * 265 *=============================================================================================*/ 266 template<class T> 267 int VectorClass<T>::ID(T const & object) 268 { 269 for (int index = 0; index < (int)VectorMax; index++) { 270 if ((*this)[index] == object) { 271 return(index); 272 } 273 } 274 return(-1); 275 } 276 277 278 /*********************************************************************************************** 279 * VectorClass<T>::Clear -- Frees and clears the vector. * 280 * * 281 * Use this routine to reset the vector to an empty (non-allocated) state. A vector will * 282 * free all allocated memory when this routine is called. In order for the vector to be * 283 * useful after this point, the Resize function must be called to give it element space. * 284 * * 285 * INPUT: none * 286 * * 287 * OUTPUT: none * 288 * * 289 * WARNINGS: none * 290 * * 291 * HISTORY: * 292 * 03/10/1995 JLB : Created. * 293 *=============================================================================================*/ 294 template<class T> 295 void VectorClass<T>::Clear(void) 296 { 297 if (Vector && IsAllocated) { 298 delete[] Vector; 299 Vector = 0; 300 } 301 IsAllocated = false; 302 VectorMax = 0; 303 } 304 305 306 /*********************************************************************************************** 307 * VectorClass<T>::Resize -- Changes the size of the vector. * 308 * * 309 * This routine is used to change the size (usually to increase) the size of a vector. This * 310 * is the only way to increase the vector's working room (number of elements). * 311 * * 312 * INPUT: newsize -- The desired size of the vector. * 313 * * 314 * array -- Optional pointer to a previously allocated memory block that the * 315 * array will be located in. If this parameter is not supplied, then * 316 * the array will be allocated from free store. * 317 * * 318 * OUTPUT: bool; Was the array resized successfully? * 319 * * 320 * WARNINGS: Failure to succeed could be the result of running out of memory. * 321 * * 322 * HISTORY: * 323 * 03/10/1995 JLB : Created. * 324 *=============================================================================================*/ 325 template<class T> 326 int VectorClass<T>::Resize(unsigned newsize, T const * array) 327 { 328 if (newsize) { 329 330 /* 331 ** Allocate a new vector of the size specified. The default constructor 332 ** will be called for every object in this vector. 333 */ 334 T * newptr; 335 if (!array) { 336 newptr = new T[newsize]; 337 } else { 338 newptr = new((void*)array) T[newsize]; 339 } 340 if (!newptr) { 341 return(false); 342 } 343 344 /* 345 ** If there is an old vector, then it must be copied (as much as is feasible) 346 ** to the new vector. 347 */ 348 if (Vector) { 349 350 /* 351 ** Copy as much of the old vector into the new vector as possible. This 352 ** presumes that there is a functional assignment operator for each 353 ** of the objects in the vector. 354 */ 355 int copycount = (newsize < VectorMax) ? newsize : VectorMax; 356 for (int index = 0; index < copycount; index++) { 357 newptr[index] = Vector[index]; 358 } 359 360 /* 361 ** Delete the old vector. This might cause the destructors to be called 362 ** for all of the old elements. This makes the implementation of suitable 363 ** assignment operator very important. The default assignment operator will 364 ** only work for the simplest of objects. 365 */ 366 if (IsAllocated) { 367 delete[] Vector; 368 Vector = 0; 369 } 370 } 371 372 /* 373 ** Assign the new vector data to this class. 374 */ 375 Vector = newptr; 376 VectorMax = newsize; 377 IsAllocated = (Vector && !array); 378 379 } else { 380 381 /* 382 ** Resizing to zero is the same as clearing the vector. 383 */ 384 Clear(); 385 } 386 return(true); 387 } 388 #endif 389 //---------------------------------------------------------------------------------------------- 390 391 /*********************************************************************************************** 392 * BooleanVectorClass::BooleanVectorClass -- Explicit data buffer constructor. * 393 * * 394 * This is the constructor for a boolean array. This constructor takes the memory pointer * 395 * provided as assigns that as the array data pointer. * 396 * * 397 * INPUT: size -- The size of the array (in bits). * 398 * * 399 * array -- Pointer to the memory that the array is to use. * 400 * * 401 * OUTPUT: none * 402 * * 403 * WARNINGS: You must make sure that the memory specified is large enough to contain the * 404 * bits specified. * 405 * * 406 * HISTORY: * 407 * 07/18/1995 JLB : Created. * 408 *=============================================================================================*/ 409 BooleanVectorClass::BooleanVectorClass(unsigned size, unsigned char * array) 410 { 411 BitArray.Resize(((size + (8-1)) / 8), array); 412 LastIndex = -1; 413 BitCount = size; 414 } 415 416 417 /*********************************************************************************************** 418 * BooleanVectorClass::BooleanVectorClass -- Copy constructor of boolean array. * 419 * * 420 * This is the copy constructor for a boolean array. It is used to make a duplicate of the * 421 * boolean array. * 422 * * 423 * INPUT: vector -- Reference to the vector to be duplicated. * 424 * * 425 * OUTPUT: none * 426 * * 427 * WARNINGS: none * 428 * * 429 * HISTORY: * 430 * 07/18/1995 JLB : Created. * 431 *=============================================================================================*/ 432 BooleanVectorClass::BooleanVectorClass(BooleanVectorClass const & vector) 433 { 434 LastIndex = -1; 435 *this = vector; 436 } 437 438 439 /*********************************************************************************************** 440 * BooleanVectorClass::operator = -- Assignment operator. * 441 * * 442 * This routine will make a copy of the specified boolean vector array. The vector is * 443 * copied into an already constructed existing vector. The values from the existing vector * 444 * are destroyed by this copy. * 445 * * 446 * INPUT: vector -- Reference to the vector to make a copy of. * 447 * * 448 * OUTPUT: none * 449 * * 450 * WARNINGS: none * 451 * * 452 * HISTORY: * 453 * 07/18/1995 JLB : Created. * 454 *=============================================================================================*/ 455 BooleanVectorClass & BooleanVectorClass::operator =(BooleanVectorClass const & vector) 456 { 457 Fixup(); 458 Copy = vector.Copy; 459 LastIndex = vector.LastIndex; 460 BitArray = vector.BitArray; 461 BitCount = vector.BitCount; 462 return(*this); 463 } 464 465 466 /*********************************************************************************************** 467 * BooleanVectorClass::operator == -- Comparison operator for boolean vector. * 468 * * 469 * This is the comparison operator for a boolean vector class. Boolean vectors are equal * 470 * if the bit count and bit values are identical. * 471 * * 472 * INPUT: vector -- Reference to the vector to compare to. * 473 * * 474 * OUTPUT: Are the boolean vectors identical? * 475 * * 476 * WARNINGS: none * 477 * * 478 * HISTORY: * 479 * 07/18/1995 JLB : Created. * 480 *=============================================================================================*/ 481 int BooleanVectorClass::operator == (const BooleanVectorClass & vector) 482 { 483 Fixup(LastIndex); 484 return(BitCount == vector.BitCount && BitArray == vector.BitArray); 485 } 486 487 488 /*********************************************************************************************** 489 * BooleanVectorClass::Resize -- Resizes a boolean vector object. * 490 * * 491 * This routine will resize the boolean vector object. An index value used with a boolean * 492 * vector must be less than the value specified in as the new size. * 493 * * 494 * INPUT: size -- The new maximum size of this boolean vector. * 495 * * 496 * OUTPUT: Was the boolean vector sized successfully? * 497 * * 498 * WARNINGS: The boolean array might be reallocated or even deleted by this routine. * 499 * * 500 * HISTORY: * 501 * 07/18/1995 JLB : Created. * 502 *=============================================================================================*/ 503 int BooleanVectorClass::Resize(unsigned size) 504 { 505 Fixup(); 506 507 if (size) { 508 509 /* 510 ** Record the previous bit count of the boolean vector. This is used 511 ** to determine if the array has grown in size and thus clearing is 512 ** necessary. 513 */ 514 int oldsize = BitCount; 515 516 /* 517 ** Actually resize the bit array. Since this is a bit packed array, 518 ** there are 8 elements per byte (rounded up). 519 */ 520 int success = BitArray.Resize(((size + (8-1)) / 8)); 521 522 /* 523 ** Since there is no default constructor for bit packed integers, a manual 524 ** clearing of the bits is required. 525 */ 526 BitCount = size; 527 if (success && oldsize < (int)size) { 528 for (int index = oldsize; index < (int)size; index++) { 529 (*this)[index] = 0; 530 } 531 } 532 533 return(success); 534 } 535 536 /* 537 ** Resizing to zero is the same as clearing and deallocating the array. 538 ** This is always successful. 539 */ 540 Clear(); 541 return(true); 542 } 543 544 545 /*********************************************************************************************** 546 * BooleanVectorClass::Clear -- Resets boolean vector to empty state. * 547 * * 548 * This routine will clear out the boolean array. This will free any allocated memory and * 549 * result in the boolean vector being unusable until the Resize function is subsequently * 550 * called. * 551 * * 552 * INPUT: none * 553 * * 554 * OUTPUT: none * 555 * * 556 * WARNINGS: The boolean vector cannot be used until it is resized to a non null condition. * 557 * * 558 * HISTORY: * 559 * 07/18/1995 JLB : Created. * 560 *=============================================================================================*/ 561 void BooleanVectorClass::Clear(void) 562 { 563 Fixup(); 564 BitCount = 0; 565 BitArray.Clear(); 566 } 567 568 569 /*********************************************************************************************** 570 * BooleanVectorClass::Reset -- Clear all boolean values in array. * 571 * * 572 * This is the preferred (and quick) method to clear the boolean array to a false condition.* 573 * * 574 * INPUT: none * 575 * * 576 * OUTPUT: none * 577 * * 578 * WARNINGS: none * 579 * * 580 * HISTORY: * 581 * 07/18/1995 JLB : Created. * 582 *=============================================================================================*/ 583 void BooleanVectorClass::Reset(void) 584 { 585 LastIndex = -1; 586 if (BitArray.Length()) { 587 memset(&BitArray[0], '\0', BitArray.Length()); 588 } 589 } 590 591 592 /*********************************************************************************************** 593 * BooleanVectorClass::Set -- Forces all boolean elements to true. * 594 * * 595 * This is the preferred (and fast) way to set all boolean elements to true. * 596 * * 597 * INPUT: none * 598 * * 599 * OUTPUT: none * 600 * * 601 * WARNINGS: none * 602 * * 603 * HISTORY: * 604 * 07/18/1995 JLB : Created. * 605 *=============================================================================================*/ 606 void BooleanVectorClass::Set(void) 607 { 608 LastIndex = -1; 609 if (BitArray.Length()) { 610 memset(&BitArray[0], '\xFF', BitArray.Length()); 611 } 612 } 613 614 615 /*********************************************************************************************** 616 * BooleanVectorClass::Fixup -- Updates the boolean vector to a known state. * 617 * * 618 * Use this routine to set the boolean value copy to match the appropriate bit in the * 619 * boolean array. The boolean array will be updated with any changes from the last time * 620 * a value was fetched from the boolean vector. By using this update method, the boolean * 621 * array can be treated as a normal array even though the elements are composed of * 622 * otherwise inaccessible bits. * 623 * * 624 * INPUT: index -- The index to set the new copy value to. If the index is -1, then the * 625 * previous value will be updated into the vector array, but no new value * 626 * will be fetched from it. * 627 * * 628 * OUTPUT: none * 629 * * 630 * WARNINGS: Always call this routine with "-1" if any direct manipulation of the bit * 631 * array is to occur. This ensures that the bit array is accurate. * 632 * * 633 * HISTORY: * 634 * 07/18/1995 JLB : Created. * 635 *=============================================================================================*/ 636 void BooleanVectorClass::Fixup(int index) const 637 { 638 /* 639 ** If the requested index value is illegal, then force the index 640 ** to be -1. This is the default non-index value. 641 */ 642 if (index >= BitCount) { 643 index = -1; 644 } 645 646 /* 647 ** If the new index is different than the previous index, there might 648 ** be some fixing up required. 649 */ 650 if (index != LastIndex) { 651 652 /* 653 ** If the previously fetched boolean value was changed, then update 654 ** the boolean array accordingly. 655 */ 656 if (LastIndex != -1) { 657 Set_Bit((void*)&BitArray[0], LastIndex, Copy); 658 } 659 660 /* 661 ** If this new current index is valid, then fill in the reference boolean 662 ** value with the appropriate data from the bit array. 663 */ 664 if (index != -1) { 665 ((unsigned char&)Copy) = Get_Bit(&BitArray[0], index); 666 } 667 668 ((int &)LastIndex) = index; 669 } 670 } 671 672