feisty meow concerns codebase  2.140
stack.h
Go to the documentation of this file.
1 #ifndef STACK_CLASS
2 #define STACK_CLASS
3 
4 /*****************************************************************************\
5 * *
6 * Name : stack *
7 * Author : Chris Koeritz *
8 * *
9 *******************************************************************************
10 * Copyright (c) 1990-$now By Author. This program is free software; you can *
11 * redistribute it and/or modify it under the terms of the GNU General Public *
12 * License as published by the Free Software Foundation; either version 2 of *
13 * the License or (at your option) any later version. This is online at: *
14 * http://www.fsf.org/copyleft/gpl.html *
15 * Please send any updates to: fred@gruntose.com *
16 \*****************************************************************************/
17 
18 #include <basis/array.h>
19 
20 namespace structures {
21 
23 
28 template <class contents>
29 class stack
30 {
31 public:
33 
34  stack(int elements = 0);
36 
45  stack(const stack &to_copy);
47 
48  ~stack();
50 
51  void reset();
53 
54  stack_kinds kind() const { return _kind; }
56 
57  basis::outcome push(const contents &element);
59 
65 
68  contents &top();
70 
73  basis::outcome acquire_pop(contents &to_stuff);
75 
78  int size() const;
80 
82  stack &operator =(const stack &to_copy);
84 
85  contents &operator [](int index);
87 
92  void invert();
94 
95  int elements() const;
97 
102 private:
103  basis::array<contents> _store;
104  stack_kinds _kind;
105  int _valid_fields;
106 };
107 
109 
110 // implementations below...
111 
112 template <class contents>
114 : _store(elements >= 0? elements : 0),
115  _kind(_store.length()? BOUNDED : UNBOUNDED),
116  _valid_fields(0)
117 {}
118 
119 template <class contents>
121 : _store(0), _valid_fields(0)
122 { operator = (to_copy); }
123 
124 template <class contents> stack<contents>::~stack() {}
125 
126 template <class contents>
127 int stack<contents>::size() const { return _valid_fields; }
128 
129 template <class contents>
131 {
132  while (pop() == basis::common::OKAY) {} // pop off elements until all are gone.
133 }
134 
135 template <class contents>
136 int stack<contents>::elements() const { return _store.length(); }
137 
138 template <class contents>
139 basis::outcome stack<contents>::push(const contents &element)
140 {
141  if (_kind == BOUNDED) {
142  if (_valid_fields >= elements()) return basis::common::IS_FULL;
143  basis::outcome result = _store.put(_valid_fields, element);
144  if (result != basis::common::OKAY) return basis::common::IS_FULL;
145  } else _store.concatenate(element);
146  _valid_fields++;
147  return basis::common::OKAY;
148 }
149 
150 template <class contents>
152 {
153  if (_valid_fields < 1) return basis::common::IS_EMPTY;
154  if (_kind == UNBOUNDED)
155  _store.zap(_store.length() - 1, _store.length() - 1);
156  _valid_fields--;
157  return basis::common::OKAY;
158 }
159 
160 template <class contents>
162 { return _store[_valid_fields - 1]; }
163 
164 template <class contents>
166 {
167  if (this == &to_copy) return *this;
168  reset();
169  _kind = to_copy._kind;
170  _store.reset(to_copy._store.length());
171  for (int i = 0; i < to_copy._store.length(); i++)
172  _store.put(i, to_copy._store[i]);
173  _valid_fields = to_copy._valid_fields;
174  return *this;
175 }
176 
177 template <class contents>
179 {
180  for (int i = 0; i < _store.length() / 2; i++) {
181  contents hold = _store.get(i);
182  int exchange_index = _store.length() - i - 1;
183  _store.put(i, _store.get(exchange_index));
184  _store.put(exchange_index, hold);
185  }
186 }
187 
188 template <class contents>
189 contents &stack<contents>::operator [](int index)
190 {
191  if (index >= _valid_fields) index = -1; // force a bogus return.
192  return _store[index];
193 }
194 
195 template <class contents>
197 {
198  if (!_valid_fields) return basis::common::IS_EMPTY;
199  to_stuff = _store[_valid_fields - 1];
200  if (_kind == UNBOUNDED) _store.zap(elements()-1, elements()-1);
201  _valid_fields--;
202  return basis::common::OKAY;
203 }
204 
205 } //namespace.
206 
207 #endif
208 
Represents a sequential, ordered, contiguous collection of objects.
Definition: array.h:54
Outcomes describe the state of completion for an operation.
Definition: outcome.h:31
An abstraction that represents a stack data structure.
Definition: stack.h:30
basis::outcome push(const contents &element)
Enters a new element onto the top of the stack.
Definition: stack.h:139
void reset()
throws out all contents on the stack.
Definition: stack.h:130
stack & operator=(const stack &to_copy)
makes this stack a copy of "to_copy".
Definition: stack.h:165
int elements() const
Returns the number of elements used by the stack.
Definition: stack.h:136
stack(const stack &to_copy)
constructs a stack as a copy of "to_copy".
Definition: stack.h:120
stack(int elements=0)
Creates a stack with room for the specified number of "elements".
Definition: stack.h:113
contents & operator[](int index)
Accesses the item at position "index" in the stack.
Definition: stack.h:189
basis::outcome acquire_pop(contents &to_stuff)
Used to grab the top off of the stack.
Definition: stack.h:196
void invert()
Inverts this stack, meaning that the old bottom is the new top.
Definition: stack.h:178
int size() const
returns the size of the stack.
Definition: stack.h:127
~stack()
destroys anything left on the stack.
Definition: stack.h:124
contents & top()
Returns the top element from the stack but doesn't change the stack.
Definition: stack.h:161
stack_kinds kind() const
returns the type of stack that was constructed.
Definition: stack.h:54
basis::outcome pop()
Removes the top element on the stack.
Definition: stack.h:151
A dynamic container class that holds any kind of object via pointers.
Definition: amorph.h:55