Bullet Collision Detection & Physics Library: btAlignedObjectArray.h Source File

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 #ifndef BT_OBJECT_ARRAY__
17 #define BT_OBJECT_ARRAY__
18
19 #include "btScalar.h" // has definitions like SIMD_FORCE_INLINE
20 #include "btAlignedAllocator.h"
21
27
28 #define BT_USE_PLACEMENT_NEW 1
29 //#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...
30 #define BT_ALLOW_ARRAY_COPY_OPERATOR // enabling this can accidently perform deep copies of data if you are not careful
31
32 #ifdef BT_USE_MEMCPY
33 #include <memory.h>
34 #include <string.h>
35 #endif //BT_USE_MEMCPY
36
37 #ifdef BT_USE_PLACEMENT_NEW
38 #include <new> //for placement new
39 #endif //BT_USE_PLACEMENT_NEW
40
41 // The register keyword is deprecated in C++11 so don't use it.
42 #if __cplusplus > 199711L
43 #define BT_REGISTER
44 #else
45 #define BT_REGISTER register
46 #endif
47
50 template <typename T>
51 //template <class T>
52 class btAlignedObjectArray
53 {
54 btAlignedAllocator<T, 16> m_allocator;
55
56 int m_size;
57 int m_capacity;
58 T* m_data;
59 //PCK: added this line
60 bool m_ownsMemory;
61
62 #ifdef BT_ALLOW_ARRAY_COPY_OPERATOR
63 public:
64 SIMD_FORCE_INLINE btAlignedObjectArray<T>& operator=(const btAlignedObjectArray<T>& other)
65 {
66 copyFromArray(other);
67 return *this;
68 }
69 #else //BT_ALLOW_ARRAY_COPY_OPERATOR
70 private:
71 SIMD_FORCE_INLINE btAlignedObjectArray<T>& operator=(const btAlignedObjectArray<T>& other);
72 #endif //BT_ALLOW_ARRAY_COPY_OPERATOR
73
74 protected:
75 SIMD_FORCE_INLINE int allocSize(int size)
76 {
77 return (size ? size * 2 : 1);
78 }
79 SIMD_FORCE_INLINE void copy(int start, int end, T* dest) const
80 {
81 int i;
82 for (i = start; i < end; ++i)
83 #ifdef BT_USE_PLACEMENT_NEW
84 new (&dest[i]) T(m_data[i]);
85 #else
86 dest[i] = m_data[i];
87 #endif //BT_USE_PLACEMENT_NEW
88 }
89
90 SIMD_FORCE_INLINE void init()
91 {
92 //PCK: added this line
93 m_ownsMemory = true;
94 m_data = 0;
95 m_size = 0;
96 m_capacity = 0;
97 }
98 SIMD_FORCE_INLINE void destroy(int first, int last)
99 {
100 int i;
101 for (i = first; i < last; i++)
102 {
103 m_data[i].~T();
104 }
105 }
106
107 SIMD_FORCE_INLINE void* allocate(int size)
108 {
109 if (size)
110 return m_allocator.allocate(size);
111 return 0;
112 }
113
114 SIMD_FORCE_INLINE void deallocate()
115 {
116 if (m_data)
117 {
118 //PCK: enclosed the deallocation in this block
119 if (m_ownsMemory)
120 {
121 m_allocator.deallocate(m_data);
122 }
123 m_data = 0;
124 }
125 }
126
127 public:
128 btAlignedObjectArray()
129 {
130 init();
131 }
132
133 ~btAlignedObjectArray()
134 {
135 clear();
136 }
137
139 btAlignedObjectArray(const btAlignedObjectArray& otherArray)
140 {
141 init();
142
143 int otherSize = otherArray.size();
144 resize(otherSize);
145 otherArray.copy(0, otherSize, m_data);
146 }
147
149 SIMD_FORCE_INLINE int size() const
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
161 SIMD_FORCE_INLINE T& at(int n)
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
175 SIMD_FORCE_INLINE T& operator[](int n)
176 {
177 btAssert(n >= 0);
178 btAssert(n < size());
179 return m_data[n];
180 }
181
183 SIMD_FORCE_INLINE void clear()
184 {
185 destroy(0, size());
186
187 deallocate();
188
189 init();
190 }
191
192 SIMD_FORCE_INLINE void pop_back()
193 {
194 btAssert(m_size > 0);
195 m_size--;
196 m_data[m_size].~T();
197 }
198
201 SIMD_FORCE_INLINE void resizeNoInitialize(int newsize)
202 {
203 if (newsize > size())
204 {
205 reserve(newsize);
206 }
207 m_size = newsize;
208 }
209
210 SIMD_FORCE_INLINE void resize(int newsize, const T& fillData = T())
211 {
212 const BT_REGISTER int curSize = size();
213
214 if (newsize < curSize)
215 {
216 for (int i = newsize; i < curSize; i++)
217 {
218 m_data[i].~T();
219 }
220 }
221 else
222 {
223 if (newsize > curSize)
224 {
225 reserve(newsize);
226 }
227 #ifdef BT_USE_PLACEMENT_NEW
228 for (int i = curSize; i < newsize; i++)
229 {
230 new (&m_data[i]) T(fillData);
231 }
232 #endif //BT_USE_PLACEMENT_NEW
233 }
234
235 m_size = newsize;
236 }
237 SIMD_FORCE_INLINE T& expandNonInitializing()
238 {
239 const BT_REGISTER int sz = size();
240 if (sz == capacity())
241 {
242 reserve(allocSize(size()));
243 }
244 m_size++;
245
246 return m_data[sz];
247 }
248
249 SIMD_FORCE_INLINE T& expand(const T& fillValue = T())
250 {
251 const BT_REGISTER int sz = size();
252 if (sz == capacity())
253 {
254 reserve(allocSize(size()));
255 }
256 m_size++;
257 #ifdef BT_USE_PLACEMENT_NEW
258 new (&m_data[sz]) T(fillValue); //use the in-place new (not really allocating heap memory)
259 #endif
260
261 return m_data[sz];
262 }
263
264 SIMD_FORCE_INLINE void push_back(const T& _Val)
265 {
266 const BT_REGISTER int sz = size();
267 if (sz == capacity())
268 {
269 reserve(allocSize(size()));
270 }
271
272 #ifdef BT_USE_PLACEMENT_NEW
273 new (&m_data[m_size]) T(_Val);
274 #else
275 m_data[size()] = _Val;
276 #endif //BT_USE_PLACEMENT_NEW
277
278 m_size++;
279 }
280
282 SIMD_FORCE_INLINE int capacity() const
283 {
284 return m_capacity;
285 }
286
287 SIMD_FORCE_INLINE void reserve(int _Count)
288 { // determine new minimum length of allocated storage
289 if (capacity() < _Count)
290 { // not enough room, reallocate
291 T* s = (T*)allocate(_Count);
292
293 copy(0, size(), s);
294
295 destroy(0, size());
296
297 deallocate();
298
299 //PCK: added this line
300 m_ownsMemory = true;
301
302 m_data = s;
303
304 m_capacity = _Count;
305 }
306 }
307
308 class less
309 {
310 public:
311 bool operator()(const T& a, const T& b) const
312 {
313 return (a < b);
314 }
315 };
316
317 template <typename L>
318 void quickSortInternal(const L& CompareFunc, int lo, int hi)
319 {
320 // lo is the lower index, hi is the upper index
321 // of the region of array a that is to be sorted
322 int i = lo, j = hi;
323 T x = m_data[(lo + hi) / 2];
324
325 // partition
326 do
327 {
328 while (CompareFunc(m_data[i], x))
329 i++;
330 while (CompareFunc(x, m_data[j]))
331 j--;
332 if (i <= j)
333 {
334 swap(i, j);
335 i++;
336 j--;
337 }
338 } while (i <= j);
339
340 // recursion
341 if (lo < j)
342 quickSortInternal(CompareFunc, lo, j);
343 if (i < hi)
344 quickSortInternal(CompareFunc, i, hi);
345 }
346
347 template <typename L>
348 void quickSort(const L& CompareFunc)
349 {
350 //don't sort 0 or 1 elements
351 if (size() > 1)
352 {
353 quickSortInternal(CompareFunc, 0, size() - 1);
354 }
355 }
356
358 template <typename L>
359 void downHeap(T* pArr, int k, int n, const L& CompareFunc)
360 {
361 /* PRE: a[k+1..N] is a heap */
362 /* POST: a[k..N] is a heap */
363
364 T temp = pArr[k - 1];
365 /* k has child(s) */
366 while (k <= n / 2)
367 {
368 int child = 2 * k;
369
370 if ((child < n) && CompareFunc(pArr[child - 1], pArr[child]))
371 {
372 child++;
373 }
374 /* pick larger child */
375 if (CompareFunc(temp, pArr[child - 1]))
376 {
377 /* move child up */
378 pArr[k - 1] = pArr[child - 1];
379 k = child;
380 }
381 else
382 {
383 break;
384 }
385 }
386 pArr[k - 1] = temp;
387 } /*downHeap*/
388
389 void swap(int index0, int index1)
390 {
391 #ifdef BT_USE_MEMCPY
392 char temp[sizeof(T)];
393 memcpy(temp, &m_data[index0], sizeof(T));
394 memcpy(&m_data[index0], &m_data[index1], sizeof(T));
395 memcpy(&m_data[index1], temp, sizeof(T));
396 #else
397 T temp = m_data[index0];
398 m_data[index0] = m_data[index1];
399 m_data[index1] = temp;
400 #endif //BT_USE_PLACEMENT_NEW
401 }
402
403 template <typename L>
404 void heapSort(const L& CompareFunc)
405 {
406 /* sort a[0..N-1], N.B. 0 to N-1 */
407 int k;
408 int n = m_size;
409 for (k = n / 2; k > 0; k--)
410 {
411 downHeap(m_data, k, n, CompareFunc);
412 }
413
414 /* a[1..N] is now a heap */
415 while (n >= 1)
416 {
417 swap(0, n - 1); /* largest of a[0..n-1] */
418
419 n = n - 1;
420 /* restore a[1..i-1] heap */
421 downHeap(m_data, 1, n, CompareFunc);
422 }
423 }
424
426 int findBinarySearch(const T& key) const
427 {
428 int first = 0;
429 int last = size() - 1;
430
431 //assume sorted array
432 while (first <= last)
433 {
434 int mid = (first + last) / 2; // compute mid point.
435 if (key > m_data[mid])
436 first = mid + 1; // repeat search in top half.
437 else if (key < m_data[mid])
438 last = mid - 1; // repeat search in bottom half.
439 else
440 return mid; // found it. return position /////
441 }
442 return size(); // failed to find key
443 }
444
445 int findLinearSearch(const T& key) const
446 {
447 int index = size();
448 int i;
449
450 for (i = 0; i < size(); i++)
451 {
452 if (m_data[i] == key)
453 {
454 index = i;
455 break;
456 }
457 }
458 return index;
459 }
460
461 // If the key is not in the array, return -1 instead of 0,
462 // since 0 also means the first element in the array.
463 int findLinearSearch2(const T& key) const
464 {
465 int index = -1;
466 int i;
467
468 for (i = 0; i < size(); i++)
469 {
470 if (m_data[i] == key)
471 {
472 index = i;
473 break;
474 }
475 }
476 return index;
477 }
478
479 void removeAtIndex(int index)
480 {
481 if (index < size())
482 {
483 swap(index, size() - 1);
484 pop_back();
485 }
486 }
487 void remove(const T& key)
488 {
489 int findIndex = findLinearSearch(key);
490 removeAtIndex(findIndex);
491 }
492
493 //PCK: whole function
494 void initializeFromBuffer(void* buffer, int size, int capacity)
495 {
496 clear();
497 m_ownsMemory = false;
498 m_data = (T*)buffer;
499 m_size = size;
500 m_capacity = capacity;
501 }
502
503 void copyFromArray(const btAlignedObjectArray& otherArray)
504 {
505 int otherSize = otherArray.size();
506 resize(otherSize);
507 otherArray.copy(0, otherSize, m_data);
508 }
509 };
510
511 #endif //BT_OBJECT_ARRAY__
btAlignedObjectArray::reserve
void reserve(int _Count)
Definition: btAlignedObjectArray.h:287
BT_REGISTER
#define BT_REGISTER
Definition: btAlignedObjectArray.h:45
btAlignedObjectArray::push_back
void push_back(const T &_Val)
Definition: btAlignedObjectArray.h:264
btAlignedAllocator::deallocate
void deallocate(pointer ptr)
Definition: btAlignedAllocator.h:95
btAlignedObjectArray::findLinearSearch2
int findLinearSearch2(const T &key) const
Definition: btAlignedObjectArray.h:463
btAlignedObjectArray::operator[]
T & operator[](int n)
Definition: btAlignedObjectArray.h:175
btAlignedObjectArray::copy
void copy(int start, int end, T *dest) const
Definition: btAlignedObjectArray.h:79
btAlignedObjectArray::m_ownsMemory
bool m_ownsMemory
Definition: btAlignedObjectArray.h:60
btAlignedObjectArray::m_capacity
int m_capacity
Definition: btAlignedObjectArray.h:57
btAlignedObjectArray
The btAlignedObjectArray template class uses a subset of the stl::vector interface for its methods It...
Definition: btAlignedObjectArray.h:52
btAlignedObjectArray::less::operator()
bool operator()(const T &a, const T &b) const
Definition: btAlignedObjectArray.h:311
btAlignedObjectArray::findLinearSearch
int findLinearSearch(const T &key) const
Definition: btAlignedObjectArray.h:445
btAlignedObjectArray::allocate
void * allocate(int size)
Definition: btAlignedObjectArray.h:107
btAlignedObjectArray::operator[]
const T & operator[](int n) const
Definition: btAlignedObjectArray.h:168
btAlignedObjectArray::init
void init()
Definition: btAlignedObjectArray.h:90
btAlignedObjectArray::resizeNoInitialize
void resizeNoInitialize(int newsize)
resize changes the number of elements in the array.
Definition: btAlignedObjectArray.h:201
btAlignedObjectArray::destroy
void destroy(int first, int last)
Definition: btAlignedObjectArray.h:98
btAssert
#define btAssert(x)
Definition: btScalar.h:133
btAlignedObjectArray::at
const T & at(int n) const
Definition: btAlignedObjectArray.h:154
SIMD_FORCE_INLINE
#define SIMD_FORCE_INLINE
Definition: btScalar.h:83
btAlignedObjectArray::copyFromArray
void copyFromArray(const btAlignedObjectArray &otherArray)
Definition: btAlignedObjectArray.h:503
btAlignedAllocator.h
btAlignedObjectArray::downHeap
void downHeap(T *pArr, int k, int n, const L &CompareFunc)
heap sort from http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Sort/Heap/
Definition: btAlignedObjectArray.h:359
btAlignedObjectArray::swap
void swap(int index0, int index1)
Definition: btAlignedObjectArray.h:389
btAlignedObjectArray::heapSort
void heapSort(const L &CompareFunc)
Definition: btAlignedObjectArray.h:404
btAlignedObjectArray::clear
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.
Definition: btAlignedObjectArray.h:183
btAlignedObjectArray::removeAtIndex
void removeAtIndex(int index)
Definition: btAlignedObjectArray.h:479
BT_USE_PLACEMENT_NEW
#define BT_USE_PLACEMENT_NEW
If the platform doesn&#39;t support placement new, you can disable BT_USE_PLACEMENT_NEW then the btAligne...
Definition: btAlignedObjectArray.h:28
btAlignedObjectArray::less
Definition: btAlignedObjectArray.h:308
btAlignedObjectArray::at
T & at(int n)
Definition: btAlignedObjectArray.h:161
btAlignedObjectArray::capacity
int capacity() const
return the pre-allocated (reserved) elements, this is at least as large as the total number of elemen...
Definition: btAlignedObjectArray.h:282
btAlignedObjectArray::initializeFromBuffer
void initializeFromBuffer(void *buffer, int size, int capacity)
Definition: btAlignedObjectArray.h:494
btAlignedObjectArray::allocSize
int allocSize(int size)
Definition: btAlignedObjectArray.h:75
btAlignedObjectArray::pop_back
void pop_back()
Definition: btAlignedObjectArray.h:192
btAlignedObjectArray::size
int size() const
return the number of elements in the array
Definition: btAlignedObjectArray.h:149
btAlignedObjectArray::m_allocator
btAlignedAllocator< T, 16 > m_allocator
Definition: btAlignedObjectArray.h:54
btAlignedObjectArray::btAlignedObjectArray
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.
Definition: btAlignedObjectArray.h:139
btAlignedObjectArray::btAlignedObjectArray
btAlignedObjectArray()
Definition: btAlignedObjectArray.h:128
btAlignedObjectArray::m_size
int m_size
Definition: btAlignedObjectArray.h:56
btAlignedObjectArray::resize
void resize(int newsize, const T &fillData=T())
Definition: btAlignedObjectArray.h:210
btAlignedAllocator< T, 16 >
btAlignedObjectArray::m_data
T * m_data
Definition: btAlignedObjectArray.h:58
btAlignedObjectArray::operator=
btAlignedObjectArray< T > & operator=(const btAlignedObjectArray< T > &other)
Definition: btAlignedObjectArray.h:64
btAlignedObjectArray::findBinarySearch
int findBinarySearch(const T &key) const
non-recursive binary search, assumes sorted array
Definition: btAlignedObjectArray.h:426
btAlignedObjectArray::expand
T & expand(const T &fillValue=T())
Definition: btAlignedObjectArray.h:249
btAlignedObjectArray::~btAlignedObjectArray
~btAlignedObjectArray()
Definition: btAlignedObjectArray.h:133
btAlignedAllocator::allocate
pointer allocate(size_type n, const_pointer *hint=0)
Definition: btAlignedAllocator.h:89
btAlignedObjectArray::deallocate
void deallocate()
Definition: btAlignedObjectArray.h:114
btAlignedObjectArray::expandNonInitializing
T & expandNonInitializing()
Definition: btAlignedObjectArray.h:237
btAlignedObjectArray::quickSortInternal
void quickSortInternal(const L &CompareFunc, int lo, int hi)
Definition: btAlignedObjectArray.h:318
btAlignedObjectArray::quickSort
void quickSort(const L &CompareFunc)
Definition: btAlignedObjectArray.h:348
btScalar.h