My Project
Array.h
1 #pragma once
2 
3 /* this template is based on Nikolaus Gebhardt's Array Class in the "Irrlicht Engine". */
4 
6 // #define BOUNDARY_SAFE
7 namespace ParaEngine
8 {
9 
10 
12  template<class T>
13  inline void heapsink(T*array, int element, int max)
14  {
15  while ((element<<1) < max) // there is a left child
16  {
17  int j = (element<<1);
18 
19  if (j+1 < max && array[j] < array[j+1])
20  j = j+1; // take right child
21 
22  if (array[element] < array[j])
23  {
24  T t = array[j]; // swap elements
25  array[j] = array[element];
26  array[element] = t;
27  element = j;
28  }
29  else
30  return;
31  }
32  }
33 
34 
36  template<class T>
37  inline void heapsort(T* array, int size)
38  {
39  // for heapsink we pretend this is not c++, where
40  // arrays start with index 0. So we decrease the array pointer,
41  // the maximum always +2 and the element always +1
42 
43  T* virtualArray = array - 1;
44  int virtualSize = size + 2;
45  int i;
46 
47  // build heap
48 
49  for (i=((size-1)/2); i>=0; --i)
50  heapsink(virtualArray, i+1, virtualSize-1);
51 
52  // sort array
53 
54  for (i=size-1; i>=0; --i)
55  {
56  T t = array[0];
57  array[0] = array[i];
58  array[i] = t;
59  heapsink(virtualArray, 1, i + 1);
60  }
61  }
62 
64 
66  template <class T>
67  class array
68  {
69 
70  public:
71 
72  array()
73  : data(0), used(0), allocated(0),
74  free_when_destroyed(true), is_sorted(true)
75  {
76  }
77 
80  array(DWORD start_count)
81  : data(0), used(0), allocated(0),
82  free_when_destroyed(true), is_sorted(true)
83  {
84  reallocate(start_count);
85  }
86 
87 
90  : data(0)
91  {
92  *this = other;
93  }
94 
95 
96 
100  {
101  if (free_when_destroyed)
102  delete [] data;
103  }
104 
105 
106 
109  void reallocate(DWORD new_size)
110  {
111  T* old_data = data;
112 
113  data = new T[new_size];
114  allocated = new_size;
115 
116  int end = used < new_size ? used : new_size;
117  for (int i=0; i<end; ++i)
118  data[i] = old_data[i];
119 
120  if (allocated < used)
121  used = allocated;
122 
123  delete [] old_data;
124  }
125 
126 
127 
131  void push_back(const T& element)
132  {
133  if (used + 1 > allocated)
134  reallocate(used * 2 +1);
135 
136  data[used++] = element;
137  is_sorted = false;
138  }
139 
140 
141 
143  void clear()
144  {
145  delete [] data;
146  data = 0;
147  used = 0;
148  allocated = 0;
149  is_sorted = true;
150  }
151 
152 
153 
157  void set_pointer(T* newPointer, DWORD size)
158  {
159  delete [] data;
160  data = newPointer;
161  allocated = size;
162  used = size;
163  is_sorted = false;
164  }
165 
166 
167 
172  {
173  free_when_destroyed = f;
174  }
175 
176 
177 
180  void set_used(DWORD usedNow)
181  {
182  if (allocated < usedNow)
183  reallocate(usedNow);
184 
185  used = usedNow;
186  }
187 
188 
189 
191  void operator=(const array<T>& other)
192  {
193  if (data)
194  delete [] data;
195 
196  //if (allocated < other.allocated)
197  if (other.allocated == 0)
198  data = 0;
199  else
200  data = new T[other.allocated];
201 
202  used = other.used;
203  free_when_destroyed = other.free_when_destroyed;
204  is_sorted = other.is_sorted;
205  allocated = other.allocated;
206 
207  for (DWORD i=0; i<other.used; ++i)
208  data[i] = other.data[i];
209  }
210 
211 
213  T& operator [](DWORD index)
214  {
215 #ifdef BOUNDARY_SAFE
216  if (index>=used)
217  return; // access violation
218 #endif
219 
220  return data[index];
221  }
222 
223 
224 
226  const T& operator [](DWORD index) const
227  {
228 #ifdef BOUNDARY_SAFE
229  if (index>=used)
230  return; // access violation
231 #endif
232 
233  return data[index];
234  }
235 
237  const T& getLast() const
238  {
239 #ifdef BOUNDARY_SAFE
240  if (!used)
241  return; // access violation
242 #endif
243 
244  return data[used-1];
245  }
246 
248  T& getLast()
249  {
250 #ifdef BOUNDARY_SAFE
251  if (!used)
252  return; // access violation
253 #endif
254 
255  return data[used-1];
256  }
257 
258 
261  T* pointer()
262  {
263  return data;
264  }
265 
266 
267 
270  const T* const_pointer() const
271  {
272  return data;
273  }
274 
275 
276 
279  DWORD size() const
280  {
281  return used;
282  }
283 
284 
285 
289  DWORD allocated_size() const
290  {
291  return allocated;
292  }
293 
294 
295 
298  bool empty() const
299  {
300  return used == 0;
301  }
302 
303 
304 
307  void sort()
308  {
309  if (is_sorted || used<2)
310  return;
311 
312  heapsort(data, used);
313  is_sorted = true;
314  }
315 
316 
317 
324  int binary_search(const T& element)
325  {
326  return binary_search(element, 0, used-1);
327  }
328 
329 
330 
339  int binary_search(const T& element, int left, int right)
340  {
341  if (!used)
342  return -1;
343 
344  sort();
345 
346  int m;
347 
348  do
349  {
350  m = (left+right)>>1;
351 
352  if (element < data[m])
353  right = m - 1;
354  else
355  left = m + 1;
356 
357  } while((element < data[m] || data[m] < element) && left<=right);
358 
359  // this last line equals to:
360  // " while((element != array[m]) && left<=right);"
361  // but we only want to use the '<' operator.
362  // the same in next line, it is "(element == array[m])"
363 
364  if (!(element < data[m]) && !(data[m] < element))
365  return m;
366 
367  return -1;
368  }
369 
370 
376  int linear_search(T& element)
377  {
378  for (DWORD i=0; i<used; ++i)
379  if (!(element < data[i]) && !(data[i] < element))
380  return (int)i;
381 
382  return -1;
383  }
384 
385 
391  int linear_reverse_search(T& element)
392  {
393  for (int i=used-1; i>=0; --i)
394  if (data[i] == element)
395  return (int)i;
396 
397  return -1;
398  }
399 
400 
401 
405  void erase(DWORD index)
406  {
407 #ifdef BOUNDARY_SAFE
408  if (index>=used || index<0)
409  return; // access violation
410 #endif
411 
412  for (DWORD i=index+1; i<used; ++i)
413  data[i-1] = data[i];
414 
415  --used;
416  }
417 
418 
423  void erase(DWORD index, int count)
424  {
425 #ifdef BOUNDARY_SAFE
426  if (index>=used || index<0 || count<1 || index+count>used)
427  return; // access violation
428 #endif
429 
430  for (DWORD i=index+count; i<used; ++i)
431  data[i-count] = data[i];
432 
433  used-= count;
434  }
435 
436 
438  void set_sorted(bool _is_sorted)
439  {
440  is_sorted = _is_sorted;
441  }
442 
443 
444  private:
445 
446  T* data;
447  DWORD allocated;
448  DWORD used;
449  bool free_when_destroyed;
450  bool is_sorted;
451  };
452 
453 }
const T * const_pointer() const
Returns a const pointer to the array.
Definition: Array.h:270
const T & getLast() const
Gets last frame.
Definition: Array.h:237
void sort()
Sorts the array using heapsort.
Definition: Array.h:307
void clear()
Clears the array and deletes all allocated memory.
Definition: Array.h:143
void reallocate(DWORD new_size)
Reallocates the array, make it bigger or smaller.
Definition: Array.h:109
void set_pointer(T *newPointer, DWORD size)
Sets pointer to new array, using this as new workspace.
Definition: Array.h:157
void heapsink(T *array, int element, int max)
Sinks an element into the heap.
Definition: Array.h:13
T * pointer()
Returns a pointer to the array.
Definition: Array.h:261
DWORD size() const
Returns size of used array.
Definition: Array.h:279
void set_sorted(bool _is_sorted)
Sets if the array is sorted.
Definition: Array.h:438
different physics engine has different winding order.
Definition: EventBinding.h:32
void push_back(const T &element)
Adds an element at back of array.
Definition: Array.h:131
int linear_reverse_search(T &element)
Finds an element in linear time, which is very slow.
Definition: Array.h:391
DWORD allocated_size() const
Returns amount memory allocated.
Definition: Array.h:289
int linear_search(T &element)
Finds an element in linear time, which is very slow.
Definition: Array.h:376
void erase(DWORD index, int count)
Erases some elements from the array.
Definition: Array.h:423
Definition: other.hpp:41
T & getLast()
Gets last frame.
Definition: Array.h:248
bool empty() const
Returns true if array is empty.
Definition: Array.h:298
array(const array< T > &other)
Copy constructor.
Definition: Array.h:89
T & operator[](DWORD index)
Direct access operator.
Definition: Array.h:213
void erase(DWORD index)
Erases an element from the array.
Definition: Array.h:405
~array()
Destructor.
Definition: Array.h:99
void heapsort(T *array, int size)
Sorts an array with size &#39;size&#39; using heapsort.
Definition: Array.h:37
Self reallocating template array (like stl vector) with additional features.
Definition: Array.h:67
void set_free_when_destroyed(bool f)
Sets if the array should delete the memory it used.
Definition: Array.h:171
void operator=(const array< T > &other)
Assignment operator.
Definition: Array.h:191
array(DWORD start_count)
Constructs a array and allocates an initial chunk of memory.
Definition: Array.h:80
int binary_search(const T &element)
Performs a binary search for an element, returns -1 if not found.
Definition: Array.h:324
void set_used(DWORD usedNow)
Sets the size of the array.
Definition: Array.h:180
int binary_search(const T &element, int left, int right)
Performs a binary search for an element, returns -1 if not found.
Definition: Array.h:339