📄 genarray.cpp
字号:
#include <assert.h>#include "genarray.h"#include <string.h>#include <limits.h>#pragma intrinsic memcpyenum{growby=20}; // grow this many elements at a timevoid * generic_ptr_array::operator [](int index){ if(index < 0 || index >= slotsused) return(0); return elements[index];}const void * generic_ptr_array::operator [](int index)const{ if(index < 0 || index >= slotsused) return(0); return elements[index];}void *& generic_ptr_array::element_ref(int index){ static void *vp; vp = 0; if(index < 0 || index >= slotsused) return(vp); return elements[index];}/* * Add a pointer to the array. * If necessary, allocate more store for the pointer array * and copy the elements. */void generic_ptr_array::operator +=(void *vp){ void **tvpp; if(slotsallocated == slotsused){ // grow the array slotsallocated += growby; tvpp = new void * [slotsallocated]; assert(tvpp);/* for (int i = 0; i < slotsused; i++) tvpp[i] = elements[i];*/ memcpy(tvpp, elements, slotsused*sizeof(tvpp[0])); delete elements; elements = tvpp; } elements[slotsused] = vp; slotsused++;}void generic_ptr_array::insert_before_element(int index, void *vp){ // make room if(index < 0 ) return; // if off the end, append .. if(index > slotsused) index = slotsused; // first, guarantee room at the end with a filthy trick operator += (0);/* void **evp = elements; for(int i = slotsused-1; i > index; i--) evp[i] = evp[i-1]; evp[index] = vp;*/ void **evp = &elements[slotsused-1]; for(int i = slotsused-1; i > index; i--, evp--) *evp = evp[-1]; *evp = vp;}// shuffle down elements// as ever, caller must have handled the delete of the zapped pointer// important to work with any valid element - last one is specialvoid *generic_ptr_array::delete_this_element(int index){ if(index < 0 || index >= slotsused) return 0; void *vp = elements[index]; if(index == slotsused-1){ // last one - nothing to shuffle down! delete_last_element(); return vp; } while(index < slotsused-1){ elements[index] = elements[index+1]; index++; } slotsused--; return vp;}// Nasty, inefficient sort (but it's small!)void generic_ptr_array::sort(sortdirection d, int (*cmp)(const void *, const void *)){ // A simple bubble sort is used - anything else is unlikely // to be a lot better const int upperbound = element_count(); const void **e = (const void **)elements; for(int i = 0; i < upperbound-1; i++){ for(int j = i+1; j < upperbound; j++){ const void *ei = e[i]; const void *ej = e[j]; if(cmp(ei , ej) == (d == up)){ // swap them e[i] = ej; e[j] = ei; } } }}#ifdef LARGEvoid dl_generic_list::insert_after(list_bucket *bp, void *vp){ list_bucket *lbp = new list_bucket; assert(lbp); lbp->itemp = vp; lbp->back = bp; lbp->forw = bp->forw; bp->forw = lbp; lbp->forw->back = lbp; nitems++;}void dl_generic_list::insert_before(list_bucket *bp, void *vp){ list_bucket *lbp = new list_bucket; assert(lbp); lbp->itemp = vp; lbp->forw = bp; lbp->back = bp->back; bp->back = lbp; lbp->back->forw = lbp; nitems++;}void dl_generic_list::unlink(list_bucket *bp){ bp->forw->back = bp->back; bp->back->forw = bp->forw; delete bp; nitems--;}dl_generic_list::dl_generic_list(){ list_head.forw = &list_head; list_head.back = &list_head; list_head.itemp = 0; // safety.. nitems = 0;}void *dl_generic_list::pop(){ if(nitems == 0) return 0; void *vp = list_head.forw->itemp; unlink(list_head.forw); return vp;}void * dl_generic_iterator::delete_this_element(){ void *vp = 0; if(at_end()) return 0; vp = lbp->itemp; dlp->unlink(lbp); return vp;}#endifsimplelistbase::simplelistbase(unsigned esize){ mysize = maxsofar = 0; mydata = 0; ele_size = esize;}simplelistbase::~simplelistbase(){ delete [] mydata;}void *simplelistbase::operator[](unsigned eno){ /* no more than 64K bytes, thank you */ if((unsigned long)eno * ele_size >= UINT_MAX) return 0; if(eno >= maxsofar){ // Time to grow if(((unsigned long)maxsofar + growby) * ele_size >= UINT_MAX) maxsofar = eno+1; else maxsofar += growby; // Might not have grown it enough! if(eno >= maxsofar) maxsofar = eno+1; unsigned newsize = maxsofar * ele_size; char *newp = new char[newsize]; assert(newp); memset(newp, 0, newsize); if(mysize){ memcpy(newp, mydata, mysize*ele_size); delete mydata; } mydata = newp; } if (eno >= mysize) mysize = eno+1; return (char *)mydata + (eno*ele_size);}void *simplelistbase::operator[](unsigned eno)const{ if (eno >= mysize) return 0; return (char *)mydata + (eno*ele_size);}void simplelistbase::initcopy(const simplelistbase &s){ ele_size = s.ele_size; mysize = s.mysize; maxsofar = s.maxsofar; mydata = new char[maxsofar*ele_size]; if(mysize) memcpy(mydata, s.mydata, mysize*ele_size);}void simplelistbase::operator =(const simplelistbase &rhs){ if(this == &rhs) return; delete mydata; initcopy(rhs);}simplelistbase::simplelistbase(const simplelistbase &rhs){ initcopy(rhs);}#ifdef USELINKEDLISTS///////////////////////////////////////////// Linked Lists ////////////////////////////////////linked_list_vpbase::linked_list_vpbase(){ listhead.forwp = &listhead; listhead.backp = &listhead; listhead.item = 0; // actually unused neles = 0;}void linked_list_vpbase::operator +=(void *vp){ list_bucket *lbp = new list_bucket; lbp->item = vp; lbp->forwp = &listhead; listhead.backp->forwp = lbp; lbp->backp = listhead.backp; listhead.backp = lbp; neles++;}const void *linked_list_vpbase::operator[](unsigned u)const{ const list_bucket *lbp = locate_ele(u); if(lbp == 0) return 0; return lbp->item;}void linked_list_vpbase::clear(){ while(listhead.forwp != &listhead){ list_bucket *todelete = listhead.forwp; listhead.forwp = listhead.forwp->forwp; delete todelete; } neles = 0; listhead.backp = &listhead;}void linked_list_vpbase::insert_before_element(unsigned idx, void *vp){ list_bucket *lbp = (list_bucket*)locate_ele(idx); if(lbp){ list_bucket *nbp = new list_bucket; nbp->item = vp; lbp->backp->forwp = nbp; nbp->forwp = lbp; nbp->backp = lbp->backp; lbp->backp = nbp; }}void linked_list_vpbase::delete_this_element(unsigned idx){ list_bucket *lbp = (list_bucket*)locate_ele(idx); if(lbp){ lbp->backp->forwp = lbp->forwp; lbp->forwp->backp = lbp->backp; delete lbp; }}const linked_list_vpbase::list_bucket *linked_list_vpbase::locate_ele(unsigned u)const{ if(u >= neles) return 0; list_bucket *lbp = listhead.forwp; while(u--){ lbp = lbp->forwp; } return lbp;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -