// FlexArrayTmpl.hh #ifndef __FLEXARRAY_TMPL_HH_ #define __FLEXARRAY_TMPL_HH_ #ifdef SGI #include #endif #include "Arch.h" // #define DOUBLEWORD 8 // sgi doubleword == -align64 at a minimum #define DOUBLEWORD 1 // kludge for space efficiency (should allow setting of blocksize // #define FLEXARRAYDEBUG /*------------- Template: FlexArray Purpose: Simplifies dynamically allocated array management since it contains array size information and manages array resizing. However, since speed-critical operations like indexing (the [] operator) are inlined, it adds no speed penalty for the most common speed-critical operations. Method Summary: constructor: The initial "size" is 0 (the size of the array that is accessible using the indexing operator []. However, the internally allocated size is a minimum of 8 elements. [] : Indexing operator. Acts just like [] would for a generic array. Since it is inlined, there is actually no penalty in performance compared to using a generic array. append : Add an element to the end of the array, resizing the array if necessary. The arrays are allocated in blocks so it doesn't need to realloc on every append. For arrays < 1024 elements long, it doubles the array size on each realloc. When larger than 1024 elements, it adds 1024 elements to the array on every realloc. setSize(): Sets the internal and externally availible array sizes to the specified size; shrinking a larger internal array if necessary. getSize(): Return the current externally availible array size. The internal size may be larger. ---------------*/ template class FlexArray { int size,maxsize; T *data; // Internal reallocation procedure. void grow(int targetSize=1); public: // constructor FlexArray(int sz=0); // copy constructor FlexArray(FlexArray &src); FlexArray &operator=(FlexArray &src); // destructor ~FlexArray(); inline int getSize(){return size;} int setSize(int s); int append(T value); int append(T *values,int nvals); #ifdef FLEXARRAYDEBUG T &operator[](int idx){ if(idx>=size || idx<0) { // range check printf("FlexArray:: Bad index. Arraysize=%u Index=%u\n", size,idx); idx=0; } return (data[idx]); } #else inline T &operator[](int idx){ return (data[idx]); } #endif // purge? which forces array delete inline void purge(){ if(data) delete[] data; #ifdef FLEXARRAYDEBUG else printf("-----FlexArray.purge(): Data was already 0\n"); printf("****Flexarray.purge() maxsize=%u size=%u data was = %lX\n", maxsize,size,data); #endif data=0; maxsize=size=0; } //inline operator T*() { return data; } // typecasting operator inline T *getData() { return data; } // sometimes you need direct access to the contained array. }; template FlexArray::FlexArray(int sz):size(sz){ /* if(sz>DOUBLEWORD) maxsize=sz; else maxsize=DOUBLEWORD; always allocate in doubleword chunks data = new T[maxsize]; */ maxsize=sz; // problem here is that virtually guarauntees reallocation if(maxsize>0) data = new T[maxsize]; else data = 0; #ifdef FLEXARRAYDEBUG printf("****FlexArray constructor: Init with maxsize=%u size=%u data was = %lX\n", maxsize,size,data); #endif } template FlexArray::~FlexArray(){ if(maxsize>0 && data) delete[] data; size=maxsize=0; data=0; } template void FlexArray::grow(int targetSize){ #ifdef FLEXARRAYDEBUG printf("****FlexArray.grow(targ=%u): Init with maxsize=%u size=%u data was = %lX\n", targetSize,maxsize,size,data); #endif do{ if(!maxsize) maxsize=1; //if(maxsize<1024) maxsize<<=1; // double in size //else // maxsize+=1024; // increase by 1k element block }while(maxsize%u\n",targetSize,maxsize); T *newdata=new T[maxsize]; // has to do its own copy because realloc is not always compatible with // new/delete on all machines if(data){ for(int i=0;i FlexArray::FlexArray(FlexArray &src):data(0),size(0),maxsize(0){ setSize(src.getSize()); //puts("\tFlexArraycopy constructor***********"); for(int i=0;idata[i]=src->data[i]; // (*this)[i]=src[i]; // a full stupid copy!! #ifdef FLEXARRAYDEBUG printf("****FlexArray copy constructor: Init with maxsize=%u size=%u data was = %lX\n", maxsize,size,data); #endif } template FlexArray &FlexArray::operator=(FlexArray &src){ if(this == &src) return *this; setSize(src.getSize()); //puts("\t\tFlexArraycopy operator"); for(int i=0;i int FlexArray::setSize(int s){ #ifdef FLEXARRAYDEBUG printf("****FlexArray.setSize(%u): Init with maxsize=%u size=%u data was = %lX\n", s,maxsize,size,data); #endif if(s<0) s=0; // make sure size isn't negative if(s<=maxsize){ size=s; #ifdef FLEXARRAYDEBUG printf("****FlexArray.setSize(%u): Changed to maxsize=%u size=%u data was = %lX\n", s,maxsize,size,data); #endif return size; // can't allow shrinkage below current size } // otherwise if >, then set array size to exactly requested size maxsize=s; T *newdata=new T[maxsize]; if(data){ for(int i=0;i int FlexArray::append(T value){ if(size>=maxsize) // failsafe check grow(size+1); // this array only increases in size data[size++]=value; return size; } template int FlexArray::append(T *values,int nvals){ if(size+nvals >= maxsize) grow(size+nvals);//this array only increases in size for(int i=0;i