Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
simplevec.h
Go to the documentation of this file.
1/*
2** Command & Conquer Generals Zero Hour(tm)
3** Copyright 2025 Electronic Arts Inc.
4**
5** This program is free software: you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation, either version 3 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19/***********************************************************************************************
20 *** 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 ***
21 ***********************************************************************************************
22 * *
23 * Project Name : WWLib *
24 * *
25 * $Archive:: /Commando/Code/wwlib/simplevec.h $*
26 * *
27 * Original Author:: Greg Hjelstrom *
28 * *
29 * $Author:: Greg_h $*
30 * *
31 * $Modtime:: 5/16/01 10:42a $*
32 * *
33 * $Revision:: 16 $*
34 * *
35 *---------------------------------------------------------------------------------------------*
36 * Functions: *
37 * SimpleVecClass<T>::SimpleVecClass -- Constructor *
38 * SimpleVecClass<T>::~SimpleVecClass -- Destructor *
39 * SimpleVecClass<T>::Resize -- resize the array *
40 * SimpleVecClass<T>::Uninitialised_Grow -- upscale the array, don't copy contents *
41 * SimpleDynVecClass<T>::~SimpleDynVecClass -- Destructor *
42 * SimpleDynVecClass<T>::SimpleDynVecClass -- Constructor *
43 * SimpleDynVecClass<T>::Resize -- Resize the array *
44 * SimpleDynVecClass<T>::Add -- Add an item to the end of the array *
45 * SimpleDynVecClass<T>::Delete -- Delete an item from the array *
46 * SimpleDynVecClass<T>::Delete_Range -- delete several items from the array *
47 * SimpleDynVecClass<T>::Delete_All -- delete all items from the array *
48 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
49
50#if defined(_MSC_VER)
51#pragma once
52#endif
53
54#ifndef SIMPLEVEC_H
55#define SIMPLEVEC_H
56
57#include "always.h"
58#include <assert.h>
59#include <string.h> // for memmove
60
61
62#if (_MSC_VER >= 1200)
63#pragma warning (push)
64#pragma warning (disable:4702) // disabling the "unreachable code" warning.
65#endif
66
73template <class T> class SimpleVecClass
74{
75public:
76
77 SimpleVecClass(int size = 0);
78 virtual ~SimpleVecClass(void);
79
80 T & operator[](int index) { assert(index < VectorMax); return(Vector[index]); }
81 T const & operator[](int index) const { assert(index < VectorMax); return(Vector[index]); }
82
83 int Length(void) const { return VectorMax; }
84 virtual bool Resize(int newsize);
85 virtual bool Uninitialised_Grow(int newsize);
86 void Zero_Memory(void) { if (Vector != NULL) { memset(Vector,0,VectorMax * sizeof(T)); } }
87
88protected:
89
90 T * Vector;
92};
93
94
95/***********************************************************************************************
96 * SimpleVecClass<T>::SimpleVecClass -- Constructor *
97 * *
98 * INPUT: *
99 * size - initial size of the vector *
100 * *
101 * OUTPUT: *
102 * *
103 * WARNINGS: *
104 * *
105 * HISTORY: *
106 * 1/25/00 gth : Created. *
107 *=============================================================================================*/
108template<class T>
110 Vector(NULL),
111 VectorMax(0)
112{
113 if (size > 0) {
114 Resize(size);
115 }
116}
117
118/***********************************************************************************************
119 * SimpleVecClass<T>::~SimpleVecClass -- Destructor *
120 * *
121 * INPUT: *
122 * *
123 * OUTPUT: *
124 * *
125 * WARNINGS: *
126 * *
127 * HISTORY: *
128 * 1/25/00 gth : Created. *
129 *=============================================================================================*/
130template<class T>
132{
133 if (Vector != NULL) {
134 delete[] Vector;
135 Vector = NULL;
136 VectorMax = 0;
137 }
138}
139
140/***********************************************************************************************
141 * SimpleVecClass<T>::Resize -- resize the array *
142 * *
143 * INPUT: *
144 * *
145 * OUTPUT: *
146 * *
147 * WARNINGS: *
148 * *
149 * HISTORY: *
150 * 1/25/00 gth : Created. *
151 *=============================================================================================*/
152template<class T>
153inline bool SimpleVecClass<T>::Resize(int newsize)
154{
155 if (newsize == VectorMax) {
156 return true;
157 }
158
159 if (newsize > 0) {
160
161 /*
162 ** Allocate a new vector of the size specified. The default constructor
163 ** will be called for every object in this vector.
164 */
165 T * newptr = W3DNEWARRAY T[newsize];
166
167 /*
168 ** If there is an old vector, then it must be copied (as much as is feasible)
169 ** to the new vector.
170 */
171 if (Vector != NULL) {
172
173 /*
174 ** Mem copy as much of the old vector into the new vector as possible.
175 */
176 int copycount = (newsize < VectorMax) ? newsize : VectorMax;
177 memcpy(newptr,Vector,copycount * sizeof(T));
178
179 /*
180 ** Delete the old vector.
181 */
182 delete[] Vector;
183 Vector = NULL;
184 }
185
186 /*
187 ** Assign the new vector data to this class.
188 */
189 Vector = newptr;
190 VectorMax = newsize;
191
192 } else {
193
194 /*
195 ** Delete entire vector and reset counts
196 */
197 VectorMax = 0;
198 if (Vector != NULL) {
199 delete[] Vector;
200 Vector = NULL;
201 }
202 }
203 return true;
204}
205
206/***********************************************************************************************
207 * SimpleVecClass<T>::Uninitialised_Grow -- resize the array if current array is too small. *
208 * Note that it the function doesn't copy the contents so if resising occurs (contents are *
209 * assumed uninitialised after the call). *
210 * *
211 * INPUT: *
212 * *
213 * OUTPUT: *
214 * *
215 * WARNINGS: *
216 * *
217 * HISTORY: *
218 * 6/6/00 jani : Created. *
219 *=============================================================================================*/
220template<class T>
222{
223 if (newsize <= VectorMax) {
224 return true;
225 }
226
227 if (newsize > 0) {
228
229 /*
230 ** Allocate a new vector of the size specified. The default constructor
231 ** will be called for every object in this vector.
232 */
233 delete[] Vector;
234 Vector = W3DNEWARRAY T[newsize];
235 VectorMax=newsize;
236 }
237 return true;
238}
239
240
255template <class T> class SimpleDynVecClass : public SimpleVecClass<T>
256{
257public:
258
259 SimpleDynVecClass(int size = 0);
260 virtual ~SimpleDynVecClass(void);
261
262 // Array-like access (does not grow)
263 int Count(void) const { return(ActiveCount); }
264 T & operator[](int index) { assert(index < ActiveCount); return(Vector[index]); }
265 T const & operator[](int index) const { assert(index < ActiveCount); return(Vector[index]); }
266
267 // Change maximum size of vector
268 virtual bool Resize(int newsize);
269
270 // Add object to vector (growing as necessary).
271 bool Add(T const & object,int new_size_hint = 0);
272
273 // Add room for multiple object to vector. Pointer to first slot added is returned.
274 T * Add_Multiple( int number_to_add );
275
276 // Delete objects from the vector
277 bool Delete(int index,bool allow_shrink = true);
278 bool Delete(T const & object,bool allow_shrink = true);
279 bool Delete_Range(int start,int count,bool allow_shrink = true);
280 void Delete_All(bool allow_shrink = true);
281
282protected:
283
284 bool Grow(int new_size_hint);
285 bool Shrink(void);
286
287 int Find_Index(T const & object);
288
290};
291
292
293/***********************************************************************************************
294 * SimpleDynVecClass<T>::SimpleDynVecClass -- Constructor *
295 * *
296 * INPUT: *
297 * size - initial size of the allocated vector *
298 * *
299 * OUTPUT: *
300 * *
301 * WARNINGS: *
302 * *
303 * HISTORY: *
304 * 1/25/00 gth : Created. *
305 *=============================================================================================*/
306template<class T>
308 SimpleVecClass<T>(size),
309 ActiveCount(0)
310{
311}
312
313/***********************************************************************************************
314 * SimpleDynVecClass<T>::~SimpleDynVecClass -- Destructor *
315 * *
316 * INPUT: *
317 * *
318 * OUTPUT: *
319 * *
320 * WARNINGS: *
321 * *
322 * HISTORY: *
323 * 1/25/00 gth : Created. *
324 *=============================================================================================*/
325template<class T>
327{
328 if (Vector != NULL) {
329 delete[] Vector;
330 Vector = NULL;
331 }
332}
333
334/***********************************************************************************************
335 * SimpleDynVecClass<T>::Resize -- Resize the array *
336 * *
337 * INPUT: *
338 * newsize - new desired size of the array *
339 * *
340 * OUTPUT: *
341 * *
342 * WARNINGS: *
343 * *
344 * HISTORY: *
345 * 1/25/00 gth : Created. *
346 *=============================================================================================*/
347template<class T>
348inline bool SimpleDynVecClass<T>::Resize(int newsize)
349{
350 if (SimpleVecClass<T>::Resize(newsize)) {
352 return(true);
353 }
354 return(false);
355}
356
357/***********************************************************************************************
358 * SimpleDynVecClass<T>::Add -- Add an item to the end of the array *
359 * *
360 * INPUT: *
361 * object - object to add to the array *
362 * *
363 * OUTPUT: *
364 * *
365 * WARNINGS: *
366 * *
367 * HISTORY: *
368 * 1/25/00 gth : Created. *
369 *=============================================================================================*/
370template<class T>
371inline bool SimpleDynVecClass<T>::Add(T const & object,int new_size_hint)
372{
373 if (ActiveCount >= VectorMax) {
374
375 /*
376 ** We are out of space so tell the vector to grow
377 */
378 if (!Grow(new_size_hint)) {
379 return false;
380 }
381
382 }
383
384 /*
385 ** There is room for the new object now. Add it to the end of the object vector.
386 */
387 (*this)[ActiveCount++] = object;
388 return true;
389}
390
391/***********************************************************************************************
392 * SimpleDynVecClass<T>::Add_Multiple -- Add room for multiple object to vector. *
393 * *
394 * INPUT: number of object slots to add *
395 * *
396 * OUTPUT: pointer to first slot added is returned. *
397 * *
398 * WARNINGS: *
399 * *
400 * HISTORY: *
401 * 1/25/01 bmg : Created. *
402 *=============================================================================================*/
403template<class T>
404inline T * SimpleDynVecClass<T>::Add_Multiple( int number_to_add )
405{
406 int index = ActiveCount;
407 ActiveCount += number_to_add;
408
409 if (ActiveCount >= VectorMax) {
410
411 /*
412 ** We are out of space so tell the vector to grow
413 */
414 Grow( ActiveCount );
415 }
416
417 return &Vector[index];
418}
419
420
421/***********************************************************************************************
422 * SimpleDynVecClass<T>::Delete -- Delete an item from the array *
423 * *
424 * This causes the items below the specified index to be mem-moved up. *
425 * *
426 * INPUT: *
427 * index - index of the entry to delete *
428 * allow_shrink - should the vector be allowed to resize *
429 * *
430 * OUTPUT: *
431 * *
432 * WARNINGS: *
433 * *
434 * HISTORY: *
435 * 1/25/00 gth : Created. *
436 *=============================================================================================*/
437template<class T>
438inline bool SimpleDynVecClass<T>::Delete(int index,bool allow_shrink)
439{
440 assert(index < ActiveCount);
441
442 /*
443 ** If there are any objects past the index that was deleted, memcopy
444 ** those objects to collapse the array. NOTE: again, this template
445 ** cannot be used for classes that cannot be memcopied!!
446 */
447 if (index < ActiveCount-1) {
448 memmove(&(Vector[index]),&(Vector[index+1]),(ActiveCount - index - 1) * sizeof(T));
449 }
450 ActiveCount--;
451
452 /*
453 ** We deleted something so we may need to shrink
454 */
455 if (allow_shrink) {
456 Shrink();
457 }
458
459 return true;
460}
461
462/***********************************************************************************************
463 * SimpleDynVecClass<T>::Delete -- Remove the specified object from the vector. *
464 * *
465 * This routine will delete the object referenced from the vector. All objects in the *
466 * vector that follow the one deleted will be moved "down" to fill the hole. *
467 * *
468 * INPUT: object -- Reference to the object in this vector that is to be deleted. *
469 * allow_shrink -- should the vector be allowed to shrink if it is wasting space? *
470 * *
471 * OUTPUT: bool; Was the object deleted successfully? *
472 * *
473 * WARNINGS: *
474 * *
475 * HISTORY: *
476 * 03/10/1995 JLB : Created. *
477 *=============================================================================================*/
478template<class T>
479inline bool SimpleDynVecClass<T>::Delete(T const & object,bool allow_shrink)
480{
481 int id = Find_Index(object);
482 if (id != -1) {
483 return(Delete(id),allow_shrink);
484 }
485 return(false);
486}
487
488/***********************************************************************************************
489 * SimpleDynVecClass<T>::Delete_Range -- delete several items from the array *
490 * *
491 * This causes the items below the specified index range to be mem-moved up. *
492 * *
493 * INPUT: *
494 * start - starting index to delete *
495 * count - number of entries to delete *
496 * allow_shrink - should the vector be allowed to shrink *
497 * *
498 * OUTPUT: *
499 * *
500 * WARNINGS: *
501 * *
502 * HISTORY: *
503 * 1/25/00 gth : Created. *
504 *=============================================================================================*/
505template<class T>
506inline bool SimpleDynVecClass<T>::Delete_Range(int start,int count,bool allow_shrink)
507{
508 assert(start >= 0);
509 assert(start <= ActiveCount - count);
510
511 /*
512 ** If there are any objects past the index that was deleted, memcopy
513 ** those objects to collapse the array. NOTE: again, this template
514 ** cannot be used for classes that cannot be memcopied!!
515 */
516 if (start < ActiveCount - count) {
517 memmove(&(Vector[start]),&(Vector[start + count]),(ActiveCount - start - count) * sizeof(T));
518 }
519
520 ActiveCount -= count;
521
522 /*
523 ** We deleted something so we may need to shrink
524 */
525 if (allow_shrink) {
526 Shrink();
527 }
528
529 return true;
530}
531
532/***********************************************************************************************
533 * SimpleDynVecClass<T>::Delete_All -- delete all items from the array *
534 * *
535 * Internally, this just resets the ActiveCount... *
536 * *
537 * INPUT: *
538 * *
539 * OUTPUT: *
540 * *
541 * WARNINGS: *
542 * *
543 * HISTORY: *
544 * 1/25/00 gth : Created. *
545 *=============================================================================================*/
546template<class T>
547inline void SimpleDynVecClass<T>::Delete_All(bool allow_shrink)
548{
549 ActiveCount = 0;
550
551 /*
552 ** We deleted something so we may need to shrink
553 */
554 if (allow_shrink) {
555 Shrink();
556 }
557}
558
559/***********************************************************************************************
560 * SimpleDynVecClass<T>::Grow -- increase the size of the array *
561 * *
562 * Internally, this just resets the ActiveCount... *
563 * *
564 * INPUT: *
565 * *
566 * OUTPUT: *
567 * *
568 * WARNINGS: *
569 * *
570 * HISTORY: *
571 * 1/25/00 gth : Created. *
572 *=============================================================================================*/
573template<class T>
574inline bool SimpleDynVecClass<T>::Grow(int new_size_hint)
575{
576 /*
577 ** Vector should grow to 25% bigger, grow at least 4 elements,
578 ** and grow at least up to the user's new_size_hint
579 */
580 int new_size = MAX(Length() + Length()/4,Length() + 4);
581 new_size = MAX(new_size,new_size_hint);
582
583 return Resize(new_size);
584}
585
586/***********************************************************************************************
587 * SimpleDynVecClass<T>::Shrink -- reduce the size of the array *
588 * *
589 * Internally, this just resets the ActiveCount... *
590 * *
591 * INPUT: *
592 * *
593 * OUTPUT: *
594 * *
595 * WARNINGS: *
596 * *
597 * HISTORY: *
598 * 1/25/00 gth : Created. *
599 *=============================================================================================*/
600template<class T>
602{
603 /*
604 ** Shrink the array if it is wasting more than 25%
605 */
606 if (ActiveCount < VectorMax/4) {
607 return Resize(ActiveCount);
608 }
609 return true;
610}
611
612
613/***********************************************************************************************
614 * SimpleDynVecClass<T>::Find_Index -- Find matching value in the dynamic vector. *
615 * *
616 * Use this routine to find a matching object (by value) in the vector. Unlike the base *
617 * class ID function of similar name, this one restricts the scan to the current number *
618 * of valid objects. *
619 * *
620 * INPUT: object -- A reference to the object that a match is to be found in the *
621 * vector. *
622 * *
623 * OUTPUT: Returns with the index number of the object that is equivalent to the one *
624 * specified. If no equivalent object could be found then -1 is returned. *
625 * *
626 * WARNINGS: none *
627 * *
628 * HISTORY: *
629 * 03/13/1995 JLB : Created. *
630 *=============================================================================================*/
631template<class T>
632inline int SimpleDynVecClass<T>::Find_Index(T const & object)
633{
634 for (int index = 0; index < Count(); index++) {
635 if ((*this)[index] == object) return(index);
636 }
637 return(-1);
638}
639
640#if (_MSC_VER >= 1200)
641#pragma warning (pop)
642#endif
643
644#endif // SIMPLEVEC_H
645
#define NULL
Definition BaseType.h:92
#define W3DNEWARRAY
Definition always.h:110
#define MAX(a, b)
Definition always.h:185
void Delete_All(bool allow_shrink=true)
Definition simplevec.h:547
int Count(void) const
Definition simplevec.h:263
T * Add_Multiple(int number_to_add)
Definition simplevec.h:404
int Find_Index(T const &object)
Definition simplevec.h:632
virtual ~SimpleDynVecClass(void)
Definition simplevec.h:326
bool Add(T const &object, int new_size_hint=0)
Definition simplevec.h:371
SimpleDynVecClass(int size=0)
Definition simplevec.h:307
T & operator[](int index)
Definition simplevec.h:264
virtual bool Resize(int newsize)
Definition simplevec.h:348
bool Shrink(void)
Definition simplevec.h:601
bool Delete(T const &object, bool allow_shrink=true)
Definition simplevec.h:479
T const & operator[](int index) const
Definition simplevec.h:265
bool Delete_Range(int start, int count, bool allow_shrink=true)
Definition simplevec.h:506
bool Delete(int index, bool allow_shrink=true)
Definition simplevec.h:438
bool Grow(int new_size_hint)
Definition simplevec.h:574
virtual bool Resize(int newsize)
Definition simplevec.h:153
T & operator[](int index)
Definition simplevec.h:80
T const & operator[](int index) const
Definition simplevec.h:81
void Zero_Memory(void)
Definition simplevec.h:86
virtual ~SimpleVecClass(void)
Definition simplevec.h:131
int Length(void) const
Definition simplevec.h:83
SimpleVecClass(int size=0)
Definition simplevec.h:109
virtual bool Uninitialised_Grow(int newsize)
Definition simplevec.h:221