Gnash  0.8.11dev
SafeStack.h
Go to the documentation of this file.
1 // SafeStack.h A stack which doesn't drop or free references until explicitly
2 // asked to do so, so that values outside of the stack are guaranteed good
3 // in an appropriate scope.
4 //
5 // Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012
6 // Free Software Foundation, Inc.
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 3 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the Free Software
20 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #ifndef GNASH_SAFESTACK_H
22 #define GNASH_SAFESTACK_H
23 
24 
25 #include <vector>
26 
27 namespace gnash {
28 
29 class StackException {};
30 
40 template <class T>
41 class SafeStack
42 {
43 
44  typedef std::vector<T*> StackType;
45 
46 public:
47 
48  // May be useful for callers to know.
49  typedef typename StackType::size_type StackSize;
50 
52  //
54  const T& top(StackSize i) const
55  {
56 
57  if (i >= size()) throw StackException();
58  const StackSize offset = _end - i;
59  return _data[offset >> _chunkShift][offset & _chunkMod];
60  }
61 
63  //
66  T& top(StackSize i)
67  {
68 
69  if (i >= size()) throw StackException();
70  const StackSize offset = _end - i;
71  return _data[offset >> _chunkShift][offset & _chunkMod];
72  }
73 
75  //
77  const T& at(StackSize i) const
78  {
79 
80  if (i >= totalSize()) throw StackException();
81  const StackSize offset = _end - i;
82  return _data[offset >> _chunkShift][offset & _chunkMod];
83  }
84 
85 
87  //
90  T& at(StackSize i)
91  {
92 
93  if (i >= totalSize()) throw StackException();
94  const StackSize offset = _end - i;
95  return _data[offset >> _chunkShift][offset & _chunkMod];
96  }
97 
100  T& value(StackSize i)
101  {
102  if (i >= size()) throw StackException();
103 
104  StackSize offset = _downstop + i + 2;
105  return _data[offset >> _chunkShift][offset & _chunkMod];
106  }
107 
108  const T& value(StackSize i) const
109  {
110  if (i >= size()) throw StackException();
111 
112  StackSize offset = _downstop + i + 2;
113  return _data[offset >> _chunkShift][offset & _chunkMod];
114  }
115 
117  void assign(StackSize i, T val)
118  {
119  if (i >= size()) throw StackException();
120 
121  StackSize offset = _downstop + i + 2;
122  _data[offset >> _chunkShift][offset & _chunkMod] = val;
123  }
124 
128  void drop(StackSize i) {
129  if (i > size()) throw StackException();
130  _end -= i;
131  }
132 
134  void clear() {
135  _downstop = 0;
136  _end = 1;
137  }
138 
141  void push(const T& t) {
142  grow(1);
143  top(0) = t;
144  }
145 
147  T& pop() {
148  T& ret = top(0);
149  drop(1);
150  return ret;
151  }
152 
155  void grow(StackSize i)
156  {
157  StackSize available = (1 << _chunkShift) * _data.size() - _end + 1;
158  StackSize n = size()+i;
159  while (available < n)
160  {
161  //log_debug("Increasing size of the real stack: %d.",_data.size());
162  _data.push_back(new T[1 << _chunkShift]);
163  available += 1 << _chunkShift;
164  }
165  _end += i;
166  }
167 
169  StackSize getDownstop() const
170  {
171  return _downstop;
172  }
173 
175  StackSize size() const { return _end - _downstop - 1; }
176 
178  bool empty() const { return size() == 0; }
179 
183  StackSize fixDownstop()
184  {
185  StackSize ret = _downstop;
186  _downstop = _end - 1;
187  return ret;
188  }
189 
192  void setDownstop(StackSize i)
193  {
194  if (i > _end) throw StackException();
195  _downstop = i;
196  }
197 
199  //
202  StackSize totalSize() const { return _end - 1; }
203 
206  void setAllSizes(StackSize total, StackSize downstop)
207  {
208  _end = total + 1;
209  _downstop = downstop;
210  }
211 
213  SafeStack() : _data(), _downstop(0), _end(1) {}
214 
217  {
218  for (auto& elem : _data) delete [] elem;
219  }
220 
221 private:
222  StackType _data;
223  StackSize _downstop;
224  StackSize _end;
225 
226  // If _chunkMod is not a power of 2 less 1, it will not work properly.
227  static const StackSize _chunkShift = 6;
228  static const StackSize _chunkMod = (1 << _chunkShift) - 1;
229 };
230 
231 } // namespace gnash
232 #endif
T & at(StackSize i)
From the top of the stack, get the i&#39;th value down.
Definition: SafeStack.h:90
void setAllSizes(StackSize total, StackSize downstop)
Definition: SafeStack.h:206
void assign(StackSize i, T val)
Assign a value to given index counting from bottom.
Definition: SafeStack.h:117
void clear()
Drop all stack elements reguardless of the "downstop".
Definition: SafeStack.h:134
void setDownstop(StackSize i)
Definition: SafeStack.h:192
T & top(StackSize i)
From the top of the stack, get the i&#39;th value down.
Definition: SafeStack.h:66
StackType::size_type StackSize
Definition: SafeStack.h:49
SafeStack()
Default constructor.
Definition: SafeStack.h:213
~SafeStack()
Delete the allocated data.
Definition: SafeStack.h:216
Anonymous namespace for callbacks, local functions, event handlers etc.
Definition: dbus_ext.cpp:40
Definition: SafeStack.h:41
Definition: GnashKey.h:160
const T & value(StackSize i) const
Definition: SafeStack.h:108
void grow(StackSize i)
Definition: SafeStack.h:155
Definition: GnashKey.h:166
Definition: SafeStack.h:29
const T & top(StackSize i) const
From the top of the stack, get the i&#39;th value down.
Definition: SafeStack.h:54
StackSize getDownstop() const
Gives the size of the stack which is currently accessible.
Definition: SafeStack.h:169
T & value(StackSize i)
Definition: SafeStack.h:100
T & pop()
Pop the top of the stack.
Definition: SafeStack.h:147
void drop(StackSize i)
Definition: SafeStack.h:128
Definition: GnashKey.h:132
Definition: GnashKey.h:155
void push(const T &t)
Definition: SafeStack.h:141
const T & at(StackSize i) const
From the top of the stack, get the i&#39;th value down.
Definition: SafeStack.h:77
StackSize fixDownstop()
Definition: SafeStack.h:183
bool empty() const
Is the stack empty to us? (Check totalSize() != for actually empty)
Definition: SafeStack.h:178
StackSize totalSize() const
Return the complete stack size, including non-accessible elements.
Definition: SafeStack.h:202
StackSize size() const
Alias for getDownstop()
Definition: SafeStack.h:175