@@ -360,20 +360,25 @@ class GSeg {
360360
361361// basic dynamic array template for primitive types
362362// which can only grow (reallocate) as needed
363- #define GDynArray_INDEX_ERR " Error: invalid index (%d) in dynamic array!\n "
363+
364+ // optimize index test
365+ #define GDynArray_INDEX_ERR " Error: use of index (%d) in GDynArray of size %d!\n "
364366 #if defined(NDEBUG) || defined(NODEBUG) || defined(_NDEBUG) || defined(NO_DEBUG)
365367 #define GDynArray_TEST_INDEX (x )
366368#else
367369 #define GDynArray_TEST_INDEX (x ) \
368- if (x>=fCount ) GError(GDynArray_INDEX_ERR, x)
370+ if (fCount == 0 || x>=fCount ) GError(GDynArray_INDEX_ERR, x, fCount )
369371#endif
370372
371373#define GDynArray_MAXCOUNT UINT_MAX-1
372374#define GDynArray_NOIDX UINT_MAX
373375
376+ // basic dynamic array (vector) template for simple/primitive types or structs
377+ // Warning: uses malloc so it will never call the item's default constructor when growing
378+
374379template <class OBJ > class GDynArray {
375380 protected:
376- bool byptr;
381+ bool byptr; // in-place copy (pointer) takeover of existing OBJ[]
377382 OBJ *fArray ;
378383 uint fCount ;
379384 uint fCapacity ; // size of allocated memory
@@ -401,12 +406,12 @@ template<class OBJ> class GDynArray {
401406 Clear ();
402407 return *this ;
403408 }
404- setCapacity (a.fCapacity ); // set size
409+ increaseCapacity (a.fCapacity ); // set size
405410 memcpy (fArray , a.fArray , sizeof (OBJ)*a.fCount );
406411 return *this ;
407412 }
408413
409- OBJ& operator [] (uint idx) {// get array item
414+ OBJ& operator [] (uint idx) {// get array item
410415 GDynArray_TEST_INDEX (idx);
411416 return fArray [idx];
412417 }
@@ -416,53 +421,78 @@ template<class OBJ> class GDynArray {
416421 if (GDynArray_MAXCOUNT-delta<=fCapacity )
417422 delta=GDynArray_MAXCOUNT-fCapacity ;
418423 if (delta<=1 ) GError (" Error at GDynArray::Grow(): max capacity reached!\n " );
419- setCapacity (fCapacity + delta);
424+ increaseCapacity (fCapacity + delta);
420425 }
421- #define GDYNARRAY_ADD (item ) \
426+ #define GDynArray_ADD (item ) \
422427 if (fCount ==MAX_UINT-1 ) GError(" Error at GDynArray: cannot add item, maximum count reached!\n " ); \
423428 if ((++fCount ) > fCapacity ) Grow(); \
424429 fArray [fCount -1 ] = item;
425430
426- uint Add (OBJ* item) { // Add item to the end of array by pointer
431+ uint Add (OBJ* item) { // Add item to the end of array
432+ // element given by pointer
427433 if (item==NULL ) return GDynArray_NOIDX;
428- GDYNARRAY_ADD ( (*item) );
434+ GDynArray_ADD ( (*item) );
429435 return (fCount -1 );
430436 }
431437
432- uint Add (OBJ item) { // Add item copy to the end of array
433- GDYNARRAY_ADD (item);
438+ uint Add (OBJ item) { // Add OBJ copy to the end of array
439+ GDynArray_ADD (item);
434440 return (fCount -1 );
435441 }
436442
437- uint Push (OBJ item) {
438- GDYNARRAY_ADD (item);
443+ uint Push (OBJ item) { // same as Add
444+ GDynArray_ADD (item);
439445 return (fCount -1 );
440446 }
441447
442- OBJ Pop () {
443- if (fCount ==0 ) return (OBJ)NULL ;
448+ OBJ Pop () { // shoddy.. Do NOT call this for an empty array!
449+ if (fCount ==0 ) return (OBJ)NULL ; // a NULL cast operator is required
444450 --fCount ;
445451 return fArray [fCount ];
446452 }
447453
448454 uint Count () { return fCount ; } // get size of array (elements)
449455 uint Capacity () { return fCapacity ; }
450- virtual void setCapacity (uint newcap) {
451- if (newcap==0 ) { Clear (); return ; } // better use Clear() instead
452- if (newcap <= fCapacity ) return ; // never shrink -- use GVec for this
456+ void increaseCapacity (uint newcap) {
457+ if (newcap==0 ) { Clear (); return ; }
458+ if (newcap <= fCapacity ) return ; // never shrinks (use Pack() for this)
459+ GREALLOC (fArray , newcap*sizeof (OBJ));
460+ fCapacity =newcap;
461+ }
462+ void Trim (int tcount=1 ) {
463+ // simply cut (discard) the last tcount items
464+ // new Count is now fCount-tcount
465+ // does NOT shrink capacity accordingly!
466+ if (fCount >=tcount) fCount -=tcount;
467+ }
468+
469+ void Pack () { // shrink capacity to fCount+dyn_array_defcap
470+ if (fCapacity -fCount <=dyn_array_defcap) return ;
471+ int newcap=fCount +dyn_array_defcap;
453472 GREALLOC (fArray , newcap*sizeof (OBJ));
454473 fCapacity =newcap;
455474 }
456475
457- void Clear () { // clear array
476+ inline void Shrink () { Pack (); }
477+
478+ void Delete (uint idx) {
479+ GDynArray_TEST_INDEX (idx);
480+ --fCount ;
481+ if (idx<fCount )
482+ memmove (&fArray [idx], &fArray [idx+1 ], (fCount -idx)*sizeof (OBJ));
483+ }
484+
485+ inline void Remove (uint idx) { Delete (idx); }
486+
487+ void Clear () { // clear array, shrinking its allocated memory
458488 fCount = 0 ;
459489 GREALLOC (fArray , sizeof (OBJ)*dyn_array_defcap);
460490 // set initial memory size again
461491 fCapacity = dyn_array_defcap;
462492 }
463493
464- void reset () {
465- fCount = 0 ; // do not deallocate, just show it empty
494+ void Reset () {// fast clear array WITHOUT deallocating it
495+ fCount = 0 ;
466496 }
467497 // pointer getptr() { return (pointer) fArray; }
468498 OBJ* operator ()() { return fArray ; }
0 commit comments