ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/gclib/gclib/GVec.hh
(Generate patch)
# Line 7 | Line 7
7   #define _GVec_HH
8  
9   #include "GBase.h"
10 //#include "assert.h"
10  
12 #ifdef __LINE__
13 #define GVEC_INDEX_ERR "GVec error (%s:%d):Invalid index: %d\n"
14 #define TEST_INDEX(x) \
15 if (x<0 || x>=fCount) GError(GVEC_INDEX_ERR, __FILE__,__LINE__, x)
16 #else
11   #define GVEC_INDEX_ERR "GVec error: invalid index: %d\n"
12 < #define TEST_INDEX(x) \
13 < if (x<0 || x>=fCount) GError(GVEC_INDEX_ERR, x, __FILE__,__LINE__)
12 > #if defined(NDEBUG) || defined(NODEBUG) || defined(_NDEBUG) || defined(NO_DEBUG)
13 > #define TEST_INDEX(x)
14 > #else
15 > #define TEST_INDEX(x) \
16 > if (x<0 || x>=fCount) GError(GVEC_INDEX_ERR, x)
17   #endif
18  
19   #define GVEC_CAPACITY_ERR "GVec error: invalid capacity: %d\n"
# Line 26 | Line 23
23  
24   #define FREEDATA (fFreeProc!=NULL)
25  
26 + template<class T> struct IsPrimitiveType {
27 +    enum { VAL = 0 };
28 + };
29 +
30 + template<> struct IsPrimitiveType<bool> { enum { VAL = 1 }; };
31 + template<> struct IsPrimitiveType<void*> { enum { VAL = 1 }; };
32 + template<> struct IsPrimitiveType<float> { enum { VAL = 1 }; };
33 + template<> struct IsPrimitiveType<double> { enum { VAL = 1 }; };
34 +
35 + template<> struct IsPrimitiveType<int> { enum { VAL = 1 }; };
36 + template<> struct IsPrimitiveType<unsigned int> { enum { VAL = 1 }; };
37 + template<> struct IsPrimitiveType<char> { enum { VAL = 1 }; };
38 + template<> struct IsPrimitiveType<unsigned char> { enum { VAL = 1 }; };
39 + template<> struct IsPrimitiveType<short> { enum { VAL = 1 }; };
40 + template<> struct IsPrimitiveType<unsigned short> { enum { VAL = 1 }; };
41 + template<> struct IsPrimitiveType<long> { enum { VAL = 1 }; };
42 + template<> struct IsPrimitiveType<unsigned long> { enum { VAL = 1 }; };
43 + template<> struct IsPrimitiveType<long long> { enum { VAL = 1 }; };
44 + template<> struct IsPrimitiveType<unsigned long long> { enum { VAL = 1 }; };
45 +
46 + /*
47 + template<> struct IsPrimitiveType<int64_t> { enum { VAL = 1 }; };
48 + template<> struct IsPrimitiveType<uint64_t> { enum { VAL = 1 }; };
49 + template<> struct IsPrimitiveType<int32_t> { enum { VAL = 1 }; };
50 + template<> struct IsPrimitiveType<uint32_t> { enum { VAL = 1 }; };
51 + template<> struct IsPrimitiveType<int16_t> { enum { VAL = 1 }; };
52 + template<> struct IsPrimitiveType<uint16_t> { enum { VAL = 1 }; };
53 + template<> struct IsPrimitiveType<int8_t> { enum { VAL = 1 }; };
54 + template<> struct IsPrimitiveType<uint8_t> { enum { VAL = 1 }; };
55 + */
56 +
57 +
58 + template <class OBJ> int DefLTCompareProc(const pointer p1, const pointer p2) {
59 + const OBJ& o1 = *((OBJ*) p1);
60 + const OBJ& o2 = *((OBJ*) p2);
61 + if (o1 < o2) return -1;
62 +   else return ((o2 < o1) ? 1 : 0 );
63 + }
64 +
65   //basic template for array of objects;
66   //so it doesn't require comparison operators to be defined
67   template <class OBJ> class GVec {
# Line 36 | Line 72
72      void qSort(int L, int R, GCompareProc* cmpFunc);
73    public:
74      GVec(int init_capacity=2);
75 +    GVec(int init_count, const OBJ init_val);
76      GVec(GVec<OBJ>& array); //copy constructor
77      const GVec<OBJ>& operator=(GVec<OBJ>& array); //copy operator
78      virtual ~GVec();
79 <    void idxInsert(int idx, OBJ& item);
79 >    void Insert(int idx, OBJ item) { Insert(idx, &item); }
80 >    void Insert(int idx, OBJ* item);
81 >    void idxInsert(int idx, OBJ& item) { Insert(idx, &item); }
82      void Grow();
83 <    void Grow(int idx, OBJ& item);
83 >    void Grow(int idx, OBJ& item); //grow and add/insert item copy
84      void Reverse(); //WARNING: will break the sort order if SORTED!
85      int Add(OBJ* item); // simply append to the end of fArray, reallocating as needed
86 <    int Add(OBJ& item) { return Add(&item); } //both will CREATE a new OBJ and COPY to it
87 <                       // using OBJ copy operator=
86 >    int Add(OBJ& item) { return Add(&item); }
87 >    int cAdd(OBJ item) { return Add(&item); } //all these will CREATE a new OBJ and COPY to it
88 >    //                   // using OBJ copy operator=
89      // -- stack/queue usage:
90      //int Push(OBJ& item) { return Add(&item); }
91      int Push(OBJ& item) { return Add(&item); }
92 +    int cPush(OBJ item) { return Add(&item); }
93      OBJ Pop();// Stack use; removes and returns a copy of the last item
94      OBJ Shift(); //Queue use: removes and returns a copy of the first item
95  
# Line 58 | Line 99
99            TEST_INDEX(idx);
100            return fArray[idx];
101            }
102 <    OBJ& operator[](int i) {
102 >    inline OBJ& operator[](int i) {
103            TEST_INDEX(i);
104            return fArray[i];
105            }
# Line 71 | Line 112
112           return fArray[0];
113           }
114      void Clear();
74    void Insert(int idx, OBJ* item);
115      void Delete(int index);
116      void Replace(int idx, OBJ& item); //Put, use operator= to copy
117      void Exchange(int idx1, int idx2);
# Line 82 | Line 122
122      int  Count() { return fCount; }
123  
124      void setCount(int NewCount);         // will trim or expand the array as needed
125 <    void setCount(int NewCount, OBJ& v); //same as setCount() but new objects are set to v
125 >    void setCount(int NewCount, OBJ* v); //same as setCount() but new objects are set to v
126 >    void setCount(int NewCount, OBJ v);
127      void Resize(int NewCount) { setCount(NewCount); }
128 <    void Resize(int NewCount, OBJ& v) { setCount(NewCount, v); }
128 >    //void Resize(int NewCount, OBJ* v) { setCount(NewCount, v); }
129 >    void Resize(int NewCount, OBJ v) { setCount(NewCount, &v); }
130  
131 <    void Move(int curidx, int newidx);
131 >    //void Move(int curidx, int newidx);
132      bool isEmpty() { return fCount==0; }
133      bool notEmpty() { return fCount>0; }
134  
135      void Sort(GCompareProc* cmpFunc);
136 +    void Sort();
137   };
138  
139   //---- template for dynamic array of object pointers
# Line 130 | Line 173
173      int Push(OBJ* item) { return Add(item); }
174      OBJ* Pop();// Stack use; removes and returns last item,but does NOT FREE it
175      OBJ* Shift(); //Queue use: removes and returns first item, but does NOT FREE it
176 <    void deallocate_item(OBJ* item); //forcefully call fFreeProc or delete on item
176 >    void deallocate_item(OBJ*& item); //forcefully call fFreeProc or delete on item
177      void Clear();
178      void Exchange(int idx1, int idx2);
179      void Swap(int idx1, int idx2)  { Exchange(idx1, idx2); }
# Line 153 | Line 196
196      int RemovePtr(pointer item); //always use linear search to find the pointer! calls Delete() if found
197      int IndexOf(pointer item); //a linear search for pointer address!
198      void Sort(GCompareProc* cmpFunc);
199 +    void Sort();
200   };
201  
202   //-------------------- TEMPLATE IMPLEMENTATION-------------------------------
# Line 164 | Line 208
208    setCapacity(init_capacity);
209   }
210  
211 +
212 + template <class OBJ> GVec<OBJ>::GVec(int init_count, const OBJ init_val) {
213 +  fCount=0;
214 +  fCapacity=0;
215 +  fArray=NULL;
216 +  setCapacity(init_count);
217 +  fCount = init_count;
218 +  for (int i=0;i<fCount;i++)
219 +    fArray[i]=init_val;
220 + }
221 +
222 +
223   template <class OBJ> GVec<OBJ>::GVec(GVec<OBJ>& array) { //copy constructor
224   this->fCount=array.fCount;
225   this->fCapacity=array.fCapacity;
226   this->fArray=NULL;
227   if (this->fCapacity>0) {
228 <    //GMALLOC(fArray, fCapacity*sizeof(OBJ));
229 <    fArray=new OBJ[this->fCapacity];
230 <    }
228 >   if (IsPrimitiveType<OBJ>::VAL) {
229 >     GMALLOC(fArray, fCapacity*sizeof(OBJ));
230 >     memcpy(fArray, array.fArray, fCount*sizeof(OBJ));
231 >   }
232 >   else {
233 >     fArray=new OBJ[this->fCapacity]; //]()
234 >     // uses OBJ operator=
235 >     for (int i=0;i<this->fCount;i++) fArray[i]=array[i];
236 >   }
237 > }
238   this->fCount=array.fCount;
176 // uses OBJ operator=
177 for (int i=0;i<this->fCount;i++) fArray[i]=array[i];
239   }
240  
241   template <class OBJ> const GVec<OBJ>& GVec<OBJ>::operator=(GVec<OBJ>& array) {
242   if (&array==this) return *this;
243   Clear();
183 fCount=array.fCount;
244   fCapacity=array.fCapacity;
245 + fCount=array.fCount;
246   if (fCapacity>0) {
247 <    //GMALLOC(fArray, fCapacity*sizeof(OBJ));
248 <    fArray=new OBJ[this->fCapacity];
247 >   if (IsPrimitiveType<OBJ>::VAL) {
248 >     GMALLOC(fArray, fCapacity*sizeof(OBJ));
249 >     memcpy(fArray, array.fArray, fCount*sizeof(OBJ));
250 >     }
251 >   else {
252 >    fArray=new OBJ[this->fCapacity]; // ]()
253 >    // uses OBJ operator=
254 >    for (int i=0;i<fCount;i++) {
255 >      fArray[i]=array.fArray[i];
256      }
189 fCount=array.fCount;
190 // uses OBJ operator=
191 for (int i=0;i<fCount;i++) {
192   fArray[i]=array[i];
257     }
258 + }
259   return *this;
260   }
261  
# Line 202 | Line 267
267   template <class OBJ> void GVec<OBJ>::setCapacity(int NewCapacity) {
268    if (NewCapacity < fCount || NewCapacity > MAXLISTSIZE)
269      GError(GVEC_CAPACITY_ERR, NewCapacity);
270 <    //error: capacity not within range
270 >    //error: NewCapacity MUST be > fCount
271     //if you want to shrink it use Resize() or setCount()
272    if (NewCapacity!=fCapacity) {
273     if (NewCapacity==0) {
274 <      delete[] fArray;
274 >      if (IsPrimitiveType<OBJ>::VAL) {
275 >       GFREE(fArray);
276 >      } else {
277 >       delete[] fArray;
278 >       fArray=NULL;
279        }
280 <    else {
281 <      //GREALLOC(fArray, NewCapacity*sizeof(OBJ));
282 <      OBJ* oldArray=fArray;
283 <      fArray=new OBJ[NewCapacity];
284 <      for (int i=0;i<this->fCount;i++) {
285 <        fArray[i] = oldArray[i]; // operator=
286 <        }
287 <      delete[] oldArray;
280 >   }
281 >   else {
282 >      if (IsPrimitiveType<OBJ>::VAL) {
283 >        GREALLOC(fArray, NewCapacity*sizeof(OBJ));
284 >      } else {
285 >        OBJ* oldArray=fArray;
286 >                //fArray=new OBJ[NewCapacity]();
287 >                fArray=new OBJ[NewCapacity];
288 >        for (int i=0;i<this->fCount;i++) {
289 >          fArray[i] = oldArray[i];
290 >          }// we need operator= here
291 >        //wouldn't be faster to use memcpy instead?
292 >        //memcpy(fArray, oldArray, fCount*sizeof(OBJ));
293 >        if (oldArray) delete[] oldArray;
294        }
220   fCapacity=NewCapacity;
295     }
296 +  fCapacity=NewCapacity;
297 +  }
298   }
299  
300   template <class OBJ> void GVec<OBJ>::Clear() {
301 <  setCount(0);
302 <  setCapacity(0); //so the array itself is deallocated too!
301 >  fCount=0;
302 >  if (IsPrimitiveType<OBJ>::VAL) {
303 >    GFREE(fArray);
304 >  }
305 >  else {
306 >    delete[] fArray;
307 >    fArray=NULL;
308 >  }
309 >  fCapacity=0;
310   }
311  
312   template <class OBJ> void GVec<OBJ>::Grow() {
313 < int delta;
231 < if (fCapacity > 64 ) {
232 <   delta = (fCapacity > 0xFFF) ? 0x100 : (fCapacity>>4);
233 < }
234 < else {
235 <   delta = (fCapacity>8) ? (fCapacity>>2) : 1 ;
236 < }
313 > int delta = (fCapacity>8) ? (fCapacity>>2) : 1 ;
314   setCapacity(fCapacity + delta);
315   }
316  
# Line 249 | Line 326
326   }
327  
328   template <class OBJ> void GVec<OBJ>::Grow(int idx, OBJ& item) {
329 < int delta;
253 < /*
254 < if (fCapacity > 64) delta = fCapacity/4;
255 <   else if (fCapacity > 8) delta = 16;
256 <                      else delta = 4;
257 < */
258 < if (fCapacity > 64 ) {
259 <   delta = (fCapacity > 0xFFF) ? 0x100 : (fCapacity>>4);
260 < }
261 < else {
262 <   delta = (fCapacity>8) ? (fCapacity>>2) : 1 ;
263 < }
329 > int delta = (fCapacity>8) ? (fCapacity>>2) : 1 ;
330   int NewCapacity=fCapacity+delta;
331 <  if (NewCapacity <= fCount || NewCapacity >= MAXLISTSIZE)
331 > if (NewCapacity <= fCount || NewCapacity >= MAXLISTSIZE)
332      GError(GVEC_CAPACITY_ERR, NewCapacity);
333      //error: capacity not within range
334 <
335 <  if (NewCapacity!=fCapacity) {
270 <    if (NewCapacity==0) {
271 <      //GFREE(fArray);
272 <      delete[] fArray;
273 <      fArray=NULL;
274 <      }
275 <    else { //add the new item
276 <      if (idx==fCount) { //append item
334 > //if (NewCapacity!=fCapacity) {
335 > if (idx==fCount) { //append item
336           //GREALLOC(fArray, NewCapacity*sizeof(OBJ));
337           setCapacity(NewCapacity);
338           fArray[idx]=item;
339 <         }
340 <       else { //insert item at idx
341 <        OBJ* newList;
342 <        //GMALLOC(newList, NewCapacity*sizeof(OBJ));
343 <        newList=new OBJ[NewCapacity];
339 > }
340 > else { //insert item at idx
341 >   OBJ* newList;
342 >   if (IsPrimitiveType<OBJ>::VAL) {
343 >        GMALLOC(newList, NewCapacity*sizeof(OBJ));
344          //copy data before idx
345 <        //memmove(&newList[0],&fArray[0], idx*sizeof(OBJ));
345 >        memcpy(&newList[0],&fArray[0], idx*sizeof(OBJ));
346 >        newList[idx]=item;
347 >        //copy data after idx
348 >        memmove(&newList[idx+1],&fArray[idx], (fCount-idx)*sizeof(OBJ));
349 >        //..shouldn't do this:
350 >        memset(&newList[fCount+1], 0, (NewCapacity-fCount-1)*sizeof(OBJ));
351 >        //data copied:
352 >        GFREE(fArray);
353 >   } else {
354 >        newList=new OBJ[NewCapacity]; //]()
355          // operator= required!
356          for (int i=0;i<idx;i++) {
357            newList[i]=fArray[i];
# Line 294 | Line 362
362          for (int i=idx+1;i<=fCount;i++) {
363            newList[i]=fArray[i-1];
364            }
297        //memset(&newList[fCount+1], 0, (NewCapacity-fCount-1)*sizeof(OBJ));
298        //data copied:
299        //GFREE(fArray);
365          delete[] fArray;
301        fArray=newList;
302        }
303      fCount++;
304      }
305   fCapacity=NewCapacity;
366     }
367 +   fArray=newList;
368 +   fCapacity=NewCapacity;
369 + }
370 + fCount++;
371   }
308
309
372   template <class OBJ> int GVec<OBJ>::Add(OBJ* item) {
373   if (item==NULL) return -1;
374   if (fCount==fCapacity) Grow();
# Line 320 | Line 382
382    if (list.Count()==0) return;
383    //simply copy
384    setCapacity(fCapacity+list.fCount);
385 <  int s=fCount;
386 <  for (int i=0;i<list.fCount;i++)
387 <           fArray[s+i]=list.fArray[i];
385 >  if (IsPrimitiveType<OBJ>::VAL) {
386 >    memcpy( &fArray[fCount], list.fArray, list.fCount*sizeof(OBJ));
387 >    }
388 >   else {
389 >    for (int i=0;i<list.fCount;i++)
390 >          fArray[fCount+i]=list.fArray[i];
391 >    }
392    fCount+=list.fCount;
393   }
394  
329
395   //Stack usage:
396   template <class OBJ> OBJ GVec<OBJ>::Pop() {
397   if (fCount<=0) GError("Error: invalid GVec::Pop() operation!\n");
# Line 334 | Line 399
399   //OBJ o(fArray[fCount]); //copy constructor
400   //o=fList[fCount];
401   //fArray[fCount]=NULL;
402 < return fArray[fCount]; //copy of the last element
402 > return fArray[fCount]; //copy of the last element (copy constructor called)
403   }
404  
405   //Queue usage:
# Line 348 | Line 413
413   return o;
414   }
415  
416 < template <class OBJ> void GVec<OBJ>::idxInsert(int idx, OBJ& item) {
416 > template <class OBJ> void GVec<OBJ>::Insert(int idx, OBJ* item) {
417   //idx must be the new position this new item must have
418   //so the allowed range is [0..fCount]
419   //the old idx item all the above will be shifted to idx+1
420   if (idx<0 || idx>fCount) GError(GVEC_INDEX_ERR, idx);
421   if (fCount==fCapacity) { //need to resize the array
422 <    Grow(idx, item); //expand and also copy/move data and insert the new item
422 >    Grow(idx, *item); //expand and also copy/move data and insert the new item
423      return;
424      }
425   //move data around to make room for the new item
426   if (idx<fCount) {
427 <      //copy after-idx items (shift up)
428 <      //memmove(&newList[idx+1],&fArray[idx], (fCount-idx)*sizeof(OBJ));
427 >   //copy after-idx items (shift up)
428 >   if (IsPrimitiveType<OBJ>::VAL) {      
429 >      memmove(&fArray[idx+1],&fArray[idx], (fCount-idx)*sizeof(OBJ));
430 >   }
431 >   else {
432        for (int i=fCount; i>idx; i--) {
433            fArray[i]=fArray[i-1];
434            }
435 <      }
436 < fArray[idx]=item;
435 >   }
436 > }
437 > fArray[idx]=*item;
438   fCount++;
439   }
440  
372 template <class OBJ> void GVec<OBJ>::Insert(int idx, OBJ* item) {
373 //idx can be [0..fCount] so an item can be actually added
374 idxInsert(idx, item);
375 }
376
441  
442 < template <class OBJ> void GVec<OBJ>::Move(int curidx, int newidx) {
442 > /*template <class OBJ> void GVec<OBJ>::Move(int curidx, int newidx) { //swap
443   if (curidx!=newidx || newidx>=fCount)
444       GError(GVEC_INDEX_ERR, newidx);
445   OBJ tmp=fArray[curidx]; //copy constructor here
446   fArray[curidx]=fArray[newidx];
447   fArray[newidx]=tmp;
448 < }
448 > }*/
449  
450  
451   template <class OBJ> void GVec<OBJ>::Replace(int idx, OBJ& item) {
# Line 401 | Line 465
465   template <class OBJ> void GVec<OBJ>::Delete(int index) {
466   TEST_INDEX(index);
467   fCount--;
468 < while (index<fCount) {
468 > if (IsPrimitiveType<OBJ>::VAL) {
469 >   if (index<fCount)
470      //move higher elements if any (shift down)
471 <    //memmove(&fArray[index], &fArray[index+1], (fCount-index)*sizeof(OBJ));
472 <    fArray[index]=fArray[index+1];
473 <    index++;
474 <    }
471 >      memmove(&fArray[index], &fArray[index+1], (fCount-index)*sizeof(OBJ));
472 >   }
473 > else {
474 >   while (index<fCount) {
475 >      fArray[index]=fArray[index+1];
476 >      index++;
477 >      }
478 >  }
479   }
480  
481   template <class OBJ> void GVec<OBJ>::setCount(int NewCount) {
482 <  if (NewCount<0 || NewCount > MAXLISTSIZE)
483 <     GError(GVEC_COUNT_ERR, NewCount);
484 <  if (NewCount > fCapacity) setCapacity(NewCount);
485 <  fCount = NewCount;
486 < }
487 <
488 < template <class OBJ> void GVec<OBJ>::setCount(int NewCount, OBJ& v) {
489 <  if (NewCount<0 || NewCount > MAXLISTSIZE)
490 <     GError(GVEC_COUNT_ERR, NewCount);
491 <  if (NewCount > fCapacity) setCapacity(NewCount);
492 <  if (NewCount>fCount) {
493 <        for (int i=fCount;i<NewCount;i++)
494 <           fArray[i]=v;
495 <  }
496 <  fCount = NewCount;
482 >        if (NewCount<0 || NewCount > MAXLISTSIZE)
483 >           GError(GVEC_COUNT_ERR, NewCount);
484 >        //if (NewCount > fCapacity) setCapacity(NewCount);
485 >        while(NewCount > fCapacity) Grow();
486 >        fCount = NewCount; //new items will be populated by the default object constructor(!)
487 > }
488 >
489 > template <class OBJ> void GVec<OBJ>::setCount(int NewCount, OBJ* v) {
490 >        if (NewCount<0 || NewCount > MAXLISTSIZE)
491 >          GError(GVEC_COUNT_ERR, NewCount);
492 >        while (NewCount > fCapacity) Grow();
493 >        if (NewCount>fCount) {
494 >                for (int i=fCount;i<NewCount;i++)
495 >                  fArray[i]=*v;
496 >        }
497 >        fCount = NewCount;
498 > }
499 >
500 > template <class OBJ> void GVec<OBJ>::setCount(int NewCount, OBJ v) {
501 >        if (NewCount<0 || NewCount > MAXLISTSIZE)
502 >           GError(GVEC_COUNT_ERR, NewCount);
503 >        while (NewCount > fCapacity) Grow();
504 >        if (NewCount>fCount) {
505 >                for (int i=fCount;i<NewCount;i++)
506 >                  fArray[i]=v;
507 >        }
508 >        fCount = NewCount;
509   }
510  
511  
# Line 450 | Line 531
531   }
532  
533   template <class OBJ> void GVec<OBJ>::Sort(GCompareProc* cmpFunc) {
534 < if (this->fArray!=NULL && this->fCount>0 && cmpFunc!=NULL)
534 > if (cmpFunc==NULL) {
535 >   GMessage("Warning: NULL compare function given, useless Sort() call.\n");
536 >   return;
537 > }
538 > if (this->fArray!=NULL && this->fCount>0)
539       qSort(0, this->fCount-1, cmpFunc);
540   }
541  
542 + template <class OBJ> void GVec<OBJ>::Sort() {  
543 +  GCompareProc* cmpFunc = DefLTCompareProc<OBJ>;
544 +  Sort(cmpFunc);
545 + }
546 +
547  
548   //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
549   //*=> GPVec implementation
# Line 461 | Line 551
551   template <class OBJ> GPVec<OBJ>::GPVec(GPVec& list) { //copy constructor
552   fCount=list.fCount;
553   fCapacity=list.fCapacity;
554 + fList=NULL;
555   if (fCapacity>0) {
556        GMALLOC(fList, fCapacity*sizeof(OBJ*));
557        }
# Line 489 | Line 580
580       fFreeProc=list.fFreeProc;
581       //Attention: the object *POINTERS* are copied,
582       // but the actual object content is NOT duplicated
583 <     for (int i=0;i<list.Count();i++) Add(list[i]);
583 >     //for (int i=0;i<list.Count();i++) Add(list[i]);
584 >     fCount=list.fCount;
585 >     GMALLOC(fList, fCapacity*sizeof(OBJ*));
586 >     memcpy(fList, list.fList, fCount*sizeof(OBJ*));
587       }
588   return *this;
589   }
# Line 549 | Line 643
643     }
644   }
645  
646 < template <class OBJ> void GPVec<OBJ>::deallocate_item(OBJ* item) {
646 > template <class OBJ> void GPVec<OBJ>::deallocate_item(OBJ* &item) {
647   if (item==NULL) return;
648   if (FREEDATA) {
649     (*fFreeProc)(item);
650 +   item=NULL;
651     }
652   else {
653    delete item;
654 +  item=NULL;
655    }
656   }
657  
# Line 565 | Line 661
661       (*fFreeProc)(fList[i]);
662       }
663     }
664 < setCount(0);
665 < setCapacity(0); //so the array itself is deallocated too!
664 > GFREE(fList);
665 > fCount=0;
666 > fCapacity=0;
667   }
668  
669   template <class OBJ> void GPVec<OBJ>::Exchange(int idx1, int idx2) {
# Line 588 | Line 685
685   }
686  
687   template <class OBJ> void GPVec<OBJ>::Grow() {
688 + /*
689   int delta;
690   if (fCapacity > 64 ) {
691     delta = (fCapacity > 0xFFF) ? 0x100 : (fCapacity>>4);
# Line 595 | Line 693
693   else {
694     delta = (fCapacity>8) ? (fCapacity>>2) : 1 ;
695   }
696 <  setCapacity(fCapacity + delta);
696 > */
697 >        int delta = (fCapacity>8) ? (fCapacity>>2) : 1;
698 >        setCapacity(fCapacity + delta);
699   }
700  
701   template <class OBJ> void GPVec<OBJ>::Grow(int idx, OBJ* newitem) {
702 + /*
703   int delta;
704   if (fCapacity > 64 ) {
705     delta = (fCapacity > 0xFFF) ? 0x100 : (fCapacity>>4);
# Line 606 | Line 707
707   else {
708     delta = (fCapacity>8) ? (fCapacity>>2) : 1 ;
709   }
710 < // setCapacity(fCapacity + delta);
710 > */
711 > int delta = (fCapacity>8) ? (fCapacity>>2) : 1 ;
712   int NewCapacity=fCapacity+delta;
713 <  if (NewCapacity <= fCount || NewCapacity > MAXLISTSIZE)
713 > if (NewCapacity <= fCount || NewCapacity > MAXLISTSIZE)
714      GError(GVEC_CAPACITY_ERR, NewCapacity);
715      //error: capacity not within range
716 <  if (NewCapacity!=fCapacity) {
717 <    if (NewCapacity==0) {
716 > //if (NewCapacity!=fCapacity) {
717 > /*if (NewCapacity==0) {
718        GFREE(fList);
719 <      }
720 <    else  {//add the new item
721 <      if (idx==fCount) {
722 <         GREALLOC(fList, NewCapacity*sizeof(OBJ*));
723 <         fList[idx]=newitem;
724 <         }
725 <       else {
726 <        OBJ** newList;
727 <        GMALLOC(newList, NewCapacity*sizeof(OBJ*));
728 <        //copy data before idx
729 <        memmove(&newList[0],&fList[0], idx*sizeof(OBJ*));
730 <        newList[idx]=newitem;
731 <        //copy data after idx
732 <        memmove(&newList[idx+1],&fList[idx], (fCount-idx)*sizeof(OBJ*));
733 <        memset(&newList[fCount+1], 0, (NewCapacity-fCount-1)*sizeof(OBJ*));
734 <        //data copied:
735 <        GFREE(fList);
736 <        fList=newList;
737 <        }
636 <      fCount++;
637 <      }
638 <   fCapacity=NewCapacity;
719 > }
720 > else  {//add the new item
721 > */
722 > if (idx==fCount) {
723 >    GREALLOC(fList, NewCapacity*sizeof(OBJ*));
724 >    fList[idx]=newitem;
725 >    }
726 > else {
727 >   OBJ** newList;
728 >   GMALLOC(newList, NewCapacity*sizeof(OBJ*));
729 >   //copy data before idx
730 >   memcpy(&newList[0],&fList[0], idx*sizeof(OBJ*));
731 >   newList[idx]=newitem;
732 >   //copy data after idx
733 >   memmove(&newList[idx+1],&fList[idx], (fCount-idx)*sizeof(OBJ*));
734 >   memset(&newList[fCount+1], 0, (NewCapacity-fCount-1)*sizeof(OBJ*));
735 >   //data copied:
736 >   GFREE(fList);
737 >   fList=newList;
738     }
739 + fCount++;
740 + fCapacity=NewCapacity;
741   }
742  
743   template <class OBJ> int GPVec<OBJ>::IndexOf(pointer item) {
# Line 670 | Line 771
771   fCount++;
772   }
773  
774 < template <class OBJ> void GPVec<OBJ>::Move(int curidx, int newidx) {
774 > template <class OBJ> void GPVec<OBJ>::Move(int curidx, int newidx) { //s
775   //BE_UNSORTED; //cannot do that in a sorted list!
776   if (curidx!=newidx || newidx>=fCount)
777       GError(GVEC_INDEX_ERR, newidx);
# Line 787 | Line 888
888   }
889  
890   template <class OBJ> void GPVec<OBJ>::Sort(GCompareProc* cmpFunc) {
891 < if (this->fList!=NULL && this->fCount>0 && cmpFunc!=NULL)
891 > if (cmpFunc==NULL) {
892 >    GMessage("Warning: NULL compare function given, useless Sort() call.\n");
893 >    return;
894 >    }
895 > if (this->fList!=NULL && this->fCount>0)
896       qSort(0, this->fCount-1, cmpFunc);
897   }
898  
899 +
900 + template <class OBJ> void GPVec<OBJ>::Sort() {
901 +  GCompareProc* cmpFunc = DefLTCompareProc<OBJ>;
902 +  Sort(cmpFunc);
903 + }
904 +
905 +
906   //---------------------------------------------------------------------------
907   #endif

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines