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 return m_data[n];
00144 }
00145
00146 SIMD_FORCE_INLINE T& at(int n)
00147 {
00148 return m_data[n];
00149 }
00150
00151 SIMD_FORCE_INLINE const T& operator[](int n) const
00152 {
00153 return m_data[n];
00154 }
00155
00156 SIMD_FORCE_INLINE T& operator[](int n)
00157 {
00158 return m_data[n];
00159 }
00160
00161
00163 SIMD_FORCE_INLINE void clear()
00164 {
00165 destroy(0,size());
00166
00167 deallocate();
00168
00169 init();
00170 }
00171
00172 SIMD_FORCE_INLINE void pop_back()
00173 {
00174 m_size--;
00175 m_data[m_size].~T();
00176 }
00177
00180 SIMD_FORCE_INLINE void resize(int newsize, const T& fillData=T())
00181 {
00182 int curSize = size();
00183
00184 if (newsize < curSize)
00185 {
00186 for(int i = newsize; i < curSize; i++)
00187 {
00188 m_data[i].~T();
00189 }
00190 } else
00191 {
00192 if (newsize > size())
00193 {
00194 reserve(newsize);
00195 }
00196 #ifdef BT_USE_PLACEMENT_NEW
00197 for (int i=curSize;i<newsize;i++)
00198 {
00199 new ( &m_data[i]) T(fillData);
00200 }
00201 #endif //BT_USE_PLACEMENT_NEW
00202
00203 }
00204
00205 m_size = newsize;
00206 }
00207
00208 SIMD_FORCE_INLINE T& expandNonInitializing( )
00209 {
00210 int sz = size();
00211 if( sz == capacity() )
00212 {
00213 reserve( allocSize(size()) );
00214 }
00215 m_size++;
00216
00217 return m_data[sz];
00218 }
00219
00220
00221 SIMD_FORCE_INLINE T& expand( const T& fillValue=T())
00222 {
00223 int sz = size();
00224 if( sz == capacity() )
00225 {
00226 reserve( allocSize(size()) );
00227 }
00228 m_size++;
00229 #ifdef BT_USE_PLACEMENT_NEW
00230 new (&m_data[sz]) T(fillValue);
00231 #endif
00232
00233 return m_data[sz];
00234 }
00235
00236
00237 SIMD_FORCE_INLINE void push_back(const T& _Val)
00238 {
00239 int sz = size();
00240 if( sz == capacity() )
00241 {
00242 reserve( allocSize(size()) );
00243 }
00244
00245 #ifdef BT_USE_PLACEMENT_NEW
00246 new ( &m_data[m_size] ) T(_Val);
00247 #else
00248 m_data[size()] = _Val;
00249 #endif //BT_USE_PLACEMENT_NEW
00250
00251 m_size++;
00252 }
00253
00254
00256 SIMD_FORCE_INLINE int capacity() const
00257 {
00258 return m_capacity;
00259 }
00260
00261 SIMD_FORCE_INLINE void reserve(int _Count)
00262 {
00263 if (capacity() < _Count)
00264 {
00265 T* s = (T*)allocate(_Count);
00266
00267 copy(0, size(), s);
00268
00269 destroy(0,size());
00270
00271 deallocate();
00272
00273
00274 m_ownsMemory = true;
00275
00276 m_data = s;
00277
00278 m_capacity = _Count;
00279
00280 }
00281 }
00282
00283
00284 class less
00285 {
00286 public:
00287
00288 bool operator() ( const T& a, const T& b )
00289 {
00290 return ( a < b );
00291 }
00292 };
00293
00294 template <typename L>
00295 void quickSortInternal(L CompareFunc,int lo, int hi)
00296 {
00297
00298
00299 int i=lo, j=hi;
00300 T x=m_data[(lo+hi)/2];
00301
00302
00303 do
00304 {
00305 while (CompareFunc(m_data[i],x))
00306 i++;
00307 while (CompareFunc(x,m_data[j]))
00308 j--;
00309 if (i<=j)
00310 {
00311 swap(i,j);
00312 i++; j--;
00313 }
00314 } while (i<=j);
00315
00316
00317 if (lo<j)
00318 quickSortInternal( CompareFunc, lo, j);
00319 if (i<hi)
00320 quickSortInternal( CompareFunc, i, hi);
00321 }
00322
00323
00324 template <typename L>
00325 void quickSort(L CompareFunc)
00326 {
00327
00328 if (size()>1)
00329 {
00330 quickSortInternal(CompareFunc,0,size()-1);
00331 }
00332 }
00333
00334
00336 template <typename L>
00337 void downHeap(T *pArr, int k, int n,L CompareFunc)
00338 {
00339
00340
00341
00342 T temp = pArr[k - 1];
00343
00344 while (k <= n/2)
00345 {
00346 int child = 2*k;
00347
00348 if ((child < n) && CompareFunc(pArr[child - 1] , pArr[child]))
00349 {
00350 child++;
00351 }
00352
00353 if (CompareFunc(temp , pArr[child - 1]))
00354 {
00355
00356 pArr[k - 1] = pArr[child - 1];
00357 k = child;
00358 }
00359 else
00360 {
00361 break;
00362 }
00363 }
00364 pArr[k - 1] = temp;
00365 }
00366
00367 void swap(int index0,int index1)
00368 {
00369 #ifdef BT_USE_MEMCPY
00370 char temp[sizeof(T)];
00371 memcpy(temp,&m_data[index0],sizeof(T));
00372 memcpy(&m_data[index0],&m_data[index1],sizeof(T));
00373 memcpy(&m_data[index1],temp,sizeof(T));
00374 #else
00375 T temp = m_data[index0];
00376 m_data[index0] = m_data[index1];
00377 m_data[index1] = temp;
00378 #endif //BT_USE_PLACEMENT_NEW
00379
00380 }
00381
00382 template <typename L>
00383 void heapSort(L CompareFunc)
00384 {
00385
00386 int k;
00387 int n = m_size;
00388 for (k = n/2; k > 0; k--)
00389 {
00390 downHeap(m_data, k, n, CompareFunc);
00391 }
00392
00393
00394 while ( n>=1 )
00395 {
00396 swap(0,n-1);
00397
00398
00399 n = n - 1;
00400
00401 downHeap(m_data, 1, n, CompareFunc);
00402 }
00403 }
00404
00406 int findBinarySearch(const T& key) const
00407 {
00408 int first = 0;
00409 int last = size();
00410
00411
00412 while (first <= last) {
00413 int mid = (first + last) / 2;
00414 if (key > m_data[mid])
00415 first = mid + 1;
00416 else if (key < m_data[mid])
00417 last = mid - 1;
00418 else
00419 return mid;
00420 }
00421 return size();
00422 }
00423
00424
00425 int findLinearSearch(const T& key) const
00426 {
00427 int index=size();
00428 int i;
00429
00430 for (i=0;i<size();i++)
00431 {
00432 if (m_data[i] == key)
00433 {
00434 index = i;
00435 break;
00436 }
00437 }
00438 return index;
00439 }
00440
00441 void remove(const T& key)
00442 {
00443
00444 int findIndex = findLinearSearch(key);
00445 if (findIndex<size())
00446 {
00447 swap( findIndex,size()-1);
00448 pop_back();
00449 }
00450 }
00451
00452
00453 void initializeFromBuffer(void *buffer, int size, int capacity)
00454 {
00455 clear();
00456 m_ownsMemory = false;
00457 m_data = (T*)buffer;
00458 m_size = size;
00459 m_capacity = capacity;
00460 }
00461
00462 };
00463
00464 #endif //BT_OBJECT_ARRAY__