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                         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); //use the in-place new (not really allocating heap memory)
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                 {       // determine new minimum length of allocated storage
00272                         if (capacity() < _Count)
00273                         {       // not enough room, reallocate
00274                                 T*      s = (T*)allocate(_Count);
00275 
00276                                 copy(0, size(), s);
00277 
00278                                 destroy(0,size());
00279 
00280                                 deallocate();
00281                                 
00282                                 //PCK: added this line
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                 //  lo is the lower index, hi is the upper index
00307                 //  of the region of array a that is to be sorted
00308                         int i=lo, j=hi;
00309                         T x=m_data[(lo+hi)/2];
00310 
00311                         //  partition
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                         //  recursion
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                         //don't sort 0 or 1 elements
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                         /*  PRE: a[k+1..N] is a heap */
00349                         /* POST:  a[k..N]  is a heap */
00350                         
00351                         T temp = pArr[k - 1];
00352                         /* k has child(s) */
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                                 /* pick larger child */
00362                                 if (CompareFunc(temp , pArr[child - 1]))
00363                                 {
00364                                         /* move child up */
00365                                         pArr[k - 1] = pArr[child - 1];
00366                                         k = child;
00367                                 }
00368                                 else
00369                                 {
00370                                         break;
00371                                 }
00372                         }
00373                         pArr[k - 1] = temp;
00374                 } /*downHeap*/
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                 /* sort a[0..N-1],  N.B. 0 to N-1 */
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                 /* a[1..N] is now a heap */
00403                 while ( n>=1 ) 
00404                 {
00405                         swap(0,n-1); /* largest of a[0..n-1] */
00406 
00407 
00408                         n = n - 1;
00409                         /* restore a[1..i-1] heap */
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                 //assume sorted array
00421                 while (first <= last) {
00422                         int mid = (first + last) / 2;  // compute mid point.
00423                         if (key > m_data[mid]) 
00424                                 first = mid + 1;  // repeat search in top half.
00425                         else if (key < m_data[mid]) 
00426                                 last = mid - 1; // repeat search in bottom half.
00427                         else
00428                                 return mid;     // found it. return position /////
00429                 }
00430                 return size();    // failed to find key
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         //PCK: whole function
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__
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines


bullet
Author(s): Erwin Coumans, ROS package maintained by Tully Foote
autogenerated on Wed Oct 31 2012 07:54:30