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