btAlignedObjectArray.h

Go to the documentation of this file.
00001 /*
00002 Bullet Continuous Collision Detection and Physics Library
00003 Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
00004 
00005 This software is provided 'as-is', without any express or implied warranty.
00006 In no event will the authors be held liable for any damages arising from the use of this software.
00007 Permission is granted to anyone to use this software for any purpose, 
00008 including commercial applications, and to alter it and redistribute it freely, 
00009 subject to the following restrictions:
00010 
00011 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.
00012 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
00013 3. This notice may not be removed or altered from any source distribution.
00014 */
00015 
00016 
00017 #ifndef BT_OBJECT_ARRAY__
00018 #define BT_OBJECT_ARRAY__
00019 
00020 #include "btScalar.h" // has definitions like SIMD_FORCE_INLINE
00021 #include "btAlignedAllocator.h"
00022 
00028 
00029 #define BT_USE_PLACEMENT_NEW 1
00030 //#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...
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> //for placement new
00039 #endif //BT_USE_PLACEMENT_NEW
00040 
00041 
00044 template <typename T> 
00045 //template <class T> 
00046 class btAlignedObjectArray
00047 {
00048         btAlignedAllocator<T , 16>      m_allocator;
00049 
00050         int                                     m_size;
00051         int                                     m_capacity;
00052         T*                                      m_data;
00053         //PCK: added this line
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                         //PCK: added this line
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                                 //PCK: enclosed the deallocation in this block
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); //use the in-place new (not really allocating heap memory)
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                 {       // determine new minimum length of allocated storage
00263                         if (capacity() < _Count)
00264                         {       // not enough room, reallocate
00265                                 T*      s = (T*)allocate(_Count);
00266 
00267                                 copy(0, size(), s);
00268 
00269                                 destroy(0,size());
00270 
00271                                 deallocate();
00272                                 
00273                                 //PCK: added this line
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                 //  lo is the lower index, hi is the upper index
00298                 //  of the region of array a that is to be sorted
00299                         int i=lo, j=hi;
00300                         T x=m_data[(lo+hi)/2];
00301 
00302                         //  partition
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                         //  recursion
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                         //don't sort 0 or 1 elements
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                         /*  PRE: a[k+1..N] is a heap */
00340                         /* POST:  a[k..N]  is a heap */
00341                         
00342                         T temp = pArr[k - 1];
00343                         /* k has child(s) */
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                                 /* pick larger child */
00353                                 if (CompareFunc(temp , pArr[child - 1]))
00354                                 {
00355                                         /* move child up */
00356                                         pArr[k - 1] = pArr[child - 1];
00357                                         k = child;
00358                                 }
00359                                 else
00360                                 {
00361                                         break;
00362                                 }
00363                         }
00364                         pArr[k - 1] = temp;
00365                 } /*downHeap*/
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                 /* sort a[0..N-1],  N.B. 0 to N-1 */
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                 /* a[1..N] is now a heap */
00394                 while ( n>=1 ) 
00395                 {
00396                         swap(0,n-1); /* largest of a[0..n-1] */
00397 
00398 
00399                         n = n - 1;
00400                         /* restore a[1..i-1] heap */
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                 //assume sorted array
00412                 while (first <= last) {
00413                         int mid = (first + last) / 2;  // compute mid point.
00414                         if (key > m_data[mid]) 
00415                                 first = mid + 1;  // repeat search in top half.
00416                         else if (key < m_data[mid]) 
00417                                 last = mid - 1; // repeat search in bottom half.
00418                         else
00419                                 return mid;     // found it. return position /////
00420                 }
00421                 return size();    // failed to find key
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         //PCK: whole function
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__

Generated on Mon Feb 15 22:17:02 2010 for Bullet Collision Detection & Physics Library by  doxygen 1.6.1