Mercurial > ~dholland > hg > ag > index.cgi
diff oldclasslib/include/stack.h @ 0:13d2b8934445
Import AnaGram (near-)release tree into Mercurial.
author | David A. Holland |
---|---|
date | Sat, 22 Dec 2007 17:52:45 -0500 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/oldclasslib/include/stack.h Sat Dec 22 17:52:45 2007 -0500 @@ -0,0 +1,200 @@ +/* + * AnaGram, a System for Syntax Directed Programming + * + * Stack Class Definition + * + * Please note that the entire class is defined in this module. There + * is no supplementary code module. + * + * Copyright 1993 Parsifal Software. All Rights Reserved. + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + */ + +#ifndef STACK_H +#define STACK_H + +#include <assert.h> + +// Some forward decls required in current C++ +template <class T> class stack; +template <class T> stack <T> &reset(stack <T> &s); +template <class T> unsigned size(const stack <T> &s); + + +template <class T> +class stack { +protected: + T *cs; // data storage + unsigned *ls; // index (level) storage + unsigned sx; // stack index + unsigned lx; // level index + unsigned sxmax; // max stack index + unsigned lxmax; // max level index + int copy_flag; // is it live or memorex? +public: + + +// Constructor + + stack(unsigned n, unsigned m) { // (storage request, levels) + cs = new T[n]; // allocate data storage + ls = new unsigned[m]; // allocate index storage + lx = lxmax = m; // set up for pre-decrement push + sx = sxmax = n; // post-increment pop + ls[--lx] = sx; // init first level + copy_flag = 0; // live + } + + stack(unsigned n) { // (storage request) + unsigned m = 1; // single level + cs = new T[n]; // allocate data storage + ls = new unsigned[m]; // allocate index storage + lx = lxmax = m; // set up for pre-decrement push + sx = sxmax = n; // post-increment pop + ls[--lx] = sx; // init first level + copy_flag = 0; // live + } + + stack(stack<T> &s) { + *this = s; + copy_flag++; // memorex + } + + +// Destructor + + ~stack() { + if (copy_flag) return; + delete [] cs; + delete [] ls; + } + + +// Reset function +#ifdef __IBMCPP__ + friend stack<T> &reset(stack<T> &s); +#else + friend stack<T> &reset<>(stack<T> &s); +#endif + + +// Change levels + + stack<T> &operator ++() { // next level -- preincrement + assert(copy_flag == 0); + assert(lx); // not going to overflow + ls[--lx] = sx; // push storage index + return *this; + } + + stack<T> operator ++(int); // next level -- postincrement + + stack<T> &operator --() { // previous level -- predecrement + assert(copy_flag == 0); + sx = ls[lx++]; // restore storage index + assert(lx < lxmax); // no underflow + return *this; + } + + stack<T> operator --(int); // previous level -- postdecrement + + +// Push data + + stack<T> &operator << (T t) { // push data + assert(copy_flag == 0); + assert(sx && lx < lxmax); // everything's ok + cs[--sx] = t; // save it + return *this; + } + + +// Pop data + + stack<T> &operator >> (T &t) { // pop data + assert(copy_flag == 0); + assert(lx < lxmax && sx < ls[lx]); // all's well + t = cs[sx++]; // get it + return *this; + } + + +// Access stack element + + T &operator[] (unsigned k) { // access stack element + assert(lx < lxmax && sx + k < ls[lx]); // legitimate index + return cs[sx+k]; // reference data + } + + +// Pointer to top element + +// See README.txt +#if 0 + operator T * () { + return &cs[sx]; + } +#endif + T *top() { + return &cs[sx]; + } + + +// Get size of stack + +#ifdef __IBMCPP__ + friend unsigned size(const stack <T> &s); // size at current level +#else + friend unsigned size<>(const stack <T> &s); // size at current level +#endif + +}; + +template <class T> +inline stack <T> &reset(stack <T> &s) { + assert(s.copy_flag == 0); + s.lx = s.lxmax; // set up for pre-decrement push + s.sx = s.sxmax; // post-increment pop + s.ls[--s.lx] = s.sx; // init first level + return s; +} + +template <class T> +inline unsigned size(const stack <T> &s) { // size at current level + return s.ls[s.lx] - s.sx; +} + + +template <class T> +stack<T> stack<T>::operator ++(int) { // next level -- postintcrement + stack<T> cpy(*this); // make copy for return value + assert(copy_flag == 0); + assert(lx); + ls[--lx] = sx; + return cpy; +} + +template <class T> +stack<T> stack<T>::operator --(int) { // previous level -- postdecrement + stack <T> cpy(*this); // make copy for return value + assert(copy_flag == 0); + sx = ls[lx++]; // restore storage index + assert(lx < lxmax); // no underflow + return cpy; +} +#endif