--- parser3/src/include/pa_array.h 2017/02/07 22:00:31 1.85 +++ parser3/src/include/pa_array.h 2024/09/14 22:58:50 1.92 @@ -1,23 +1,25 @@ /** @file Parser: Array & Array_iterator classes decls. - Copyright (c) 2001-2017 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.85 2017/02/07 22:00:31 moko Exp $" +#define IDENT_PA_ARRAY_H "$Id: pa_array.h,v 1.92 2024/09/14 22:58:50 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' @@ -70,8 +76,6 @@ public: return true; } - - }; typedef T element_type; @@ -83,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); @@ -92,6 +96,7 @@ 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()) @@ -170,6 +175,8 @@ public: inline T operator [](size_t index) const { return get(index); } inline void clear() { + if(fused) + memset(felements, 0, fused * sizeof(T)); fused=0; } @@ -214,6 +221,7 @@ protected: bool is_full() { return fused == fallocated; } + void expand(size_t delta) { if(fallocated){ size_t new_allocated=fallocated+delta; @@ -232,10 +240,47 @@ 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; - for(Array_iterator i(a); i.has_next(); ) { + for(Array_iterator i(a); i; ) { T& element=i.next(); ... } @@ -251,18 +296,64 @@ 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 - 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.fused; + } + + /// 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