BAM
Abstract Machine for Bottom-Up Evaluation with the Push Method
stack.h
Go to the documentation of this file.
1 // ============================================================================
2 // Project: Deductive Database
3 // Filename: stack.h
4 // Purpose: Simple Stack Implementation (Class Template)
5 // Last Change: 04.08.2017
6 // Language: C++
7 // EMail: brass@informatik.uni-halle.de
8 // WWW: http://www.informatik.uni-halle.de/~brass/
9 // Address: Feldschloesschen 15, D-06120 Halle (Saale), GERMANY
10 // Copyright: (c) 2010-2017 by Stefan Brass
11 // License: See file "LICENSE" for copying conditions.
12 // Note: There is no warranty at all - this code may contain bugs.
13 // ============================================================================
14 
15 
22 //=============================================================================
23 // Include File Frame:
24 //=============================================================================
25 
26 #ifndef STACK_INCLUDED
27 #define STACK_INCLUDED
28 
29 //=============================================================================
30 // Used Types and Macros:
31 //=============================================================================
32 
33 #ifndef VER_INCLUDED
34 #include "../base/ver.h"
35 #endif
36 
37 #ifndef STR_INCLUDED
38 #include "../base/str.h"
39 #endif
40 
41 #ifndef CHECK_INCLUDED
42 #include "../base/check.h"
43 #endif
44 
45 
46 //=============================================================================
47 // Private Constants:
48 //=============================================================================
49 
50 //-----------------------------------------------------------------------------
51 // STACK_MAGIC: Magic number (identifies objects of this class).
52 //-----------------------------------------------------------------------------
53 
54 static const long STACK_MAGIC = 0x53544B0AL; // 'STK\n'
55 
56 //-----------------------------------------------------------------------------
57 // STACK_SIZE: Size of the array (maximal number of stack elements).
58 //-----------------------------------------------------------------------------
59 
60 // Usually sufficient:
61 // static const int STACK_SIZE = 10000;
62 
63 // For wine ontology benchmark:
64 //static const int STACK_SIZE = 100000;
65 
66 //=============================================================================
67 // Class Template for Stacks (Simple Implementation with Fixed Size Array):
68 //=============================================================================
69 
70 template<class T, int STACK_SIZE = 10000> class stack_c {
71  public:
72 
73 //-----------------------------------------------------------------------------
74 // Constructor, Destructor:
75 //-----------------------------------------------------------------------------
76 
77  // Constructor:
78  explicit stack_c(str_t name)
79  {
80  // Check parameter:
81  CHECK(name != STR_NULL, "stack_c::constructor: name is null");
82 
83  // Initialize attributes:
84  Name = name;
85  NumElems = 0;
86  StackPtr = Stack;
87 
88  // Set Magic number:
89  CHECK_CODE(Magic = STACK_MAGIC);
90  }
91 
92  // Destructor:
93  ~stack_c()
94  {
95  // Check this object:
96  CHECK_VALID("stack_c::destructor");
97 
98  // Make this object invalid:
99  CHECK_CODE(Magic = 0);
100  }
101 
102 //-----------------------------------------------------------------------------
103 // Copy-constructor and assignment operator are not supported for this class:
104 //-----------------------------------------------------------------------------
105 
106  private:
107 
108  stack_c(const stack_c& obj); // Not implemented
109  stack_c& operator=(const stack_c& obj); // Not implemented
110 
111 //=============================================================================
112 // (Object) Methods:
113 //=============================================================================
114 
115  public:
116 
117 //-----------------------------------------------------------------------------
118 // push: Put a new element on top of the stack.
119 //-----------------------------------------------------------------------------
120 
121  inline bool push(T elem) {
122 
123  // Ensure that object is valid:
124  CHECK_VALID("stack_c::push");
125 
126  // Generate error if the stack is already full:
127  if(NumElems >= STACK_SIZE) {
128  err_c::stack_overflow(Name, STACK_SIZE);
129  return false;
130  }
131 
132  // Put element on top of stack and increase number of elems:
133  NumElems++;
134  *StackPtr++ = elem;
135  return true;
136  }
137 
138 //-----------------------------------------------------------------------------
139 // pop: Get top element from the stack.
140 //-----------------------------------------------------------------------------
141 
142  inline T pop() {
143  // Ensure that object is valid:
144  CHECK_VALID("stack_c::pop");
145 
146  // This can only be called if the stack is non-empty:
147  CHECK(NumElems > 0, "stack_c::pop: Stack is empty");
148 
149  // Return topmost stack element and remove it:
150  NumElems--;
151  return *--StackPtr;
152  }
153 
154 //-----------------------------------------------------------------------------
155 // is_empty: Check whether the stack is empty.
156 //-----------------------------------------------------------------------------
157 
158  inline bool is_empty() const {
159 
160  // Ensure that object is valid:
161  CHECK_VALID("stack_c::is_empty");
162 
163  // The stack is empty if it has zero elements:
164  return NumElems == 0;
165  }
166 
167 //-----------------------------------------------------------------------------
168 // num_elems: Return current stack size (number of elements on the stack).
169 //-----------------------------------------------------------------------------
170 
171  inline int num_elems() const {
172 
173  // Ensure that object is valid:
174  CHECK_VALID("stack_c::num_elems");
175 
176  // Return number of elements on the stack:
177  return NumElems;
178  }
179 
180 //=============================================================================
181 // Debugging Support:
182 //=============================================================================
183 
184 //-----------------------------------------------------------------------------
185 // check: Check the integrity of this object, return error message or NULL.
186 //-----------------------------------------------------------------------------
187 
188 #if VER_DEBUG
189  // Integrity check:
190  public:
191  str_t check() const {
192 
193  // Check magic number:
194  if(Magic != STACK_MAGIC)
195  return "wrong magic number";
196 
197  // Check number of elements:
198  if(NumElems < 0)
199  return "NumElems is negative";
200  if(NumElems > STACK_SIZE)
201  return "NumElems is greater than the stack size";
202 
203  // Check stack pointer:
204  if(StackPtr == static_cast<T*>(0))
205  return "StackPtr is null";
206  if(StackPtr != Stack + NumElems)
207  return "StackPtr has wrong value";
208 
209  // Ok:
210  return STR_NULL;
211  }
212 
213  // Magic number (identifies objects of this class for debugging).
214  private:
215  long Magic; // Must be "STACK_MAGIC".
216 #endif
217 
218 //-----------------------------------------------------------------------------
219 // dump: Show data structure.
220 //-----------------------------------------------------------------------------
221 
222 #if VER_DUMP
223 
224  public:
225 
226 void dump(str_t headline = STR_NULL) const
227 {
228  // Headline:
229  if(headline == STR_NULL)
230  headline = "Stack";
231  err_c::dump_begin(headline);
232 
233  // Basic information:
234  err_c::dump_str("Name: '");
235  err_c::dump_str(Name);
236  err_c::dump_str("'");
237  err_c::dump_nl();
238  err_c::dump_str("NumElems: ");
239  err_c::dump_int(NumElems);
240  err_c::dump_nl();
241  err_c::dump_str("Base Addr. : ");
242  err_c::dump_ptr(Stack);
243  err_c::dump_nl();
244  err_c::dump_str("StackPtr: ");
245  err_c::dump_ptr(StackPtr);
246  err_c::dump_str(" [corresponds to index ");
247  err_c::dump_int(static_cast<int>(StackPtr - Stack));
248  err_c::dump_str("]");
249  err_c::dump_nl();
250  err_c::dump_str("Object Size: ");
251  err_c::dump_int(static_cast<int>(sizeof(stack_c<T>)));
252  err_c::dump_nl();
253  err_c::dump_nl();
254 
255  // Dump stack elements as int-values:
256  if(NumElems > 0) {
257  err_c::dump_str("Stack Contents (printed as int-values):");
258  for(int i = 0; i < NumElems; i++) {
259  err_c::dump_str(" ");
260  err_c::dump_str(str_fill(i, 3));
261  err_c::dump_int(i);
262  err_c::dump_str(": ");
263  err_c::dump_int(reinterpret_cast<int>(Stack[i]));
264  err_c::dump_nl();
265  }
266  err_c::dump_nl();
267  }
268 
269  // Done:
270  err_c::dump_end();
271 }
272 
273 #endif
274 
275 
276 //=============================================================================
277 // Private Object Members:
278 //=============================================================================
279 
280  private:
281 
282  // NumElems: Number of elements in the stack.
283  int NumElems;
284 
285  // Stack: Array for storing the elements of the stack.
286  T Stack[STACK_SIZE];
287 
288  // StackPtr: Pointer to the next (free) place in the array.
289  T *StackPtr;
290 
291  // Name: Name of stack (for use in "stack overflow" error message).
292  str_t Name;
293 
294 //=============================================================================
295 // End of Class Template:
296 //=============================================================================
297 
298 };
299 
300 
301 //=============================================================================
302 // End of Include File:
303 //=============================================================================
304 
305 #endif
306 
#define CHECK_CODE(CODE)
Definition: check.h:167
static void dump_ptr(const void *p)
Definition: err.cpp:791
static void dump_str(str_t str)
Definition: err.cpp:705
static void stack_overflow(str_t name, int curr_limit)
Definition: err.cpp:164
str_t str_fill(int n, int field_width)
Definition: str.cpp:286
Definition: stack.h:70
#define CHECK_VALID(EX)
Definition: check.h:85
static void dump_begin(str_t headline)
Definition: err.cpp:685
const char * str_t
Definition: str.h:41
#define STR_NULL
Definition: str.h:52
static void dump_end()
Definition: err.cpp:811
static void dump_int(int n)
Definition: err.cpp:739
static void dump_nl()
Definition: err.cpp:717
#define CHECK(EX, MSG)
Definition: check.h:69