--- parser3/src/include/pa_array.h 2024/09/10 19:09:56 1.90 +++ parser3/src/include/pa_array.h 2024/09/15 00:38:27 1.93 @@ -8,7 +8,7 @@ #ifndef PA_ARRAY_H #define PA_ARRAY_H -#define IDENT_PA_ARRAY_H "$Id: pa_array.h,v 1.90 2024/09/10 19:09:56 moko Exp $" +#define IDENT_PA_ARRAY_H "$Id: pa_array.h,v 1.93 2024/09/15 00:38:27 moko Exp $" // includes @@ -76,8 +76,6 @@ public: return true; } - - }; typedef T element_type; @@ -89,7 +87,7 @@ public: felements=fallocated?(T *)pa_malloc(fallocated*sizeof(T)):0; } -#ifdef USE_DESTRUCTORS +#ifdef USE_DESTRUCTORS inline ~Array(){ if(felements) pa_free(felements); @@ -98,10 +96,11 @@ public: /// how many items are in Array inline size_t count() const { return fused; } + /// append to array inline Array& operator+=(T src) { if(is_full()) - expand(fallocated>0? 2+fallocated/32 : 3); // 3 is PAF default, confirmed by tests + expand(); felements[fused++]=src; @@ -123,14 +122,14 @@ public: if(limit==ARRAY_OPTION_LIMIT_ALL || limit>m) limit=m; - ssize_t delta=limit-(fallocated-fused); - if(delta>0) - expand(delta); + size_t required=fused+limit; + if(required>fallocated) + resize(required); T* from=&src.felements[offset]; T* to=&felements[fused]; - for(T* from_end=from+limit; from0? 2+fallocated/32 : 3); // 3 is PAF default, confirmed by tests + expand(); memmove(felements+index+1, felements+index, (fused-index) * sizeof(T)); @@ -217,34 +216,23 @@ public: return felements + index; } - void fit(size_t index, T element){ - if(index >= fallocated){ - size_t new_allocated=fallocated>0 ? fallocated : 3; - while(new_allocated <= index){ - new_allocated+=2 + new_allocated/32; - } - expand(new_allocated - fallocated); - } - felements[index]=element; - if(index >= fused){ - fused=index+1; - } - } - protected: bool is_full() { return fused == fallocated; } - void expand(size_t delta) { + inline void expand() { + resize(fallocated>0 ? fallocated+fallocated/4+2 : 3); // 3 is PAF default, confirmed by tests + } + + void resize(size_t asize) { if(fallocated){ - size_t new_allocated=fallocated+delta; - felements=(T *)pa_realloc(felements, new_allocated*sizeof(T)); - fallocated=new_allocated; + felements=(T *)pa_realloc(felements, asize*sizeof(T)); + fallocated=asize; } else { - fallocated=delta; - felements=(T *)pa_malloc(fallocated*sizeof(T)); + fallocated=asize; + felements=(T *)pa_malloc(asize*sizeof(T)); } } @@ -255,6 +243,43 @@ private: //disabled }; +/// Commonly used, templated to work with any integer type + +template char* pa_itoa(T n, T base=10){ + char buf[MAX_NUMBER + 1]; + char* pos=buf + MAX_NUMBER; + *pos='\0'; + + bool negative=n < 0; + if (n < 0){ + n=-n; + } + + do { + *(--pos)=(n % base) + '0'; + n/=base; + } while (n > 0); + + if (negative) { + *(--pos) = '-'; + } + return pa_strdup(pos, buf + MAX_NUMBER - pos); +} + +template char* pa_uitoa(T n, T base=10){ + char buf[MAX_NUMBER + 1]; + char* pos=buf + MAX_NUMBER; + *pos='\0'; + + do { + *(--pos)=(n % base) + '0'; + n/=base; + } while (n > 0); + + return pa_strdup(pos, buf + MAX_NUMBER - pos); +} + + /** Array iterator, usage: @code // Array a; @@ -274,7 +299,7 @@ public: Array_iterator(const Array& aarray): farray(aarray) { fcurrent=farray.felements; - flast=farray.felements + farray.count(); + flast=farray.felements + farray.fused; } /// there are still elements @@ -298,9 +323,7 @@ public: } inline char *key(){ - char local_buf[MAX_NUMBER]; - size_t length=snprintf(local_buf, MAX_NUMBER, "%zu", index()); - return pa_strdup(local_buf, length); + return pa_uitoa(index()); } }; @@ -313,7 +336,7 @@ template class Array_reverse public: Array_reverse_iterator(const Array& aarray): farray(aarray) { - fcurrent=farray.felements+farray.count(); + fcurrent=farray.felements + farray.fused; } /// there are still elements @@ -332,9 +355,7 @@ public: } inline char *key(){ - char local_buf[MAX_NUMBER]; - size_t length=snprintf(local_buf, MAX_NUMBER, "%zu", index()); - return pa_strdup(local_buf, length); + return pa_uitoa(index()); } };