00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef BT_OBJECT_ARRAY__
00018 #define BT_OBJECT_ARRAY__
00019
00020 #include "btScalar.h"
00021 #include "btAlignedAllocator.h"
00022
00028
00029 #define BT_USE_PLACEMENT_NEW 1
00030
00031
00032 #ifdef BT_USE_MEMCPY
00033 #include <memory.h>
00034 #include <string.h>
00035 #endif //BT_USE_MEMCPY
00036
00037 #ifdef BT_USE_PLACEMENT_NEW
00038 #include <new>
00039 #endif //BT_USE_PLACEMENT_NEW
00040
00041
00044 template <typename T>
00045
00046 class btAlignedObjectArray
00047 {
00048 btAlignedAllocator<T , 16> m_allocator;
00049
00050 int m_size;
00051 int m_capacity;
00052 T* m_data;
00053
00054 bool m_ownsMemory;
00055
00056 protected:
00057 SIMD_FORCE_INLINE int allocSize(int size)
00058 {
00059 return (size ? size*2 : 1);
00060 }
00061 SIMD_FORCE_INLINE void copy(int start,int end, T* dest) const
00062 {
00063 int i;
00064 for (i=start;i<end;++i)
00065 #ifdef BT_USE_PLACEMENT_NEW
00066 new (&dest[i]) T(m_data[i]);
00067 #else
00068 dest[i] = m_data[i];
00069 #endif //BT_USE_PLACEMENT_NEW
00070 }
00071
00072 SIMD_FORCE_INLINE void init()
00073 {
00074
00075 m_ownsMemory = true;
00076 m_data = 0;
00077 m_size = 0;
00078 m_capacity = 0;
00079 }
00080 SIMD_FORCE_INLINE void destroy(int first,int last)
00081 {
00082 int i;
00083 for (i=first; i<last;i++)
00084 {
00085 m_data[i].~T();
00086 }
00087 }
00088
00089 SIMD_FORCE_INLINE void* allocate(int size)
00090 {
00091 if (size)
00092 return m_allocator.allocate(size);
00093 return 0;
00094 }
00095
00096 SIMD_FORCE_INLINE void deallocate()
00097 {
00098 if(m_data) {
00099
00100 if (m_ownsMemory)
00101 {
00102 m_allocator.deallocate(m_data);
00103 }
00104 m_data = 0;
00105 }
00106 }
00107
00108
00109
00110
00111 public:
00112
00113 btAlignedObjectArray()
00114 {
00115 init();
00116 }
00117
00118 ~btAlignedObjectArray()
00119 {
00120 clear();
00121 }
00122
00124 btAlignedObjectArray(const btAlignedObjectArray& otherArray)
00125 {
00126 init();
00127
00128 int otherSize = otherArray.size();
00129 resize (otherSize);
00130 otherArray.copy(0, otherSize, m_data);
00131 }
00132
00133
00134
00136 SIMD_FORCE_INLINE int size() const
00137 {
00138 return m_size;
00139 }
00140
00141 SIMD_FORCE_INLINE const T& at(int n) const
00142 {
00143 btAssert(n>=0);
00144 btAssert(n<size());
00145 return m_data[n];
00146 }
00147
00148 SIMD_FORCE_INLINE T& at(int n)
00149 {
00150 btAssert(n>=0);
00151 btAssert(n<size());
00152 return m_data[n];
00153 }
00154
00155 SIMD_FORCE_INLINE const T& operator[](int n) const
00156 {
00157 btAssert(n>=0);
00158 btAssert(n<size());
00159 return m_data[n];
00160 }
00161
00162 SIMD_FORCE_INLINE T& operator[](int n)
00163 {
00164 btAssert(n>=0);
00165 btAssert(n<size());
00166 return m_data[n];
00167 }
00168
00169
00171 SIMD_FORCE_INLINE void clear()
00172 {
00173 destroy(0,size());
00174
00175 deallocate();
00176
00177 init();
00178 }
00179
00180 SIMD_FORCE_INLINE void pop_back()
00181 {
00182 btAssert(m_size>0);
00183 m_size--;
00184 m_data[m_size].~T();
00185 }
00186
00189 SIMD_FORCE_INLINE void resize(int newsize, const T& fillData=T())
00190 {
00191 int curSize = size();
00192
00193 if (newsize < curSize)
00194 {
00195 for(int i = newsize; i < curSize; i++)
00196 {
00197 m_data[i].~T();
00198 }
00199 } else
00200 {
00201 if (newsize > size())
00202 {
00203 reserve(newsize);
00204 }
00205 #ifdef BT_USE_PLACEMENT_NEW
00206 for (int i=curSize;i<newsize;i++)
00207 {
00208 new ( &m_data[i]) T(fillData);
00209 }
00210 #endif //BT_USE_PLACEMENT_NEW
00211
00212 }
00213
00214 m_size = newsize;
00215 }
00216
00217 SIMD_FORCE_INLINE T& expandNonInitializing( )
00218 {
00219 int sz = size();
00220 if( sz == capacity() )
00221 {
00222 reserve( allocSize(size()) );
00223 }
00224 m_size++;
00225
00226 return m_data[sz];
00227 }
00228
00229
00230 SIMD_FORCE_INLINE T& expand( const T& fillValue=T())
00231 {
00232 int sz = size();
00233 if( sz == capacity() )
00234 {
00235 reserve( allocSize(size()) );
00236 }
00237 m_size++;
00238 #ifdef BT_USE_PLACEMENT_NEW
00239 new (&m_data[sz]) T(fillValue);
00240 #endif
00241
00242 return m_data[sz];
00243 }
00244
00245
00246 SIMD_FORCE_INLINE void push_back(const T& _Val)
00247 {
00248 int sz = size();
00249 if( sz == capacity() )
00250 {
00251 reserve( allocSize(size()) );
00252 }
00253
00254 #ifdef BT_USE_PLACEMENT_NEW
00255 new ( &m_data[m_size] ) T(_Val);
00256 #else
00257 m_data[size()] = _Val;
00258 #endif //BT_USE_PLACEMENT_NEW
00259
00260 m_size++;
00261 }
00262
00263
00265 SIMD_FORCE_INLINE int capacity() const
00266 {
00267 return m_capacity;
00268 }
00269
00270 SIMD_FORCE_INLINE void reserve(int _Count)
00271 {
00272 if (capacity() < _Count)
00273 {
00274 T* s = (T*)allocate(_Count);
00275
00276 copy(0, size(), s);
00277
00278 destroy(0,size());
00279
00280 deallocate();
00281
00282
00283 m_ownsMemory = true;
00284
00285 m_data = s;
00286
00287 m_capacity = _Count;
00288
00289 }
00290 }
00291
00292
00293 class less
00294 {
00295 public:
00296
00297 bool operator() ( const T& a, const T& b )
00298 {
00299 return ( a < b );
00300 }
00301 };
00302
00303 template <typename L>
00304 void quickSortInternal(L CompareFunc,int lo, int hi)
00305 {
00306
00307
00308 int i=lo, j=hi;
00309 T x=m_data[(lo+hi)/2];
00310
00311
00312 do
00313 {
00314 while (CompareFunc(m_data[i],x))
00315 i++;
00316 while (CompareFunc(x,m_data[j]))
00317 j--;
00318 if (i<=j)
00319 {
00320 swap(i,j);
00321 i++; j--;
00322 }
00323 } while (i<=j);
00324
00325
00326 if (lo<j)
00327 quickSortInternal( CompareFunc, lo, j);
00328 if (i<hi)
00329 quickSortInternal( CompareFunc, i, hi);
00330 }
00331
00332
00333 template <typename L>
00334 void quickSort(L CompareFunc)
00335 {
00336
00337 if (size()>1)
00338 {
00339 quickSortInternal(CompareFunc,0,size()-1);
00340 }
00341 }
00342
00343
00345 template <typename L>
00346 void downHeap(T *pArr, int k, int n,L CompareFunc)
00347 {
00348
00349
00350
00351 T temp = pArr[k - 1];
00352
00353 while (k <= n/2)
00354 {
00355 int child = 2*k;
00356
00357 if ((child < n) && CompareFunc(pArr[child - 1] , pArr[child]))
00358 {
00359 child++;
00360 }
00361
00362 if (CompareFunc(temp , pArr[child - 1]))
00363 {
00364
00365 pArr[k - 1] = pArr[child - 1];
00366 k = child;
00367 }
00368 else
00369 {
00370 break;
00371 }
00372 }
00373 pArr[k - 1] = temp;
00374 }
00375
00376 void swap(int index0,int index1)
00377 {
00378 #ifdef BT_USE_MEMCPY
00379 char temp[sizeof(T)];
00380 memcpy(temp,&m_data[index0],sizeof(T));
00381 memcpy(&m_data[index0],&m_data[index1],sizeof(T));
00382 memcpy(&m_data[index1],temp,sizeof(T));
00383 #else
00384 T temp = m_data[index0];
00385 m_data[index0] = m_data[index1];
00386 m_data[index1] = temp;
00387 #endif //BT_USE_PLACEMENT_NEW
00388
00389 }
00390
00391 template <typename L>
00392 void heapSort(L CompareFunc)
00393 {
00394
00395 int k;
00396 int n = m_size;
00397 for (k = n/2; k > 0; k--)
00398 {
00399 downHeap(m_data, k, n, CompareFunc);
00400 }
00401
00402
00403 while ( n>=1 )
00404 {
00405 swap(0,n-1);
00406
00407
00408 n = n - 1;
00409
00410 downHeap(m_data, 1, n, CompareFunc);
00411 }
00412 }
00413
00415 int findBinarySearch(const T& key) const
00416 {
00417 int first = 0;
00418 int last = size()-1;
00419
00420
00421 while (first <= last) {
00422 int mid = (first + last) / 2;
00423 if (key > m_data[mid])
00424 first = mid + 1;
00425 else if (key < m_data[mid])
00426 last = mid - 1;
00427 else
00428 return mid;
00429 }
00430 return size();
00431 }
00432
00433
00434 int findLinearSearch(const T& key) const
00435 {
00436 int index=size();
00437 int i;
00438
00439 for (i=0;i<size();i++)
00440 {
00441 if (m_data[i] == key)
00442 {
00443 index = i;
00444 break;
00445 }
00446 }
00447 return index;
00448 }
00449
00450 void remove(const T& key)
00451 {
00452
00453 int findIndex = findLinearSearch(key);
00454 if (findIndex<size())
00455 {
00456 swap( findIndex,size()-1);
00457 pop_back();
00458 }
00459 }
00460
00461
00462 void initializeFromBuffer(void *buffer, int size, int capacity)
00463 {
00464 clear();
00465 m_ownsMemory = false;
00466 m_data = (T*)buffer;
00467 m_size = size;
00468 m_capacity = capacity;
00469 }
00470
00471 void copyFromArray(const btAlignedObjectArray& otherArray)
00472 {
00473 int otherSize = otherArray.size();
00474 resize (otherSize);
00475 otherArray.copy(0, otherSize, m_data);
00476 }
00477
00478 };
00479
00480 #endif //BT_OBJECT_ARRAY__