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