ResizeArrayRaw.h

Go to the documentation of this file.
00001 
00007 /*
00008   Data storage class for ResizeArray and related container classes.
00009   Copy and assignment copy raw pointers, use copy() to copy data.
00010   Destructor does not delete data, call free first.
00011 */
00012 
00013 
00014 #ifndef RESIZEARRAYRAW_H
00015 #define RESIZEARRAYRAW_H
00016 
00017 #include <new>
00018 #include <string.h>
00019 #include "common.h"
00020 
00021 #define ResizeArrayGrowthFactor 1.5
00022 #define ResizeArrayMinSize 8
00023 
00024 // Need this juju to use templated friend below
00025 template <class Type> class ResizeArray;
00026 template <class Type> class SortableResizeArray;
00027 template <class Type> class SortedArray;
00028 template <class Type> class UniqueSortedArray;
00029 template <class Type> class ResizeArrayIter;
00030 
00031 // Class assumes that one can bit move objects
00032 // around on array.  This will be true
00033 // as long as object has no pointers to itself.
00034 template <class Elem> class ResizeArrayRaw {
00035 
00036   private:
00037     Elem *array;
00038     unsigned char *varray;
00039 
00040     int arraySize;
00041     int allocSize;
00042 
00043     // No constructor run on new elements
00044     // arraySize is not adjusted, only allocSize
00045     void resizeRaw(int size) {
00046       if (size <= allocSize) return;
00047   
00048       if (size < (int)(allocSize*ResizeArrayGrowthFactor)) 
00049         size = (int)(allocSize*ResizeArrayGrowthFactor);
00050       if ( (size-allocSize) < ResizeArrayMinSize) 
00051         size = allocSize+ResizeArrayMinSize;
00052 
00053       // align everything to 64-byte boundaries (if possible)
00054       unsigned char *tmpv = new unsigned char[size*sizeof(Elem)+63];
00055       //Elem *tmpa = (Elem *)((((long)tmpv)+63L)&(-64L));
00056       // Someday we might need this alternate form.
00057       Elem *tmpa = (Elem *)(tmpv+63 - (((long)(tmpv+63))&(63L)));
00058       if (arraySize) CmiMemcpy((void *)tmpa, (void *)array, sizeof(Elem)*arraySize);
00059   
00060       if (allocSize) delete[] varray;
00061       varray = tmpv;
00062       array = tmpa;
00063       allocSize = size;
00064     }
00065 
00066     friend class ResizeArray<Elem>;
00067     friend class SortableResizeArray<Elem>;
00068     friend class SortedArray<Elem>;
00069     friend class UniqueSortedArray<Elem>;
00070     friend class ResizeArrayIter<Elem>;
00071 
00072     inline int size(void) const { return arraySize; }
00073     inline Elem &operator[](int index) const { return array[index]; }
00074 
00075     // DMK - MIC Support - Allow us to see the buffer's size, not just how much of it is used
00076     #if NAMD_MIC != 0
00077       inline int bufSize(void) const { return allocSize; }
00078     #endif
00079 
00080     // Default constructor 
00081     ResizeArrayRaw(void) : 
00082       array((Elem *)0), varray((unsigned char *)0), arraySize(0), allocSize(0) { }
00083 
00084     // Encap a pre-existing array
00085     ResizeArrayRaw( Elem * * const array, int arraySize, int allocSize) {
00086       if (allocSize < arraySize) allocSize = arraySize;
00087       this->allocSize = allocSize;
00088       this->arraySize = arraySize;
00089       varray = (unsigned char *)*array;
00090       this->array = (Elem *)*array;
00091       *array = 0;
00092     }
00093   
00094     // copy data
00095     void copy(const ResizeArrayRaw<Elem> &rar ) {
00096   
00097       // Clean up this array
00098       resize(0);
00099       resizeRaw(rar.size());
00100   
00101       CmiMemcpy((void*)array, (void*)rar.array, sizeof(Elem)*rar.size());
00102       arraySize = rar.size();
00103     }
00104   
00105     // Properly constructs default object on new elements
00106     // Properly destructs on removed elements
00107     // arraySize is properly updated
00108     void resize(int size) {
00109       int i;
00110   
00111       if (size < arraySize) {
00112         for (i=size; i<arraySize; i++) {
00113           array[i].~Elem();
00114         }
00115       } else if (size > arraySize) {
00116         resizeRaw(size);
00117         for (i=arraySize; i<size; i++) {
00118           new ((void *)&array[i]) Elem;
00119         }
00120       }
00121       arraySize = size;
00122     }
00123   
00124     // needed for ResizeArray destructor
00125     void free(void) {
00126       for (int i=0; i < arraySize; i++) {
00127         array[i].~Elem();
00128       }
00129       delete[] varray;
00130     }
00131   
00132     // resize to 0 and free storage
00133     void clear(void) {
00134       free();
00135       array = 0;
00136       varray = 0;
00137       arraySize = 0;
00138       allocSize = 0;
00139     }
00140 
00141     inline int del(int index, int number) {
00142       int i;
00143   
00144       // Fix up number to delete if deletes off end of array
00145       if (index >= arraySize)
00146         number=0; // for inline sake, don't have multiple returns
00147       else if (index+number-1 > arraySize) {
00148         number = index-arraySize+1;
00149       }
00150   
00151       // Destruct objects to be deleted
00152       for (i=index; i < index+number; i++) {
00153         array[i].~Elem();
00154       }
00155   
00156       // Shift down
00157       memmove((void *)(array+index),
00158          (void *)(array+index+number),
00159          (arraySize-number-index)*sizeof(Elem));
00160       
00161       // fixup size of array
00162       arraySize -= number;
00163       return(number);
00164     }
00165   
00166     
00167     // Insert element in array
00168     // If index is over the end of array, default
00169     // constructor should be run over blank elements to pad.
00170     inline void ins(const Elem &e, int index) {
00171       // Size array depending if index is in current array or reaches beyond.
00172       if (index < arraySize) {
00173         resizeRaw(arraySize+1);
00174         // Shift up
00175         memmove((void *)(array+index+1),
00176           (void *)(array+index),
00177           (arraySize-index)*sizeof(Elem));
00178       } else {
00179         resizeRaw(index+1);
00180       }
00181       
00182       // Write in new element via assignment - allows any refcounting
00183       // etc. to take place correctly!
00184       new((void *)&array[index]) Elem;
00185       array[index] = e;
00186     
00187       // Take care of fill and setting correct arraySize 
00188       if (index > arraySize) {
00189         for (Elem *tmp = array+arraySize; tmp < array+index; tmp++) {
00190           new ((void *)tmp) Elem;
00191         }
00192         arraySize = index+1;
00193       } else
00194         arraySize++;
00195     }
00196 
00197     inline int find(const Elem &e) const {
00198       for (int i=0; i<arraySize; i++)
00199         if (array[i] == e) return i;
00200       return -1;
00201     }
00202 };      // end template definition
00203 
00204 #endif

Generated on Mon Nov 20 01:17:14 2017 for NAMD by  doxygen 1.4.7