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