TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Queue.h
Go to the documentation of this file.
1 
10 #ifndef G3D_Queue_h
11 #define G3D_Queue_h
12 
13 #include "G3D/platform.h"
14 #include "G3D/System.h"
15 #include "G3D/debug.h"
16 
17 namespace G3D {
18 
29 #define FIND_ENDS \
30  int firstEnd = head + num;\
31  int secondEnd = 0;\
32  if (firstEnd > numAllocated) {\
33  secondEnd = firstEnd - numAllocated;\
34  firstEnd = numAllocated;\
35  }
36 
37 
43 template <class T>
44 class Queue {
45 private:
46  //
47  // |<---- num ---->|
48  // [ | | | | | | | | | | | | | ]
49  // ^
50  // |
51  // head
52  //
53  //
54 
58  T* data;
59 
63  int head;
64 
68  int num;
69 
74 
76  void _copy(const Queue& other) {
77  debugAssert(data == NULL);
78  data = (T*)System::malloc(sizeof(T) * other.numAllocated);
79  debugAssert(data);
80  head = other.head;
81  num = other.num;
82  numAllocated = other.numAllocated;
83 
84  FIND_ENDS;
85 
86  for (int i = head; i < firstEnd; ++i) {
87  new (data + i)T(other.data[i]);
88  }
89 
90  for (int i = 0; i < secondEnd; ++i) {
91  new (data + i)T(other.data[i]);
92  }
93  }
94 
95 
100  inline int index(int i) const {
101  return (head + i + numAllocated) % numAllocated;
102  }
103 
107  void repackAndRealloc(int newSize) {
108  // TODO: shrink queue
109  T* old = data;
110  data = (T*)System::malloc(newSize * sizeof(T));
111  debugAssert(data != NULL);
112 
113  FIND_ENDS;
114 
115  int j = 0;
116  for (int i = head; i < firstEnd; ++i, ++j) {
117  new (data + j)T(old[i]);
118  (old + i)->~T();
119  }
120 
121  for (int i = 0; i < secondEnd; ++i, ++j) {
122  new (data + j)T(old[i]);
123  (old + i)->~T();
124  }
125 
126  head = 0;
127  System::free(old);
128  numAllocated = newSize;
129  }
130 
136  inline void reserveSpace() {
137  if (num == numAllocated) {
138  repackAndRealloc(numAllocated * 3 + 20);
139  }
140  }
141 
142 public:
143 
144  Queue() :
145  data(NULL),
146  head(0),
147  num(0),
148  numAllocated(0) {
149  }
150 
151 
155  Queue(const Queue& other) : data(NULL) {
156  _copy(other);
157  }
158 
159 
166  virtual ~Queue() {
167  clear();
168  }
169 
174  inline void pushFront(const T& e) {
175  reserveSpace();
176 
177  // Get the index of head-1
178  int i = index(-1);
179 
180  // Call the constructor on the newly exposed element.
181  new (data + i)T(e);
182 
183  // Reassign the head to point to this index
184  head = i;
185  ++num;
186  }
187 
191  inline void pushBack(const T& e) {
192  reserveSpace();
193 
194  // Get the index of 1+tail
195  int i = index(num);
196 
197  // Initialize that element
198  new (data + i)T(e);
199  ++num;
200  }
201 
205  inline void enqueue(const T& e) {
206  pushBack(e);
207  }
208 
209 
214  inline T popBack() {
215  int tail = index(num - 1);
216  T result(data[tail]);
217 
218  // Call the destructor
219  (data + tail)->~T();
220  --num;
221 
222  return result;
223  }
224 
228  inline T popFront() {
229  T result(data[head]);
230  // Call the destructor
231  (data + head)->~T();
232  head = (head + 1) % numAllocated;
233  --num;
234  return result;
235  }
236 
237 
241  inline T dequeue() {
242  return popFront();
243  }
244 
253  void clear(bool freeStorage = true) {
254 
255  FIND_ENDS;
256 
257  // Invoke the destructors on the elements
258  int i;
259  for (i = head; i < firstEnd; ++i) {
260  (data + i)->~T();
261  }
262 
263  for (i = 0; i < secondEnd; ++i) {
264  (data + i)->~T();
265  }
266 
267  num = 0;
268  head = 0;
269  if (freeStorage) {
270  numAllocated = 0;
271  System::free(data);
272  data = NULL;
273  }
274  }
275 
277  void fastClear() {
278  clear(false);
279  }
280 
284  Queue& operator=(const Queue& other) {
285  clear();
286  _copy(other);
287  return *this;
288  }
289 
293  inline int size() const {
294  return num;
295  }
296 
300  inline int length() const {
301  return size();
302  }
303 
307  inline T& operator[](int n) {
308  debugAssert((n >= 0) && (n < num));
309  return data[index(n)];
310  }
311 
315  inline const T& operator[](int n) const {
316  debugAssert((n >= 0) && (n < num));
317  return data[index(n)];
318  }
319 
320 
322  inline const T& last() const {
323  return (*this)[size() - 1];
324  }
325 
326  inline T& last() {
327  return (*this)[size() - 1];
328  }
329 
330  bool empty() const {
331  return size() == 0;
332  }
333 
337  bool contains(const T& e) const {
338  for (int i = 0; i < size(); ++i) {
339  if ((*this)[i] == e) {
340  return true;
341  }
342  }
343 
344  return false;
345  }
346 
351  void deleteAll() {
352  FIND_ENDS;
353 
354  int i;
355  for (i = 0; i < secondEnd; ++i) {
356  delete data[i];
357  }
358 
359  for (i = head; i < firstEnd; ++i) {
360  delete data[i];
361  }
362  clear();
363  }
364 };
365 
366 #undef FIND_ENDS
367 
368 }; // namespace
369 
370 #endif
void enqueue(const T &e)
Definition: Queue.h:205
void reserveSpace()
Definition: Queue.h:136
bool empty() const
Definition: Queue.h:330
void fastClear()
Definition: Queue.h:277
#define FIND_ENDS
Definition: Queue.h:29
int size() const
Definition: Queue.h:293
Definition: AABox.h:25
arena_t NULL
Definition: jemalloc_internal.h:624
T * data
Definition: Queue.h:58
T & last()
Definition: Queue.h:326
void pushBack(const T &e)
Definition: Queue.h:191
virtual ~Queue()
Definition: Queue.h:166
int length() const
Definition: Queue.h:300
void repackAndRealloc(int newSize)
Definition: Queue.h:107
static void * malloc(size_t bytes)
Definition: System.cpp:1441
const T & last() const
Definition: Queue.h:322
T & operator[](int n)
Definition: Queue.h:307
void clear(bool freeStorage=true)
Definition: Queue.h:253
void deleteAll()
Definition: Queue.h:351
T popFront()
Definition: Queue.h:228
int numAllocated
Definition: Queue.h:73
#define debugAssert(exp)
Definition: debugAssert.h:160
Definition: Queue.h:44
void pushFront(const T &e)
Definition: Queue.h:174
void _copy(const Queue &other)
Definition: Queue.h:76
static void free(void *p)
Definition: System.cpp:1473
Queue()
Definition: Queue.h:144
bool contains(const T &e) const
Definition: Queue.h:337
const T & operator[](int n) const
Definition: Queue.h:315
Queue & operator=(const Queue &other)
Definition: Queue.h:284
Queue(const Queue &other)
Definition: Queue.h:155
int num
Definition: Queue.h:68
int index(int i) const
Definition: Queue.h:100
T dequeue()
Definition: Queue.h:241
T popBack()
Definition: Queue.h:214
int head
Definition: Queue.h:63