#ifndef _INCLUDED_L3_STACK_H #define _INCLUDED_L3_STACK_H // *Stack* Copyright (C) Krzysztof Bosak, 1999-01-15...2000-12-06 // All rights reserved. // kbosak@box43.pl // http://www.kbosak.prv.pl // growing_arraystack is self-growing, no auto-shrinking due to code efficiency // fixed_arraystack has fixed size // both can handle memory-allocating objects (no memcpy used), objects stored by value #include "l3_array.h" template class growing_arraystack { // Corresponds to std::stack. // Is EXCEPTION NEUTRAL. autoarray _data; int _size; public: inline growing_arraystack() // EXCEPTION NEUTRAL : _data(1), _size(0) { } inline explicit growing_arraystack(int requested_size) // EXCEPTION NEUTRAL : _data(requested_size+1), _size(0) { } inline void swap(growing_arraystack& other) // NOTHROW { _data.swap(other._data); const int temp=_size; _size=other._size; other._size=temp; } inline growing_arraystack& operator=(const growing_arraystack& other) // EXCEPTION NEUTRAL { // A must to ensure strong exception safety. assert(this!=&other);// This line can be safely removed. growing_arraystack temp(other); swap(temp); return *this; } inline int size() const // NOTHROW { return _size; } inline bool empty() const // NOTHROW { return _size==0; } inline int capacity() const // NOTHROW { return _data.size(); } inline type& top() // NOTHROW { assert(_size>0); return _data[_size-1]; } inline const type& top() const // NOTHROW { assert(_size>0); return _data[_size-1]; } inline void push(const type& val) // EXCEPTION NEUTRAL { if(_size+1>=_data.size()) { _data.resize((_data.size()+1)<<1); } _data[_size]=val; _size++; } inline void pop() // NOTHROW { assert(_size>0); _size--; } inline void setsize(int requested_size) // not STL // EXCEPTION NEUTRAL { assert(requested_size>=0); _data.setsize(requested_size>0 ? requested_size : 1); _size=0; } inline void clear() // not STL // NOTHROW { _size=0; } inline void free() // not STL // EXCEPTION NEUTRAL { _data.setsize(1); _size=0; } inline void reserve(int requested_size) // not STL // EXCEPTION NEUTRAL { assert(requested_size>=1); if(requested_size>_size) { _data.resize(requested_size>0 ? requested_size : 1); } } }; template class fixed_arraystack { // Warning: std::stack is self-growing, this one is not. // Is EXCEPTION NEUTRAL. autoarray _data; int _size; public: inline explicit fixed_arraystack(int requested_size) // EXEPTION NEUTRAL : _data(requested_size), _size(0) { assert(requested_size>0); } inline void swap(fixed_arraystack& other) // NOTHROW { _data.swap(other._data); const int temp=_size; _size=other._size; other._size=temp; } inline fixed_arraystack& operator=(const fixed_arraystack& other) // EXEPTION NEUTRAL { // A must to ensure strong exception safety. assert(this!=&other);// This line can be safely removed. fixed_arraystack temp(other); swap(temp); return *this; } inline int size() const // NOTHROW { assert(_size>=0); return _size; } inline bool empty() const // NOTHROW { assert(_size>=0); return _size==0; } inline int capacity() const // NOTHROW { return _data.size(); } inline type& top() // NOTHROW { assert(_size>0); return _data[_size-1]; } inline const type& top() const // NOTHROW { assert(_size>0); return _data[_size-1]; } inline void push(const type& val) // EXCEPTION NEUTRAL { _data[_size]=val; _size++; } inline void pop() // NOTHROW { assert(_size>0); _size--; } inline void setsize(int requested_size) // not STL // EXCEPTION NEUTRAL { assert(requested_size>=0); _data.setsize(requested_size>0 ? requested_size : 1); _size=0; } inline void clear() // not STL // NOTHROW { _size=0; } inline void free() // not STL // EXCEPTION NEUTRAL { _data.setsize(1); _size=0; } }; #endif //_INCLUDED_L3_STACK_H