Bullet Collision Detection & Physics Library
btAlignedObjectArray.h
Go to the documentation of this file.
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
4 
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose,
8 including commercial applications, and to alter it and redistribute it freely,
9 subject to the following restrictions:
10 
11 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
14 */
15 
16 
17 #ifndef BT_OBJECT_ARRAY__
18 #define BT_OBJECT_ARRAY__
19 
20 #include "btScalar.h" // has definitions like SIMD_FORCE_INLINE
21 #include "btAlignedAllocator.h"
22 
28 
29 #define BT_USE_PLACEMENT_NEW 1
30 //#define BT_USE_MEMCPY 1 //disable, because it is cumbersome to find out for each platform where memcpy is defined. It can be in <memory.h> or <string.h> or otherwise...
31 #define BT_ALLOW_ARRAY_COPY_OPERATOR // enabling this can accidently perform deep copies of data if you are not careful
32 
33 #ifdef BT_USE_MEMCPY
34 #include <memory.h>
35 #include <string.h>
36 #endif //BT_USE_MEMCPY
37 
38 #ifdef BT_USE_PLACEMENT_NEW
39 #include <new> //for placement new
40 #endif //BT_USE_PLACEMENT_NEW
41 
42 
45 template <typename T>
46 //template <class T>
48 {
50 
51  int m_size;
53  T* m_data;
54  //PCK: added this line
56 
57 #ifdef BT_ALLOW_ARRAY_COPY_OPERATOR
58 public:
60  {
61  copyFromArray(other);
62  return *this;
63  }
64 #else//BT_ALLOW_ARRAY_COPY_OPERATOR
65 private:
67 #endif//BT_ALLOW_ARRAY_COPY_OPERATOR
68 
69 protected:
71  {
72  return (size ? size*2 : 1);
73  }
74  SIMD_FORCE_INLINE void copy(int start,int end, T* dest) const
75  {
76  int i;
77  for (i=start;i<end;++i)
79  new (&dest[i]) T(m_data[i]);
80 #else
81  dest[i] = m_data[i];
82 #endif //BT_USE_PLACEMENT_NEW
83  }
84 
86  {
87  //PCK: added this line
88  m_ownsMemory = true;
89  m_data = 0;
90  m_size = 0;
91  m_capacity = 0;
92  }
93  SIMD_FORCE_INLINE void destroy(int first,int last)
94  {
95  int i;
96  for (i=first; i<last;i++)
97  {
98  m_data[i].~T();
99  }
100  }
101 
103  {
104  if (size)
105  return m_allocator.allocate(size);
106  return 0;
107  }
108 
110  {
111  if(m_data) {
112  //PCK: enclosed the deallocation in this block
113  if (m_ownsMemory)
114  {
116  }
117  m_data = 0;
118  }
119  }
120 
121 
122 
123 
124  public:
125 
127  {
128  init();
129  }
130 
132  {
133  clear();
134  }
135 
138  {
139  init();
140 
141  int otherSize = otherArray.size();
142  resize (otherSize);
143  otherArray.copy(0, otherSize, m_data);
144  }
145 
146 
147 
150  {
151  return m_size;
152  }
153 
154  SIMD_FORCE_INLINE const T& at(int n) const
155  {
156  btAssert(n>=0);
157  btAssert(n<size());
158  return m_data[n];
159  }
160 
162  {
163  btAssert(n>=0);
164  btAssert(n<size());
165  return m_data[n];
166  }
167 
168  SIMD_FORCE_INLINE const T& operator[](int n) const
169  {
170  btAssert(n>=0);
171  btAssert(n<size());
172  return m_data[n];
173  }
174 
176  {
177  btAssert(n>=0);
178  btAssert(n<size());
179  return m_data[n];
180  }
181 
182 
185  {
186  destroy(0,size());
187 
188  deallocate();
189 
190  init();
191  }
192 
194  {
195  btAssert(m_size>0);
196  m_size--;
197  m_data[m_size].~T();
198  }
199 
200 
204  {
205  int curSize = size();
206 
207  if (newsize < curSize)
208  {
209  } else
210  {
211  if (newsize > size())
212  {
213  reserve(newsize);
214  }
215  //leave this uninitialized
216  }
217  m_size = newsize;
218  }
219 
220  SIMD_FORCE_INLINE void resize(int newsize, const T& fillData=T())
221  {
222  int curSize = size();
223 
224  if (newsize < curSize)
225  {
226  for(int i = newsize; i < curSize; i++)
227  {
228  m_data[i].~T();
229  }
230  } else
231  {
232  if (newsize > size())
233  {
234  reserve(newsize);
235  }
236 #ifdef BT_USE_PLACEMENT_NEW
237  for (int i=curSize;i<newsize;i++)
238  {
239  new ( &m_data[i]) T(fillData);
240  }
241 #endif //BT_USE_PLACEMENT_NEW
242 
243  }
244 
245  m_size = newsize;
246  }
248  {
249  int sz = size();
250  if( sz == capacity() )
251  {
252  reserve( allocSize(size()) );
253  }
254  m_size++;
255 
256  return m_data[sz];
257  }
258 
259 
260  SIMD_FORCE_INLINE T& expand( const T& fillValue=T())
261  {
262  int sz = size();
263  if( sz == capacity() )
264  {
265  reserve( allocSize(size()) );
266  }
267  m_size++;
268 #ifdef BT_USE_PLACEMENT_NEW
269  new (&m_data[sz]) T(fillValue); //use the in-place new (not really allocating heap memory)
270 #endif
271 
272  return m_data[sz];
273  }
274 
275 
276  SIMD_FORCE_INLINE void push_back(const T& _Val)
277  {
278  int sz = size();
279  if( sz == capacity() )
280  {
281  reserve( allocSize(size()) );
282  }
283 
284 #ifdef BT_USE_PLACEMENT_NEW
285  new ( &m_data[m_size] ) T(_Val);
286 #else
287  m_data[size()] = _Val;
288 #endif //BT_USE_PLACEMENT_NEW
289 
290  m_size++;
291  }
292 
293 
296  {
297  return m_capacity;
298  }
299 
300  SIMD_FORCE_INLINE void reserve(int _Count)
301  { // determine new minimum length of allocated storage
302  if (capacity() < _Count)
303  { // not enough room, reallocate
304  T* s = (T*)allocate(_Count);
305 
306  copy(0, size(), s);
307 
308  destroy(0,size());
309 
310  deallocate();
311 
312  //PCK: added this line
313  m_ownsMemory = true;
314 
315  m_data = s;
316 
317  m_capacity = _Count;
318 
319  }
320  }
321 
322 
323  class less
324  {
325  public:
326 
327  bool operator() ( const T& a, const T& b )
328  {
329  return ( a < b );
330  }
331  };
332 
333 
334  template <typename L>
335  void quickSortInternal(const L& CompareFunc,int lo, int hi)
336  {
337  // lo is the lower index, hi is the upper index
338  // of the region of array a that is to be sorted
339  int i=lo, j=hi;
340  T x=m_data[(lo+hi)/2];
341 
342  // partition
343  do
344  {
345  while (CompareFunc(m_data[i],x))
346  i++;
347  while (CompareFunc(x,m_data[j]))
348  j--;
349  if (i<=j)
350  {
351  swap(i,j);
352  i++; j--;
353  }
354  } while (i<=j);
355 
356  // recursion
357  if (lo<j)
358  quickSortInternal( CompareFunc, lo, j);
359  if (i<hi)
360  quickSortInternal( CompareFunc, i, hi);
361  }
362 
363 
364  template <typename L>
365  void quickSort(const L& CompareFunc)
366  {
367  //don't sort 0 or 1 elements
368  if (size()>1)
369  {
370  quickSortInternal(CompareFunc,0,size()-1);
371  }
372  }
373 
374 
376  template <typename L>
377  void downHeap(T *pArr, int k, int n, const L& CompareFunc)
378  {
379  /* PRE: a[k+1..N] is a heap */
380  /* POST: a[k..N] is a heap */
381 
382  T temp = pArr[k - 1];
383  /* k has child(s) */
384  while (k <= n/2)
385  {
386  int child = 2*k;
387 
388  if ((child < n) && CompareFunc(pArr[child - 1] , pArr[child]))
389  {
390  child++;
391  }
392  /* pick larger child */
393  if (CompareFunc(temp , pArr[child - 1]))
394  {
395  /* move child up */
396  pArr[k - 1] = pArr[child - 1];
397  k = child;
398  }
399  else
400  {
401  break;
402  }
403  }
404  pArr[k - 1] = temp;
405  } /*downHeap*/
406 
407  void swap(int index0,int index1)
408  {
409 #ifdef BT_USE_MEMCPY
410  char temp[sizeof(T)];
411  memcpy(temp,&m_data[index0],sizeof(T));
412  memcpy(&m_data[index0],&m_data[index1],sizeof(T));
413  memcpy(&m_data[index1],temp,sizeof(T));
414 #else
415  T temp = m_data[index0];
416  m_data[index0] = m_data[index1];
417  m_data[index1] = temp;
418 #endif //BT_USE_PLACEMENT_NEW
419 
420  }
421 
422  template <typename L>
423  void heapSort(const L& CompareFunc)
424  {
425  /* sort a[0..N-1], N.B. 0 to N-1 */
426  int k;
427  int n = m_size;
428  for (k = n/2; k > 0; k--)
429  {
430  downHeap(m_data, k, n, CompareFunc);
431  }
432 
433  /* a[1..N] is now a heap */
434  while ( n>=1 )
435  {
436  swap(0,n-1); /* largest of a[0..n-1] */
437 
438 
439  n = n - 1;
440  /* restore a[1..i-1] heap */
441  downHeap(m_data, 1, n, CompareFunc);
442  }
443  }
444 
446  int findBinarySearch(const T& key) const
447  {
448  int first = 0;
449  int last = size()-1;
450 
451  //assume sorted array
452  while (first <= last) {
453  int mid = (first + last) / 2; // compute mid point.
454  if (key > m_data[mid])
455  first = mid + 1; // repeat search in top half.
456  else if (key < m_data[mid])
457  last = mid - 1; // repeat search in bottom half.
458  else
459  return mid; // found it. return position /////
460  }
461  return size(); // failed to find key
462  }
463 
464 
465  int findLinearSearch(const T& key) const
466  {
467  int index=size();
468  int i;
469 
470  for (i=0;i<size();i++)
471  {
472  if (m_data[i] == key)
473  {
474  index = i;
475  break;
476  }
477  }
478  return index;
479  }
480 
481  void remove(const T& key)
482  {
483 
484  int findIndex = findLinearSearch(key);
485  if (findIndex<size())
486  {
487  swap( findIndex,size()-1);
488  pop_back();
489  }
490  }
491 
492  //PCK: whole function
493  void initializeFromBuffer(void *buffer, int size, int capacity)
494  {
495  clear();
496  m_ownsMemory = false;
497  m_data = (T*)buffer;
498  m_size = size;
500  }
501 
502  void copyFromArray(const btAlignedObjectArray& otherArray)
503  {
504  int otherSize = otherArray.size();
505  resize (otherSize);
506  otherArray.copy(0, otherSize, m_data);
507  }
508 
509 };
510 
511 #endif //BT_OBJECT_ARRAY__
void copy(int start, int end, T *dest) const
void push_back(const T &_Val)
void deallocate(pointer ptr)
The btAlignedObjectArray template class uses a subset of the stl::vector interface for its methods It...
const T & at(int n) const
const T & operator[](int n) const
void resizeNoInitialize(int newsize)
resize changes the number of elements in the array.
void destroy(int first, int last)
#define btAssert(x)
Definition: btScalar.h:101
#define SIMD_FORCE_INLINE
Definition: btScalar.h:58
void copyFromArray(const btAlignedObjectArray &otherArray)
void downHeap(T *pArr, int k, int n, const L &CompareFunc)
heap sort from http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Sort/Heap/
void swap(int index0, int index1)
void heapSort(const L &CompareFunc)
void clear()
clear the array, deallocated memory. Generally it is better to use array.resize(0), to reduce performance overhead of run-time memory (de)allocations.
int size() const
return the number of elements in the array
#define BT_USE_PLACEMENT_NEW
If the platform doesn't support placement new, you can disable BT_USE_PLACEMENT_NEW then the btAligne...
void initializeFromBuffer(void *buffer, int size, int capacity)
int capacity() const
return the pre-allocated (reserved) elements, this is at least as large as the total number of elemen...
btAlignedObjectArray(const btAlignedObjectArray &otherArray)
Generally it is best to avoid using the copy constructor of an btAlignedObjectArray, and use a (const) reference to the array instead.
void resize(int newsize, const T &fillData=T())
int findLinearSearch(const T &key) const
btAlignedObjectArray< T > & operator=(const btAlignedObjectArray< T > &other)
T & expand(const T &fillValue=T())
pointer allocate(size_type n, const_pointer *hint=0)
int findBinarySearch(const T &key) const
non-recursive binary search, assumes sorted array
btAlignedAllocator< T, 16 > m_allocator
void quickSortInternal(const L &CompareFunc, int lo, int hi)
bool operator()(const T &a, const T &b)
void quickSort(const L &CompareFunc)