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