--- parser3/src/include/pa_array.h 2017/02/07 22:00:31 1.85 +++ parser3/src/include/pa_array.h 2024/09/10 19:09:56 1.90 @@ -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.90 2024/09/10 19:09:56 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' @@ -170,6 +176,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; } @@ -209,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; @@ -235,7 +258,7 @@ private: //disabled /** 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 +274,68 @@ 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(){ + char local_buf[MAX_NUMBER]; + size_t length=snprintf(local_buf, MAX_NUMBER, "%zu", index()); + return pa_strdup(local_buf, length); + } + }; #endif