diff options
Diffstat (limited to 'libxsde/xsde/cxx/stack.ixx')
-rw-r--r-- | libxsde/xsde/cxx/stack.ixx | 75 |
1 files changed, 40 insertions, 35 deletions
diff --git a/libxsde/xsde/cxx/stack.ixx b/libxsde/xsde/cxx/stack.ixx index bef310e..1f947df 100644 --- a/libxsde/xsde/cxx/stack.ixx +++ b/libxsde/xsde/cxx/stack.ixx @@ -14,30 +14,33 @@ namespace xsde namespace cxx { inline stack:: - ~stack () - { - if (data_) -#ifndef XSDE_CUSTOM_ALLOCATOR - operator delete (data_); -#else - cxx::free (data_); -#endif - } - - inline stack:: stack (size_t el_size, void* first_el) : el_size_ (el_size), - first_ (first_el), - data_ (0), - size_ (0), - capacity_ (0) + cur_ (static_cast<block*> (first_el)), + next_ (0), + cap_ (1), + num_ (0) { } inline void stack:: pop () { - --size_; + if (cap_ == 1) + --num_; + else + { + if (num_ > 1) + --num_; + else + { + // Move to the previous block. + // + cap_ = cur_ == next_ ? 1 : cap_ / 2; + cur_ = cur_->prev; + num_ = cap_; + } + } } #ifdef XSDE_EXCEPTIONS @@ -47,45 +50,47 @@ namespace xsde #endif push () { - if (size_ > capacity_) + if (num_ < cap_) + { + num_++; +#ifndef XSDE_EXCEPTIONS + return error_none; +#endif + } + else { #ifdef XSDE_EXCEPTIONS - grow (); + push_impl (); #else - if (error e = grow ()) - return e; + return push_impl (); #endif } - - ++size_; - -#ifndef XSDE_EXCEPTIONS - return error_none; -#endif } inline void* stack:: top () { - return size_ == 1 ? first_ : data_ + (size_ - 2) * el_size_; + return cap_ == 1 + ? static_cast<void*> (cur_) + : static_cast<void*> (cur_->data + (num_ - 1) * el_size_); } inline void stack:: clear () { - size_ = 0; + cap_ = 1; + num_ = 0; + + // Reset cur_ to the first block. + // + if (next_) + cur_ = next_->prev; } inline bool stack:: empty () const { - return size_ == 0; - } - - inline size_t stack:: - size () const - { - return size_; + return num_ == 0; } inline size_t stack:: |