|
|
| version 1.20, 2003/10/02 07:26:46 | version 1.31, 2020/12/15 17:10:32 |
|---|---|
| Line 1 | Line 1 |
| /** @file | /** @file |
| Parser: stack class decl. | Parser: stack class decl. |
| Copyright (c) 2001-2003 ArtLebedev Group (http://www.artlebedev.com) | Copyright (c) 2001-2020 Art. Lebedev Studio (http://www.artlebedev.com) |
| Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru) | Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru) |
| */ | */ |
| #ifndef PA_STACK_H | #ifndef PA_STACK_H |
| #define PA_STACK_H | #define PA_STACK_H |
| static const char* IDENT_STACK_H="$Date$"; | #define IDENT_PA_STACK_H "$Id$" |
| #include "pa_config_includes.h" | |
| #include "pa_array.h" | #include "pa_array.h" |
| /// simple stack based on Array | /// simple stack based on Array |
| template<typename T> class Stack: public Array<T> { | template<typename T> class Stack: public Array<T> { |
| public: | public: |
| Stack(): ftop(0) {} | Stack(size_t initial=4) : Array<T>(initial){} |
| void push(T item) { | inline void push(T item) { |
| if(ftop<count()) // cell is already allocated? | if(this->is_full()) |
| put(ftop, item); // use it | expand(this->fallocated); // free is not called, so expanding a lot to decrease memory waste |
| else | this->felements[this->fused++]=item; |
| *this+=item; // append it | |
| ftop++; | |
| } | } |
| T pop() { | inline T pop() { |
| return get(--ftop); | return this->felements[--this->fused]; |
| } | } |
| bool is_empty() { return ftop==0; } | inline bool is_empty() { return this->fused==0; } |
| size_t top_index() { return ftop; } | inline size_t top_index() { return this->fused; } |
| void set_top_index(size_t atop) { ftop=atop; } | inline void set_top_index(size_t atop) { this->fused=atop; } |
| T top_value() { | inline T top_value() { |
| assert(!is_empty()); | assert(!is_empty()); |
| return get(ftop-1); | return this->felements[this->fused-1]; |
| } | } |
| /// call this prior to collecting garbage [in unused part of stack there may be pointers(unused)] | /// call this prior to collecting garbage [in unused part of stack there may be pointers(unused)] |
| void wipe_unused() { | void wipe_unused() { |
| if(size_t above_top_size=fused-ftop) | if(size_t above_top_size=this->fallocated-this->fused) |
| memset(&felements[ftop], 0, above_top_size*sizeof(T)); | memset((void *)&this->felements[this->fused], 0, above_top_size*sizeof(T)); |
| } | } |
| protected: | protected: |
| // deepest used index+1 | void expand(size_t delta) { |
| size_t ftop; | 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 | #endif |