_A VIRTUAL-ARRAY CLASS USING C++ TEMPLATES_ by Douglas Reilly [LISTING ONE] #ifdef __cplusplus #ifndef VIRTARRA_H #define VIRTARRA_H template class virtArray { private: int initialized; unsigned long cacheStart; unsigned long curEl; unsigned long numEls; size_t size; tfile *tempFile; T data[cacheSize]; void put(unsigned long i); void get(unsigned long i); public: virtArray(unsigned long tnumEls,T *defVal=0); ~virtArray(); T& operator [](unsigned long i); T& current() { return operator [](curEl); }; T& next() { if ( (curEl+1L virtArray::virtArray(unsigned long tnumEls,T *defVal) { if ( tnumEls ) { unsigned long totsize; char *tptr; initialized=1; tempFile=new tfile; numEls=tnumEls; curEl=0L; size=(sizeof(T)); totsize=numEls*(long)size; // no default value. Just set everything to NULLS if ( defVal==0 ) { memset(&data,EOS,size); totsize=numEls*(long)size; int grain=20480; tptr=new char[grain]; if ( tptr==0 ) { if ( tptr==0 ) { grain=10240; tptr=new char[grain]; if ( tptr==0 ) { grain=2048; tptr=new char[grain]; } if ( tptr==0 ) { initialized=0; delete tempFile; return; } } } memset(tptr,EOS,grain); while ( totsize>grain && !(tempFile->getErrno()) ) { tempFile->write(tptr,grain); totsize-=grain; } if ( totsize && !(tempFile->getErrno()) ) { tempFile->write(tptr,totsize); } delete tptr; if ( tempFile->getErrno() ) { delete tempFile; initialized=0; } } else { // Use the default value sent to constructor memcpy(&data,defVal,size); for ( unsigned long loop=0L ; loopgetErrno()==0 ; loop++ ) { tempFile->write(&data,size); } if ( tempFile->getErrno() ) { delete tempFile; initialized=0; } } cacheStart=0L; get(0L); } } template virtArray::~virtArray() { if ( initialized ) { delete tempFile; initialized=0; } } template T& virtArray::operator [](unsigned long i) { // cause reads past end to result in element 0 if ( i>numEls ) { i=0L; } if ( i>=cacheStart && i<(cacheStart+(unsigned long)cacheSize) ) { curEl=i; return(data[i-cacheStart]); } else { put(cacheStart); cacheStart=i; get(i); curEl=i; cacheStart=curEl; return(data[0]); } } template void virtArray::put(unsigned long i) { if ( iseek(i*(long)size); if ( (i+putSize)>numEls ) { putSize=(numEls-i); } tempFile->write(&data[0],putSize*size); } } template void virtArray::get(unsigned long i) { if ( iseek(i*(long)size); if ( (i+getSize)>numEls ) { getSize=(numEls-i); } tempFile->read(&data[0],getSize*size); } } // Use this function to do the something like a memset()... template void virtArray::nullOut() { char *tptr; unsigned long totsize; memset(&data,EOS,size); totsize=numEls*(long)size; int grain=20480; tptr=new char[grain]; if ( tptr==0 ) { if ( tptr==0 ) { grain=10240; tptr=new char[grain]; if ( tptr==0 ) { grain=2048; tptr=new char[grain]; } if ( tptr==0 ) { grain=512; tptr=new char[grain]; } } } memset(tptr,EOS,grain); while ( totsize>grain && !(tempFile->getErrno()) ) { tempFile->write(tptr,grain); totsize-=grain; } if ( totsize && !(tempFile->getErrno()) ) { tempFile->write(tptr,totsize); } delete tptr; get(curEl); return; } // allow the array to grow template void virtArray::grow(unsigned long numToAdd) { unsigned long bytesToAdd=0L; unsigned int grain=10240; char *tptr; bytesToAdd=numToAdd*(long)size; for ( tptr=0,grain=10240 ; grain!=0 ; ) { tptr=new char[grain]; if ( tptr==0 ) { grain-=2048; } } if ( grain!=0 && tptr!=0 ) { tempFile->seek(0L,SEEK_END); while ( bytesToAdd>grain && !(tempFile->getErrno()) ) { tempFile->write(tptr,grain); bytesToAdd-=grain; } if ( bytesToAdd && !(tempFile->getErrno()) ) { tempFile->write(tptr,bytesToAdd); } delete tptr; numEls+=numToAdd; } }