1 //---------------------------------------------------------------------------
2 /*
3 Sortable collections of objects and object pointers
4 */
5 #ifndef _GList_HH
6 #define _GList_HH
7
8 #include "GVec.hh"
9
10 #define GLIST_SORTED_ERR "Operation not allowed on a sorted list!\n"
11 #define GLIST_UNSORTED_ERR "Operation not allowed on an unsorted list!\n"
12
13 //------ useful macros:
14 #define BE_UNSORTED if (fCompareProc!=NULL) { GError(GLIST_SORTED_ERR); return; }
15 #define BE_SORTED if (fCompareProc==NULL) { GError(GLIST_UNSORTED_ERR); return; }
16
17 #define SORTED (fCompareProc!=NULL)
18 #define UNSORTED (fCompareProc==NULL)
19
20 // GArray is the sortable array type, requires the comparison operator < to be defined
21 template <class OBJ> class GArray:public GVec<OBJ> {
22 protected:
23 bool fUnique;
DefaultCompareProc(const pointer item1,const pointer item2)24 static int DefaultCompareProc(const pointer item1, const pointer item2) {
25 //operator< MUST be defined for OBJ class!
26 if (*((OBJ*)item2) < *((OBJ*)item1)) return 1;
27 else if (*((OBJ*)item1) < *((OBJ*)item2)) return -1;
28 else return 0;
29 }
30 GCompareProc* fCompareProc;
31 public:
32 GArray(GCompareProc* cmpFunc=NULL);
33 GArray(bool sorted, bool unique=false);
34 GArray(int init_capacity, bool sorted, bool unique=false);
35 GArray(GArray<OBJ>& array); //copy constructor
36 const GArray<OBJ>& operator=(GArray<OBJ>& array);
37 //~GArray();
38 //assignment operator
39 void setSorted(GCompareProc* cmpFunc);
setSorted(bool sorted)40 void setSorted(bool sorted) {
41 if (sorted) {
42 if (fCompareProc!=&DefaultCompareProc) {
43 fCompareProc=&DefaultCompareProc;
44 Sort();
45 }
46 }
47 else fCompareProc=NULL;
48 }
49 //sort the array if cmpFunc not NULL or changes
50 int Add(OBJ* item); // specific implementation if sorted
Add(OBJ & item)51 int Add(OBJ& item) { return Add(&item); } //both will CREATE a new OBJ and COPY to it
52 // using OBJ new operator=
cAdd(OBJ item)53 int cAdd(OBJ item) { return Add(&item); }
cPush(OBJ item)54 int cPush(OBJ item) { return Add(&item); }
Push(OBJ & item)55 int Push(OBJ& item) { return Add(&item); }
56
57 void Add(GArray<OBJ>& list); //add copies of all items from another list
58 //this will reject identical items in sorted lists only!
setUnique(bool beUnique)59 void setUnique(bool beUnique) { fUnique = beUnique; };
60 void Sort(); //explicit sort may be requested
Sorted()61 bool Sorted() { return fCompareProc!=NULL; }
62 void Replace(int idx, OBJ& item); //Put, use operator= to copy
Unique()63 int Unique() { return fUnique; }
64 int IndexOf(OBJ& item);
65 //this needs the == operator to have been defined for OBJ
66 bool Found(OBJ& item, int& idx); // for sorted arrays only;
67 //search by content; if found, returns true and idx will be the index
68 //of the first item found matching for which fCompareProc returns 0
69 bool Exists(OBJ& item); //same as above without existing index info
70 //unsorted only, place item at position idx:
71 void Move(int curidx, int newidx);
72 void Insert(int idx, OBJ* item);
Insert(int idx,OBJ item)73 void Insert(int idx, OBJ item) { Insert(idx,&item); }
74 };
75
76 //GList is a sortable collection of pointers to objects; requires operator< to be defined, or a custom compare function
77 template <class OBJ> class GList:public GPVec<OBJ> {
78 protected:
79 bool fUnique;
80 GCompareProc* fCompareProc; //a pointer to a Compare function
81
DefaultCompareProc(const pointer item1,const pointer item2)82 static int DefaultCompareProc(const pointer item1, const pointer item2) {
83 //operator< MUST be defined for OBJ class!
84 if (*((OBJ*)item2) < *((OBJ*)item1)) return 1;
85 else if (*((OBJ*)item1) < *((OBJ*)item2)) return -1;
86 else return 0;
87 }
88 public:
89 void sortInsert(int idx, OBJ* item); //special insert in sorted lists
90 //WARNING: the caller must know the insert index such that the sort order is preserved!
91 GList(GCompareProc* compareProc=NULL); //free by default
92 GList(GCompareProc* compareProc, //unsorted by default
93 GFreeProc *freeProc,
94 bool beUnique=false);
95 GList(bool sorted, bool free_elements=true, bool beUnique=false);
96 GList(int init_capacity, bool sorted, bool free_elements=true, bool beUnique=false);
97 GList(GList<OBJ>& list); //copy constructor?
98 GList(GList<OBJ>* list); //kind of a copy constructor
99 const GList<OBJ>& operator=(GList<OBJ>& list);
100 //void Clear();
101 //~GList();
102 void setSorted(GCompareProc* compareProc);
103 //sorted if compareProc not NULL; sort the list if compareProc changes !
Sorted()104 bool Sorted() { return fCompareProc!=NULL; }
setSorted(bool sorted)105 void setSorted(bool sorted) {
106 if (sorted) {
107 if (fCompareProc!=&DefaultCompareProc) {
108 fCompareProc=&DefaultCompareProc;
109 Sort();
110 }
111 }
112 else fCompareProc=NULL;
113 }
114 int Add(OBJ* item); //-- specific implementation if sorted - may become an Insert()
115 void Add(GList<OBJ>& list); //add all pointers from another list
116
117 OBJ* AddIfNew(OBJ* item, bool deleteIfFound=true, int* fidx=NULL);
118 // default: delete item if Found() (and pointers are not equal)!
119 //returns the equal (==) object if it's in the list already
120 //or the item itself if it is unique and actually added
121
122 int AddedIfNew(OBJ* item);
123 // if Found(item) (and pointers are not equal) delete item and returns -1
124 // if added, returns the new item index
125
126
Unique()127 int Unique() { return fUnique; }
128 //this will reject identical items in sorted lists only!
setUnique(bool beUnique)129 void setUnique(bool beUnique) { fUnique = beUnique; };
130
GetCompareProc()131 GCompareProc* GetCompareProc() {return fCompareProc;}
132 int IndexOf(OBJ* item); //this has a specific implementation for sorted lists
133 //if list is sorted, item data is located by binary search
134 //based on the Compare function
135 //if not, a linear search is performed, but
136 //this needs the == operator to have been defined for OBJ
137
138 void Put(int idx, OBJ* item, bool re_sort=false);
139 bool Found(OBJ* item, int & idx); // sorted only;
140 //search by content; if found, returns true and idx will be the index
141 //of the first item found matching for which GTCompareProc returns 0
142 bool Exists(OBJ* item); //same as above without existing index info
143 bool Exists(OBJ& item); //same as above without existing index info
144 void Sort(); //explicit sort may be requested using this function
145 int Remove(OBJ* item); //search for pointer, using binary search if sorted
146 void Insert(int idx, OBJ* item); //unsorted only, place item at position idx
147 void Move(int curidx, int newidx);
148 }; //GList
149
150
151
152 //-------------------- TEMPLATE IMPLEMENTATION-------------------------------
153
GArray(GArray<OBJ> & array)154 template <class OBJ> GArray<OBJ>::GArray(GArray<OBJ>& array):GVec<OBJ>(0) { //copy constructor
155 this->fCount=array.fCount;
156 this->fCapacity=array.fCapacity;
157 this->fArray=NULL;
158 if (this->fCapacity>0) {
159 //GMALLOC(this->fArray, this->fCapacity*sizeof(OBJ));
160 this->fArray=new OBJ[this->fCapacity];
161 }
162 this->fCount=array.fCount;
163 fUnique=array.fUnique;
164 fCompareProc=array.fCompareProc;
165 // uses OBJ operator=
166 for (int i=0;i<this->fCount;i++) this->fArray[i]=array[i];
167 }
168
operator =(GArray<OBJ> & array)169 template <class OBJ> const GArray<OBJ>& GArray<OBJ>::operator=(GArray<OBJ>& array) {
170 if (&array==this) return *this;
171 GVec<OBJ>::Clear();
172 this->fCount=array.fCount;
173 this->fUnique=array.fUnique;
174 this->fCapacity=array.fCapacity;
175 if (this->fCapacity>0) {
176 //GMALLOC(this->fArray, this->fCapacity*sizeof(OBJ));
177 this->fArray=new OBJ[this->fCapacity];
178 }
179 this->fCompareProc=array.fCompareProc;
180 this->fCount=array.fCount;
181 // uses OBJ operator=
182 for (int i=0;i<this->fCount;i++) {
183 this->fArray[i]=array[i];
184 }
185 return *this;
186 }
187
GArray(GCompareProc * cmpFunc)188 template <class OBJ> GArray<OBJ>::GArray(GCompareProc* cmpFunc):GVec<OBJ>(0) {
189 fCompareProc = cmpFunc;
190 fUnique = false; //only affects sorted lists
191 }
192
GArray(bool sorted,bool unique)193 template <class OBJ> GArray<OBJ>::GArray(bool sorted, bool unique):GVec<OBJ>(0) {
194 fUnique=unique;
195 fCompareProc = sorted ? DefaultCompareProc : NULL;
196 }
197
GArray(int init_capacity,bool sorted,bool unique)198 template <class OBJ> GArray<OBJ>::GArray(int init_capacity,
199 bool sorted, bool unique):GVec<OBJ>(init_capacity) {
200 fUnique=unique;
201 fCompareProc=sorted ? DefaultCompareProc : NULL;
202 }
203
setSorted(GCompareProc * cmpFunc)204 template <class OBJ> void GArray<OBJ>::setSorted(GCompareProc* cmpFunc) {
205 GCompareProc* old_proc=fCompareProc;
206 fCompareProc=cmpFunc;
207 if (fCompareProc!=old_proc && fCompareProc!=NULL)
208 Sort(); //new compare method
209 }
210
IndexOf(OBJ & item)211 template <class OBJ> int GArray<OBJ>::IndexOf(OBJ& item) {
212 int result=0;
213 if (Found(item, result)) return result;
214 else return -1;
215 }
216
Exists(OBJ & item)217 template <class OBJ> bool GArray<OBJ>::Exists(OBJ& item) {
218 int result=0;
219 if (Found(item, result)) return true;
220 else return false;
221 }
222
223
Add(OBJ * item)224 template <class OBJ> int GArray<OBJ>::Add(OBJ* item) {
225 if (item==NULL) return -1;
226 int result;
227 if (SORTED) {
228 if (Found(*item, result))
229 if (fUnique) return -1; //cannot add a duplicate!
230 //Found sets result to the position where the item should be!
231 GVec<OBJ>::Insert(result, *item);
232 }
233 else {
234 if (fUnique && Found(*item,result)) return -1; //set behaviour
235 result = this->fCount;
236 if (result==this->fCapacity) GVec<OBJ>::Grow();
237 this->fArray[result] = *item; //operator=, copies the item
238 this->fCount++;
239 }
240 return result;
241 }
242
243
Add(GArray<OBJ> & list)244 template <class OBJ> void GArray<OBJ>::Add(GArray<OBJ>& list) {
245 if (list.Count()==0) return;
246 if (SORTED) {
247 for (int i=0;i<list.fCount;i++) Add(&list[i]);
248 }
249 else { //simply copy
250 this->setCapacity(this->fCapacity+list.fCount);
251 int s=this->fCount;
252 for (int i=0;i<list.fCount;i++)
253 this->fArray[s+i]=list.fArray[i];
254 this->fCount+=list.fCount;
255 }
256 }
257
Found(OBJ & item,int & idx)258 template <class OBJ> bool GArray<OBJ>::Found(OBJ& item, int& idx) {
259 //search the list by using fCompareProc (if defined)
260 //or == operator for a non-sortable list
261 //for sorted lists, even when the result is false, the idx is
262 //set to the closest matching object!
263 int i;
264 idx=-1;
265 if (this->fCount==0) { idx=0;return false;}
266 if (SORTED) { //binary search based on fCompareProc
267 //do the simplest tests first:
268 if ((*fCompareProc)(&(this->fArray[0]),&item)>0) {
269 idx=0;
270 return false;
271 }
272 if ((*fCompareProc)(&item, &(this->fArray[this->fCount-1]))>0) {
273 idx=this->fCount;
274 return false;
275 }
276
277 int l=0;
278 int h = this->fCount - 1;
279 int c;
280 while (l <= h) {
281 i = (l + h) >> 1;
282 c = (*fCompareProc)(&(this->fArray[i]), &item);
283 if (c < 0) l = i + 1;
284 else {
285 h = i - 1;
286 if (c == 0) { //found!
287 idx=i;
288 return true;
289 }
290 }
291 } //while
292 idx = l;
293 return false;
294 }
295 else {//not sorted: use linear search
296 // needs == operator to compare user defined objects !
297 i=0;
298 while (i<this->fCount) {
299 if (this->fArray[i]==item) { //requires operator==
300 idx=i;
301 return true;
302 }
303 i++;
304 }
305 return false;
306 }
307 }
308
Insert(int idx,OBJ * item)309 template <class OBJ> void GArray<OBJ>::Insert(int idx, OBJ* item) {
310 //idx can be [0..fCount] so an item can be actually added
311 BE_UNSORTED; //forbid this operation on sorted data
312 GVec<OBJ>::Insert(idx, item);
313 }
314
315
Move(int curidx,int newidx)316 template <class OBJ> void GArray<OBJ>::Move(int curidx, int newidx) {
317 BE_UNSORTED; //cannot do this in a sorted list!
318 if (curidx!=newidx || newidx>=this->fCount)
319 GError(GVEC_INDEX_ERR, newidx);
320
321 OBJ tmp=this->fArray[curidx]; //copy constructor here
322 this->fArray[curidx]=this->fArray[newidx];
323 this->fArray[newidx]=tmp;
324 }
325
Replace(int idx,OBJ & item)326 template <class OBJ> void GArray<OBJ>::Replace(int idx, OBJ& item) {
327 //TEST_INDEX(idx);
328 if (idx<0 || idx>=this->fCount) GError(GVEC_INDEX_ERR, __FILE__,__LINE__, idx);
329 this->fArray[idx]=item;
330 if ( SORTED ) Sort(); //re-sort ! this could be very expensive, don't do it
331 }
332
Sort()333 template <class OBJ> void GArray<OBJ>::Sort() {
334 if (fCompareProc==NULL) { fCompareProc=DefaultCompareProc; }
335 if (this->fArray!=NULL && this->fCount>0)
336 this->qSort(0, this->fCount-1, fCompareProc);
337 }
338
339 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
340 //*=> GList implementation -- sortable array of pointers to OBJ
341
GList(GList<OBJ> & list)342 template <class OBJ> GList<OBJ>::GList(GList<OBJ>& list):GPVec<OBJ>(list) { //copy constructor
343 fUnique=list.fUnique;
344 fCompareProc=list.fCompareProc;
345 }
346
GList(GList<OBJ> * plist)347 template <class OBJ> GList<OBJ>::GList(GList<OBJ>* plist):GPVec<OBJ>(0) { //another copy constructor
348 this->fCapacity=plist->fCapacity;
349 this->fList=NULL;
350 if (this->fCapacity>0) {
351 GMALLOC(this->fList, this->fCapacity*sizeof(OBJ*));
352 }
353 fUnique=plist->fUnique;
354 fCompareProc=plist->fCompareProc;
355 this->fFreeProc=plist->fFreeProc;
356 this->fCount=plist->fCount;
357 memcpy(this->fList, plist->fList, this->fCount*sizeof(OBJ*));
358 //for (int i=0;i<list->fCount;i++) Add(plist->Get(i));
359 }
360
Add(GList<OBJ> & list)361 template <class OBJ> void GList<OBJ>::Add(GList<OBJ>& list) {
362 if (list.Count()==0) return;
363 if (SORTED) {
364 for (int i=0;i<list.Count();i++) Add(list[i]);
365 }
366 else { //simply copy
367 this->setCapacity(this->fCapacity+list.fCount);
368 memcpy( & (this->fList[this->fCount]), list.fList, list.fCount*sizeof(OBJ*));
369 this->fCount+=list.fCount;
370 }
371 }
372
373
GList(GCompareProc * compareProc,GFreeProc * freeProc,bool beUnique)374 template <class OBJ> GList<OBJ>::GList(GCompareProc* compareProc,
375 GFreeProc* freeProc, bool beUnique) {
376 fCompareProc = compareProc;
377 this->fFreeProc = freeProc;
378 fUnique = beUnique; //only affects sorted lists
379 }
380
GList(GCompareProc * compareProc)381 template <class OBJ> GList<OBJ>::GList(GCompareProc* compareProc) {
382 fCompareProc = compareProc;
383 this->fFreeProc = GPVec<OBJ>::DefaultFreeProc;
384 fUnique = false; //only affects sorted lists
385 }
386
GList(bool sorted,bool free_elements,bool beUnique)387 template <class OBJ> GList<OBJ>::GList(bool sorted,
388 bool free_elements, bool beUnique) {
389 if (sorted) {
390 if (free_elements) {
391 fCompareProc=&DefaultCompareProc;
392 this->fFreeProc = GPVec<OBJ>::DefaultFreeProc;
393 fUnique=beUnique;
394 }
395 else {
396 fCompareProc=&DefaultCompareProc;
397 this->fFreeProc=NULL;
398 fUnique=beUnique;
399 }
400 }
401 else {
402 if (free_elements) {
403 fCompareProc=NULL;
404 this->fFreeProc=GPVec<OBJ>::DefaultFreeProc;
405 fUnique=beUnique;
406 }
407 else {
408 fCompareProc=NULL;
409 this->fFreeProc=NULL;
410 fUnique=beUnique;
411 }
412 }
413 }
414
415
GList(int init_capacity,bool sorted,bool free_elements,bool beUnique)416 template <class OBJ> GList<OBJ>::GList(int init_capacity, bool sorted,
417 bool free_elements, bool beUnique):GPVec<OBJ>(init_capacity, free_elements) {
418 if (sorted) {
419 fCompareProc=&DefaultCompareProc;
420 fUnique=beUnique;
421 }
422 else {
423 fCompareProc=NULL;
424 fUnique=beUnique;
425 }
426 }
427
operator =(GList & list)428 template <class OBJ> const GList<OBJ>& GList<OBJ>::operator=(GList& list) {
429 if (&list!=this) {
430 GPVec<OBJ>::Clear();
431 fCompareProc=list.fCompareProc;
432 this->fFreeProc=list.fFreeProc;
433 //Attention: the object pointers are copied directly,
434 //but the actual objects are NOT duplicated
435 for (int i=0;i<list.Count();i++) Add(list[i]);
436 }
437 return *this;
438 }
439
setSorted(GCompareProc * compareProc)440 template <class OBJ> void GList<OBJ>::setSorted(GCompareProc* compareProc) {
441 GCompareProc* old_proc=fCompareProc;
442 fCompareProc=compareProc;
443 if (fCompareProc!=old_proc && fCompareProc!=NULL)
444 Sort(); //new compare method
445 }
446
IndexOf(OBJ * item)447 template <class OBJ> int GList<OBJ>::IndexOf(OBJ* item) {
448 int result=0;
449 if (Found(item, result)) return result;
450 else return -1;
451 }
452
Exists(OBJ & item)453 template <class OBJ> bool GList<OBJ>::Exists(OBJ& item) {
454 int result=0;
455 if (Found(&item, result)) return true;
456 else return false;
457 }
458
Exists(OBJ * item)459 template <class OBJ> bool GList<OBJ>::Exists(OBJ* item) {
460 int result=0;
461 if (Found(item, result)) return true;
462 else return false;
463 }
464
Add(OBJ * item)465 template <class OBJ> int GList<OBJ>::Add(OBJ* item) {
466 int result;
467 if (item==NULL) return -1;
468 if (SORTED) {
469 if (Found(item, result))
470 if (fUnique) return -1; //duplicates forbidden
471 //Found sets result to the position where the item should be!
472 sortInsert(result, item);
473 }
474 else {
475 if (fUnique && Found(item,result)) return -1; //set behaviour
476 result = this->fCount;
477 if (result==this->fCapacity) GPVec<OBJ>::Grow();
478 this->fList[result]=item;
479 this->fCount++;
480 }
481 return result;
482 }
483
484 //by default, it deletes the item if it has an equal in the list!
485 //returns the existing equal (==) object if it's in the list already
486 //or returns the item itself if it's unique (and adds it)
AddIfNew(OBJ * item,bool deleteIfFound,int * fidx)487 template <class OBJ> OBJ* GList<OBJ>::AddIfNew(OBJ* item,
488 bool deleteIfFound, int* fidx) {
489 int r;
490 if (Found(item, r)) {
491 if (deleteIfFound && (pointer)item != (pointer)(this->fList[r])) {
492 this->deallocate_item(item);
493 }
494 if (fidx!=NULL) *fidx=r;
495 return this->fList[r]; //found
496 }
497 //not found:
498 if (SORTED) {
499 //Found() set result to the position where the item should be inserted:
500 sortInsert(r, item);
501 }
502 else {
503 r = this->fCount;
504 if (r==this->fCapacity) GPVec<OBJ>::Grow();
505 this->fList[r]=item;
506 this->fCount++;
507 }
508 if (fidx!=NULL) *fidx=r;
509 return item;
510 }
511
512 //if item is found already in the list DELETE it and return -1
513 //otherwise the item is added and its index is returned
AddedIfNew(OBJ * item)514 template <class OBJ> int GList<OBJ>::AddedIfNew(OBJ* item) {
515 int r;
516 if (Found(item, r)) {
517 if ((pointer)item != (pointer)(this->fList[r])) {
518 this->deallocate_item(item);
519 }
520 return -1;
521 }
522 //not found:
523 if (SORTED) {
524 //Found() set r to the position where the item should be inserted:
525 sortInsert(r, item);
526 }
527 else {
528 r = this->fCount;
529 if (r==this->fCapacity) GPVec<OBJ>::Grow();
530 this->fList[r]=item;
531 this->fCount++;
532 }
533 return r;
534 }
535
536
Found(OBJ * item,int & idx)537 template <class OBJ> bool GList<OBJ>::Found(OBJ* item, int& idx) {
538 //search the list by using fCompareProc (if defined)
539 //or == operator for a non-sortable list
540 //for sorted lists, even when the result is false, the idx is
541 //set to the closest matching object!
542 int i;
543 idx=-1;
544 if (this->fCount==0) { idx=0;return false;}
545 if (SORTED) { //binary search based on fCompareProc
546 //do the simple test first:
547
548 if ((*fCompareProc)(this->fList[0],item)>0) {
549 idx=0;
550 return false;
551 }
552 if ((*fCompareProc)(item, this->fList[this->fCount-1])>0) {
553 idx=this->fCount;
554 return false;
555 }
556
557 int l, h, c;
558 l = 0;
559 h = this->fCount - 1;
560 while (l <= h) {
561 i = (l + h) >> 1;
562 c = (*fCompareProc)(this->fList[i], item);
563 if (c < 0) l = i + 1;
564 else {
565 h = i - 1;
566 if (c == 0) {
567 idx=i;
568 return true;
569 }
570 }
571 } //while
572 idx = l;
573 return false;
574 }
575 else {//not sorted: use linear search
576 // needs == operator to compare user defined objects !
577 i=0;
578 while (i<this->fCount) {
579 if (*this->fList[i]==*item) {
580 idx=i;
581 return true;
582 }
583 i++;
584 }
585 return false;
586 }
587 }
588
sortInsert(int idx,OBJ * item)589 template <class OBJ> void GList<OBJ>::sortInsert(int idx, OBJ* item) {
590 //idx must be the new position this new item must have
591 //so the allowed range is [0..fCount]
592 //the current fList[idx] and all the above will be shifted +1
593 if (idx<0 || idx>this->fCount) GError(GVEC_INDEX_ERR, idx);
594 if (this->fCount==this->fCapacity) {
595 GPVec<OBJ>::Grow(idx, item);
596 //expand and also copy/move data and insert the new item
597 return;
598 }
599 //room still left, just move data around and insert the new one
600 if (idx<this->fCount) //copy/move pointers only!
601 memmove(&(this->fList[idx+1]), &(this->fList[idx]), (this->fCount-idx)*sizeof(OBJ*));
602 this->fList[idx]=item;
603 this->fCount++;
604 }
605
Insert(int idx,OBJ * item)606 template <class OBJ> void GList<OBJ>::Insert(int idx, OBJ* item) {
607 //idx can be [0..fCount] so an item can be actually added
608 BE_UNSORTED; //cannot do that with a sorted list!
609 GPVec<OBJ>::Insert(idx,item);
610 }
611
Move(int curidx,int newidx)612 template <class OBJ> void GList<OBJ>::Move(int curidx, int newidx) {
613 BE_UNSORTED; //cannot do this in a sorted list!
614 GPVec<OBJ>::Move(curidx,newidx);
615 }
616
Put(int idx,OBJ * item,bool re_sort)617 template <class OBJ> void GList<OBJ>::Put(int idx, OBJ* item, bool re_sort) {
618 //WARNING: this will never free the replaced item!
619 // this may BREAK the sort order unless the "re_sort" parameter is given
620 if (idx<0 || idx>this->fCount) GError(GVEC_INDEX_ERR, idx);
621 this->fList[idx]=item;
622 if (SORTED && item!=NULL && re_sort) Sort(); //re-sort
623 }
624
Remove(OBJ * item)625 template <class OBJ> int GList<OBJ>::Remove(OBJ* item) {
626 //removes an item if it's in our list
627 int result=IndexOf(item);
628 if (result>=0) GPVec<OBJ>::Delete(result);
629 return result;
630 }
631
Sort()632 template <class OBJ> void GList<OBJ>::Sort() {
633 if (fCompareProc==NULL) fCompareProc = DefaultCompareProc;
634 if (this->fList!=NULL && this->fCount>0)
635 this->qSort(0, this->fCount-1, fCompareProc);
636 }
637
638 //---------------------------------------------------------------------------
639 #endif
640