// 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 /*------------- 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 index){ if(index>=size || index<0) { // range check printf("FlexArray:: Bad index. Arraysize=%u Index=%u\n", size,index); index=0; } return (data[index]); } #else inline T &operator[](int index){ return (data[index]); } #endif // purge? which forces array delete inline void purge(){ delete[] data; 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; } template FlexArray::~FlexArray(){ if(maxsize>0 && data) delete[] data; size=maxsize=0; data=0; } template void FlexArray::grow(int targetSize){ 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!! } 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){ if(ss>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