| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645 |
- /*
- ** Command & Conquer Renegade(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /***********************************************************************************************
- *** 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 ***
- ***********************************************************************************************
- * *
- * Project Name : WWLib *
- * *
- * $Archive:: /Commando/Code/wwlib/simplevec.h $*
- * *
- * Original Author:: Greg Hjelstrom *
- * *
- * $Author:: Greg_h $*
- * *
- * $Modtime:: 5/16/01 10:42a $*
- * *
- * $Revision:: 16 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * SimpleVecClass<T>::SimpleVecClass -- Constructor *
- * SimpleVecClass<T>::~SimpleVecClass -- Destructor *
- * SimpleVecClass<T>::Resize -- resize the array *
- * SimpleVecClass<T>::Uninitialised_Grow -- upscale the array, don't copy contents *
- * SimpleDynVecClass<T>::~SimpleDynVecClass -- Destructor *
- * SimpleDynVecClass<T>::SimpleDynVecClass -- Constructor *
- * SimpleDynVecClass<T>::Resize -- Resize the array *
- * SimpleDynVecClass<T>::Add -- Add an item to the end of the array *
- * SimpleDynVecClass<T>::Delete -- Delete an item from the array *
- * SimpleDynVecClass<T>::Delete_Range -- delete several items from the array *
- * SimpleDynVecClass<T>::Delete_All -- delete all items from the array *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #if defined(_MSC_VER)
- #pragma once
- #endif
- #ifndef SIMPLEVEC_H
- #define SIMPLEVEC_H
- #include "always.h"
- #include <assert.h>
- #include <string.h> // for memmove
- #if (_MSC_VER >= 1200)
- #pragma warning (push)
- #pragma warning (disable:4702) // disabling the "unreachable code" warning.
- #endif
- /**
- ** SimpleVecClass
- ** This is a template similar to VectorClass (found in Vector.h) except that it is designed
- ** specifically to work with data types that are "memcopy-able".
- ** DON'T USE THIS TEMPLATE IF YOUR CLASS REQUIRES A DESTRUCTOR!!!
- */
- template <class T> class SimpleVecClass
- {
- public:
- SimpleVecClass(int size = 0);
- virtual ~SimpleVecClass(void);
- T & operator[](int index) { assert(index < VectorMax); return(Vector[index]); }
- T const & operator[](int index) const { assert(index < VectorMax); return(Vector[index]); }
- int Length(void) const { return VectorMax; }
- virtual bool Resize(int newsize);
- virtual bool Uninitialised_Grow(int newsize);
- void Zero_Memory(void) { if (Vector != NULL) { memset(Vector,0,VectorMax * sizeof(T)); } }
- protected:
-
- T * Vector;
- int VectorMax;
- };
- /***********************************************************************************************
- * SimpleVecClass<T>::SimpleVecClass -- Constructor *
- * *
- * INPUT: *
- * size - initial size of the vector *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/25/00 gth : Created. *
- *=============================================================================================*/
- template<class T>
- inline SimpleVecClass<T>::SimpleVecClass(int size) :
- Vector(NULL),
- VectorMax(0)
- {
- if (size > 0) {
- Resize(size);
- }
- }
-
- /***********************************************************************************************
- * SimpleVecClass<T>::~SimpleVecClass -- Destructor *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/25/00 gth : Created. *
- *=============================================================================================*/
- template<class T>
- inline SimpleVecClass<T>::~SimpleVecClass(void)
- {
- if (Vector != NULL) {
- delete[] Vector;
- Vector = NULL;
- VectorMax = 0;
- }
- }
- /***********************************************************************************************
- * SimpleVecClass<T>::Resize -- resize the array *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/25/00 gth : Created. *
- *=============================================================================================*/
- template<class T>
- inline bool SimpleVecClass<T>::Resize(int newsize)
- {
- if (newsize == VectorMax) {
- return true;
- }
-
- if (newsize > 0) {
- /*
- ** Allocate a new vector of the size specified. The default constructor
- ** will be called for every object in this vector.
- */
- T * newptr = new T[newsize];
- /*
- ** If there is an old vector, then it must be copied (as much as is feasible)
- ** to the new vector.
- */
- if (Vector != NULL) {
- /*
- ** Mem copy as much of the old vector into the new vector as possible.
- */
- int copycount = (newsize < VectorMax) ? newsize : VectorMax;
- memcpy(newptr,Vector,copycount * sizeof(T));
- /*
- ** Delete the old vector.
- */
- delete[] Vector;
- Vector = NULL;
- }
- /*
- ** Assign the new vector data to this class.
- */
- Vector = newptr;
- VectorMax = newsize;
- } else {
- /*
- ** Delete entire vector and reset counts
- */
- VectorMax = 0;
- if (Vector != NULL) {
- delete[] Vector;
- Vector = NULL;
- }
- }
- return true;
- }
- /***********************************************************************************************
- * SimpleVecClass<T>::Uninitialised_Grow -- resize the array if current array is too small. *
- * Note that it the function doesn't copy the contents so if resising occurs (contents are *
- * assumed uninitialised after the call). *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 6/6/00 jani : Created. *
- *=============================================================================================*/
- template<class T>
- inline bool SimpleVecClass<T>::Uninitialised_Grow(int newsize)
- {
- if (newsize <= VectorMax) {
- return true;
- }
-
- if (newsize > 0) {
- /*
- ** Allocate a new vector of the size specified. The default constructor
- ** will be called for every object in this vector.
- */
- delete[] Vector;
- Vector = new T[newsize];
- VectorMax=newsize;
- }
- return true;
- }
- /**
- ** SimpleDynVecClass
- ** This is also a template designed to work with simple data types. It is designed to work
- ** just like DynamicVectorClass except that it assumes that the data type used can be
- ** legally mem-copied.
- ** DON'T USE THIS TEMPLATE IF YOUR CLASS REQUIRES A DESTRUCTOR!!!
- **
- ** The automatic resizing behavior for this class is a little different than DynamicVectorClass.
- ** When the vector needs to be resized, it grows by 25% and if it ever shrinks to 75% usage,
- ** it resizes downwards. In addition, when adding objects, you can pass in a "next-size-hint"
- ** which is the minimum size the vector will need to be once you are done adding your set of
- ** objects. This will cause it to resize to at least that size if it needs to resize. Just
- ** leave the parameter at its default value for default behavior.
- */
- template <class T> class SimpleDynVecClass : public SimpleVecClass<T>
- {
- public:
- SimpleDynVecClass(int size = 0);
- virtual ~SimpleDynVecClass(void);
- // Array-like access (does not grow)
- int Count(void) const { return(ActiveCount); }
- T & operator[](int index) { assert(index < ActiveCount); return(Vector[index]); }
- T const & operator[](int index) const { assert(index < ActiveCount); return(Vector[index]); }
- // Change maximum size of vector
- virtual bool Resize(int newsize);
- // Add object to vector (growing as necessary).
- bool Add(T const & object,int new_size_hint = 0);
- // Add room for multiple object to vector. Pointer to first slot added is returned.
- T * Add_Multiple( int number_to_add );
- // Delete objects from the vector
- bool Delete(int index,bool allow_shrink = true);
- bool Delete(T const & object,bool allow_shrink = true);
- bool Delete_Range(int start,int count,bool allow_shrink = true);
- void Delete_All(bool allow_shrink = true);
- protected:
- bool Grow(int new_size_hint);
- bool Shrink(void);
- int Find_Index(T const & object);
- int ActiveCount;
- };
- /***********************************************************************************************
- * SimpleDynVecClass<T>::SimpleDynVecClass -- Constructor *
- * *
- * INPUT: *
- * size - initial size of the allocated vector *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/25/00 gth : Created. *
- *=============================================================================================*/
- template<class T>
- inline SimpleDynVecClass<T>::SimpleDynVecClass(int size) :
- SimpleVecClass<T>(size),
- ActiveCount(0)
- {
- }
- /***********************************************************************************************
- * SimpleDynVecClass<T>::~SimpleDynVecClass -- Destructor *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/25/00 gth : Created. *
- *=============================================================================================*/
- template<class T>
- inline SimpleDynVecClass<T>::~SimpleDynVecClass(void)
- {
- if (Vector != NULL) {
- delete[] Vector;
- Vector = NULL;
- }
- }
- /***********************************************************************************************
- * SimpleDynVecClass<T>::Resize -- Resize the array *
- * *
- * INPUT: *
- * newsize - new desired size of the array *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/25/00 gth : Created. *
- *=============================================================================================*/
- template<class T>
- inline bool SimpleDynVecClass<T>::Resize(int newsize)
- {
- if (SimpleVecClass<T>::Resize(newsize)) {
- if (Length() < ActiveCount) ActiveCount = Length();
- return(true);
- }
- return(false);
- }
- /***********************************************************************************************
- * SimpleDynVecClass<T>::Add -- Add an item to the end of the array *
- * *
- * INPUT: *
- * object - object to add to the array *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/25/00 gth : Created. *
- *=============================================================================================*/
- template<class T>
- inline bool SimpleDynVecClass<T>::Add(T const & object,int new_size_hint)
- {
- if (ActiveCount >= VectorMax) {
-
- /*
- ** We are out of space so tell the vector to grow
- */
- if (!Grow(new_size_hint)) {
- return false;
- }
- }
- /*
- ** There is room for the new object now. Add it to the end of the object vector.
- */
- (*this)[ActiveCount++] = object;
- return true;
- }
- /***********************************************************************************************
- * SimpleDynVecClass<T>::Add_Multiple -- Add room for multiple object to vector. *
- * *
- * INPUT: number of object slots to add *
- * *
- * OUTPUT: pointer to first slot added is returned. *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/25/01 bmg : Created. *
- *=============================================================================================*/
- template<class T>
- inline T * SimpleDynVecClass<T>::Add_Multiple( int number_to_add )
- {
- int index = ActiveCount;
- ActiveCount += number_to_add;
- if (ActiveCount >= VectorMax) {
-
- /*
- ** We are out of space so tell the vector to grow
- */
- Grow( ActiveCount );
- }
- return &Vector[index];
- }
- /***********************************************************************************************
- * SimpleDynVecClass<T>::Delete -- Delete an item from the array *
- * *
- * This causes the items below the specified index to be mem-moved up. *
- * *
- * INPUT: *
- * index - index of the entry to delete *
- * allow_shrink - should the vector be allowed to resize *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/25/00 gth : Created. *
- *=============================================================================================*/
- template<class T>
- inline bool SimpleDynVecClass<T>::Delete(int index,bool allow_shrink)
- {
- assert(index < ActiveCount);
- /*
- ** If there are any objects past the index that was deleted, memcopy
- ** those objects to collapse the array. NOTE: again, this template
- ** cannot be used for classes that cannot be memcopied!!
- */
- if (index < ActiveCount-1) {
- memmove(&(Vector[index]),&(Vector[index+1]),(ActiveCount - index - 1) * sizeof(T));
- }
- ActiveCount--;
- /*
- ** We deleted something so we may need to shrink
- */
- if (allow_shrink) {
- Shrink();
- }
- return true;
- }
- /***********************************************************************************************
- * SimpleDynVecClass<T>::Delete -- Remove the specified object from the vector. *
- * *
- * This routine will delete the object referenced from the vector. All objects in the *
- * vector that follow the one deleted will be moved "down" to fill the hole. *
- * *
- * INPUT: object -- Reference to the object in this vector that is to be deleted. *
- * allow_shrink -- should the vector be allowed to shrink if it is wasting space? *
- * *
- * OUTPUT: bool; Was the object deleted successfully? *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 03/10/1995 JLB : Created. *
- *=============================================================================================*/
- template<class T>
- inline bool SimpleDynVecClass<T>::Delete(T const & object,bool allow_shrink)
- {
- int id = Find_Index(object);
- if (id != -1) {
- return(Delete(id),allow_shrink);
- }
- return(false);
- }
- /***********************************************************************************************
- * SimpleDynVecClass<T>::Delete_Range -- delete several items from the array *
- * *
- * This causes the items below the specified index range to be mem-moved up. *
- * *
- * INPUT: *
- * start - starting index to delete *
- * count - number of entries to delete *
- * allow_shrink - should the vector be allowed to shrink *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/25/00 gth : Created. *
- *=============================================================================================*/
- template<class T>
- inline bool SimpleDynVecClass<T>::Delete_Range(int start,int count,bool allow_shrink)
- {
- assert(start >= 0);
- assert(start <= ActiveCount - count);
- /*
- ** If there are any objects past the index that was deleted, memcopy
- ** those objects to collapse the array. NOTE: again, this template
- ** cannot be used for classes that cannot be memcopied!!
- */
- if (start < ActiveCount - count) {
- memmove(&(Vector[start]),&(Vector[start + count]),(ActiveCount - start - count) * sizeof(T));
- }
- ActiveCount -= count;
- /*
- ** We deleted something so we may need to shrink
- */
- if (allow_shrink) {
- Shrink();
- }
-
- return true;
- }
- /***********************************************************************************************
- * SimpleDynVecClass<T>::Delete_All -- delete all items from the array *
- * *
- * Internally, this just resets the ActiveCount... *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/25/00 gth : Created. *
- *=============================================================================================*/
- template<class T>
- inline void SimpleDynVecClass<T>::Delete_All(bool allow_shrink)
- {
- ActiveCount = 0;
- /*
- ** We deleted something so we may need to shrink
- */
- if (allow_shrink) {
- Shrink();
- }
- }
- /***********************************************************************************************
- * SimpleDynVecClass<T>::Grow -- increase the size of the array *
- * *
- * Internally, this just resets the ActiveCount... *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/25/00 gth : Created. *
- *=============================================================================================*/
- template<class T>
- inline bool SimpleDynVecClass<T>::Grow(int new_size_hint)
- {
- /*
- ** Vector should grow to 25% bigger, grow at least 4 elements,
- ** and grow at least up to the user's new_size_hint
- */
- int new_size = MAX(Length() + Length()/4,Length() + 4);
- new_size = MAX(new_size,new_size_hint);
-
- return Resize(new_size);
- }
- /***********************************************************************************************
- * SimpleDynVecClass<T>::Shrink -- reduce the size of the array *
- * *
- * Internally, this just resets the ActiveCount... *
- * *
- * INPUT: *
- * *
- * OUTPUT: *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 1/25/00 gth : Created. *
- *=============================================================================================*/
- template<class T>
- inline bool SimpleDynVecClass<T>::Shrink(void)
- {
- /*
- ** Shrink the array if it is wasting more than 25%
- */
- if (ActiveCount < VectorMax/4) {
- return Resize(ActiveCount);
- }
- return true;
- }
- /***********************************************************************************************
- * SimpleDynVecClass<T>::Find_Index -- Find matching value in the dynamic vector. *
- * *
- * Use this routine to find a matching object (by value) in the vector. Unlike the base *
- * class ID function of similar name, this one restricts the scan to the current number *
- * of valid objects. *
- * *
- * INPUT: object -- A reference to the object that a match is to be found in the *
- * vector. *
- * *
- * OUTPUT: Returns with the index number of the object that is equivalent to the one *
- * specified. If no equivalent object could be found then -1 is returned. *
- * *
- * WARNINGS: none *
- * *
- * HISTORY: *
- * 03/13/1995 JLB : Created. *
- *=============================================================================================*/
- template<class T>
- inline int SimpleDynVecClass<T>::Find_Index(T const & object)
- {
- for (int index = 0; index < Count(); index++) {
- if ((*this)[index] == object) return(index);
- }
- return(-1);
- }
- #if (_MSC_VER >= 1200)
- #pragma warning (pop)
- #endif
- #endif // SIMPLEVEC_H
|