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

Bullet Collision Detection & Physics Library

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

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>
47 class btAlignedObjectArray
48 {
49 btAlignedAllocator<T , 16> m_allocator;
50
51 int m_size;
52 int m_capacity;
53 T* m_data;
54 //PCK: added this line
55 bool m_ownsMemory;
56
57 #ifdef BT_ALLOW_ARRAY_COPY_OPERATOR
58 public:
59 SIMD_FORCE_INLINE btAlignedObjectArray<T>& operator=(const btAlignedObjectArray<T> &other)
60 {
61 copyFromArray(other);
62 return *this;
63 }
64 #else//BT_ALLOW_ARRAY_COPY_OPERATOR
65 private:
66 SIMD_FORCE_INLINE btAlignedObjectArray<T>& operator=(const btAlignedObjectArray<T> &other);
67 #endif//BT_ALLOW_ARRAY_COPY_OPERATOR
68
69 protected:
70 SIMD_FORCE_INLINE int allocSize(int size)
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)
78 #ifdef BT_USE_PLACEMENT_NEW
79 new (&dest[i]) T(m_data[i]);
80 #else
81 dest[i] = m_data[i];
82 #endif //BT_USE_PLACEMENT_NEW
83 }
84
85 SIMD_FORCE_INLINE void init()
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
102 SIMD_FORCE_INLINE void* allocate(int size)
103 {
104 if (size)
105 return m_allocator.allocate(size);
106 return 0;
107 }
108
109 SIMD_FORCE_INLINE void deallocate()
110 {
111 if(m_data) {
112 //PCK: enclosed the deallocation in this block
113 if (m_ownsMemory)
114 {
115 m_allocator.deallocate(m_data);
116 }
117 m_data = 0;
118 }
119 }
120
121
122
123
124 public:
125
126 btAlignedObjectArray()
127 {
128 init();
129 }
130
131 ~btAlignedObjectArray()
132 {
133 clear();
134 }
135
137 btAlignedObjectArray(const btAlignedObjectArray& otherArray)
138 {
139 init();
140
141 int otherSize = otherArray.size();
142 resize (otherSize);
143 otherArray.copy(0, otherSize, m_data);
144 }
145
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
182
184 SIMD_FORCE_INLINE void clear()
185 {
186 destroy(0,size());
187
188 deallocate();
189
190 init();
191 }
192
193 SIMD_FORCE_INLINE void pop_back()
194 {
195 btAssert(m_size>0);
196 m_size--;
197 m_data[m_size].~T();
198 }
199
200
203 SIMD_FORCE_INLINE void resizeNoInitialize(int newsize)
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 }
247 SIMD_FORCE_INLINE T& expandNonInitializing( )
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
295 SIMD_FORCE_INLINE int capacity() const
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;
499 m_capacity = capacity;
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__
btAlignedObjectArray::reserve
void reserve(int _Count)
Definition: btAlignedObjectArray.h:300
btAlignedObjectArray::copy
void copy(int start, int end, T *dest) const
Definition: btAlignedObjectArray.h:74
btAlignedObjectArray::push_back
void push_back(const T &_Val)
Definition: btAlignedObjectArray.h:276
btAlignedAllocator::deallocate
void deallocate(pointer ptr)
Definition: btAlignedAllocator.h:89
btAlignedObjectArray::operator[]
T & operator[](int n)
Definition: btAlignedObjectArray.h:175
btAlignedObjectArray::m_ownsMemory
bool m_ownsMemory
Definition: btAlignedObjectArray.h:55
btAlignedObjectArray::m_capacity
int m_capacity
Definition: btAlignedObjectArray.h:52
btAlignedObjectArray
The btAlignedObjectArray template class uses a subset of the stl::vector interface for its methods It...
Definition: btAlignedObjectArray.h:47
btAlignedObjectArray::at
const T & at(int n) const
Definition: btAlignedObjectArray.h:154
btAlignedObjectArray::allocate
void * allocate(int size)
Definition: btAlignedObjectArray.h:102
btAlignedObjectArray::operator[]
const T & operator[](int n) const
Definition: btAlignedObjectArray.h:168
btAlignedObjectArray::init
void init()
Definition: btAlignedObjectArray.h:85
btAlignedObjectArray::resizeNoInitialize
void resizeNoInitialize(int newsize)
resize changes the number of elements in the array.
Definition: btAlignedObjectArray.h:203
btAlignedObjectArray::destroy
void destroy(int first, int last)
Definition: btAlignedObjectArray.h:93
btAssert
#define btAssert(x)
Definition: btScalar.h:113
SIMD_FORCE_INLINE
#define SIMD_FORCE_INLINE
Definition: btScalar.h:63
btAlignedObjectArray::copyFromArray
void copyFromArray(const btAlignedObjectArray &otherArray)
Definition: btAlignedObjectArray.h:502
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:377
btAlignedObjectArray::swap
void swap(int index0, int index1)
Definition: btAlignedObjectArray.h:407
btAlignedObjectArray::heapSort
void heapSort(const L &CompareFunc)
Definition: btAlignedObjectArray.h:423
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:184
btAlignedObjectArray::size
int size() const
return the number of elements in the array
Definition: btAlignedObjectArray.h:149
BT_USE_PLACEMENT_NEW
#define BT_USE_PLACEMENT_NEW
If the platform doesn't support placement new, you can disable BT_USE_PLACEMENT_NEW then the btAligne...
Definition: btAlignedObjectArray.h:29
btAlignedObjectArray::less
Definition: btAlignedObjectArray.h:323
btAlignedObjectArray::at
T & at(int n)
Definition: btAlignedObjectArray.h:161
btAlignedObjectArray::initializeFromBuffer
void initializeFromBuffer(void *buffer, int size, int capacity)
Definition: btAlignedObjectArray.h:493
btAlignedObjectArray::allocSize
int allocSize(int size)
Definition: btAlignedObjectArray.h:70
btAlignedObjectArray::pop_back
void pop_back()
Definition: btAlignedObjectArray.h:193
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:295
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:137
btAlignedObjectArray::btAlignedObjectArray
btAlignedObjectArray()
Definition: btAlignedObjectArray.h:126
btAlignedObjectArray::m_size
int m_size
Definition: btAlignedObjectArray.h:51
btAlignedObjectArray::resize
void resize(int newsize, const T &fillData=T())
Definition: btAlignedObjectArray.h:220
btAlignedObjectArray::findLinearSearch
int findLinearSearch(const T &key) const
Definition: btAlignedObjectArray.h:465
btAlignedAllocator< T, 16 >
btAlignedObjectArray::m_data
T * m_data
Definition: btAlignedObjectArray.h:53
btAlignedObjectArray::operator=
btAlignedObjectArray< T > & operator=(const btAlignedObjectArray< T > &other)
Definition: btAlignedObjectArray.h:59
btAlignedObjectArray::expand
T & expand(const T &fillValue=T())
Definition: btAlignedObjectArray.h:260
btAlignedObjectArray::~btAlignedObjectArray
~btAlignedObjectArray()
Definition: btAlignedObjectArray.h:131
btAlignedAllocator::allocate
pointer allocate(size_type n, const_pointer *hint=0)
Definition: btAlignedAllocator.h:84
btAlignedObjectArray::deallocate
void deallocate()
Definition: btAlignedObjectArray.h:109
btAlignedObjectArray::expandNonInitializing
T & expandNonInitializing()
Definition: btAlignedObjectArray.h:247
btAlignedObjectArray::findBinarySearch
int findBinarySearch(const T &key) const
non-recursive binary search, assumes sorted array
Definition: btAlignedObjectArray.h:446
btAlignedObjectArray::m_allocator
btAlignedAllocator< T, 16 > m_allocator
Definition: btAlignedObjectArray.h:49
btAlignedObjectArray::quickSortInternal
void quickSortInternal(const L &CompareFunc, int lo, int hi)
Definition: btAlignedObjectArray.h:335
btAlignedObjectArray::less::operator()
bool operator()(const T &a, const T &b)
Definition: btAlignedObjectArray.h:327
btAlignedObjectArray::quickSort
void quickSort(const L &CompareFunc)
Definition: btAlignedObjectArray.h:365
btScalar.h