--- parser3/src/include/pa_stack.h 2001/03/08 15:15:45 1.4 +++ parser3/src/include/pa_stack.h 2019/12/05 22:21:16 1.30 @@ -1,37 +1,57 @@ -/* - $Id: pa_stack.h,v 1.4 2001/03/08 15:15:45 paf Exp $ +/** @file + Parser: stack class decl. + + Copyright (c) 2001-2017 Art. Lebedev Studio (http://www.artlebedev.com) + Author: Alexandr Petrosian (http://paf.design.ru) */ #ifndef PA_STACK_H #define PA_STACK_H +#define IDENT_PA_STACK_H "$Id: pa_stack.h,v 1.30 2019/12/05 22:21:16 moko Exp $" + #include "pa_array.h" -class Stack : public Array { +/// simple stack based on Array +template class Stack: public Array { public: - Stack(Pool& apool) : Array(apool), ftop(0) { - } + Stack(size_t initial=4) : Array(initial){} - void push(Item *item) { - if(ftopis_full()) + expand(this->fallocated); // free is not called, so expanding a lot to decrease memory waste + this->felements[this->fused++]=item; } - Item *pop() { - return get(--ftop); + + inline T pop() { + return this->felements[--this->fused]; } - int top_index() { return ftop-1; } - Item *top_value() { return get(top_index()); } + inline bool is_empty() { return this->fused==0; } + inline size_t top_index() { return this->fused; } + inline void set_top_index(size_t atop) { this->fused=atop; } + inline T top_value() { + assert(!is_empty()); + return this->felements[this->fused-1]; + } -private: + /// call this prior to collecting garbage [in unused part of stack there may be pointers(unused)] + void wipe_unused() { + if(size_t above_top_size=this->fallocated-this->fused) + memset((void *)&this->felements[this->fused], 0, above_top_size*sizeof(T)); + } - // deepest used index - int ftop; +protected: + void expand(size_t delta) { + size_t new_allocated=this->fallocated+delta; + // we can't use realloc as MethodParams references allocated stack + T* new_elements = (T *)pa_malloc(new_allocated*sizeof(T)); + memcpy(new_elements, this->felements, this->fallocated*sizeof(T)); + this->felements=new_elements; + this->fallocated=new_allocated; + } }; #endif