--- parser3/src/include/pa_array.h 2015/07/28 14:41:32 1.82 +++ parser3/src/include/pa_array.h 2024/09/11 21:07:36 1.91 @@ -1,23 +1,25 @@ /** @file Parser: Array & Array_iterator classes decls. - Copyright (c) 2001-2012 Art. Lebedev Studio (http://www.artlebedev.com) - Author: Alexandr Petrosian (http://paf.design.ru) + Copyright (c) 2001-2023 Art. Lebedev Studio (http://www.artlebedev.com) + Authors: Konstantin Morshnev , Alexandr Petrosian */ #ifndef PA_ARRAY_H #define PA_ARRAY_H -#define IDENT_PA_ARRAY_H "$Id: pa_array.h,v 1.82 2015/07/28 14:41:32 moko Exp $" +#define IDENT_PA_ARRAY_H "$Id: pa_array.h,v 1.91 2024/09/11 21:07:36 moko Exp $" // includes #include "pa_memory.h" +#include "pa_types.h" #include "pa_exception.h" // forwards template class Array_iterator; +template class Array_reverse_iterator; // defines @@ -27,6 +29,7 @@ template class Array_iterato template class Array: public PA_Object { friend class Array_iterator; + friend class Array_reverse_iterator; protected: @@ -40,6 +43,9 @@ protected: size_t fused; public: + typedef Array_iterator Iterator; + typedef Array_reverse_iterator ReverseIterator; + struct Action_options { size_t offset; size_t limit; //< ARRAY_OPTION_LIMIT_ALL means 'all'. zero limit means 'nothing' @@ -169,6 +175,12 @@ public: inline T operator [](size_t index) const { return get(index); } + inline void clear() { + if(fused) + memset(felements, 0, fused * sizeof(T)); + fused=0; + } + /// iterate over all elements template void for_each(void (*callback)(T, I), I info) const { T *last=felements+fused; @@ -205,11 +217,26 @@ 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) { if(fallocated){ size_t new_allocated=fallocated+delta; @@ -227,11 +254,47 @@ private: //disabled Array& operator = (const Array&) { return *this; } }; +/// 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; - for(Array_iterator i(a); i.has_next(); ) { + for(Array_iterator i(a); i; ) { T& element=i.next(); ... } @@ -247,18 +310,64 @@ public: Array_iterator(const Array& aarray): farray(aarray) { fcurrent=farray.felements; - flast=farray.felements+farray.count(); + flast=farray.felements + farray.count(); } /// there are still elements - bool has_next() { - return fcurrent class Array_reverse_iterator { + + const Array& farray; + T *fcurrent; + +public: + + Array_reverse_iterator(const Array& aarray): farray(aarray) { + fcurrent=farray.felements+farray.count(); + } + + /// there are still elements + inline operator bool () { + return fcurrent > farray.felements; + } + + /// returns the current element and advances the iterator + inline T prev() { + return *(--fcurrent); + } + + // returns the current index of the iterator + inline size_t index() { + return fcurrent - farray.felements; + } + + inline char *key(){ + return pa_uitoa(index()); + } + }; #endif