|
|
| version 1.17.2.6, 2003/03/04 15:59:18 | version 1.26, 2009/04/30 04:39:06 |
|---|---|
| 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-2009 ArtLebedev Group (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$"; | static const char * const IDENT_STACK_H="$Date$"; |
| #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++; | |
| } | } |
| /// @test to think: freeing unused stack item right now, may no do that? | inline T pop() { |
| /// [delay that till next push?] | return this->felements[--this->fused]; |
| T pop() { | |
| T result=get(--ftop); | |
| put(ftop, empty); | |
| return result; | |
| } | } |
| int top_index() { return ftop-1; } | inline bool is_empty() { return this->fused==0; } |
| void top_index(int top_index) { ftop=top_index+1; } | inline size_t top_index() { return this->fused; } |
| T top_value() { return get(top_index()); } | inline void set_top_index(size_t atop) { this->fused=atop; } |
| inline T top_value() { | |
| private: | assert(!is_empty()); |
| return this->felements[this->fused-1]; | |
| // deepest used index | } |
| int ftop; | |
| T empty; | /// 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(&this->felements[this->fused], 0, above_top_size*sizeof(T)); | |
| } | |
| 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 | #endif |