Main Page | Class Hierarchy | Class List | File List | Class Members

array.h

00001 //-< ARRAY.H >-------------------------------------------------------*--------*
00002 // GigaBASE                  Version 1.0         (c) 1999  GARRET    *     ?  *
00003 // (Post Relational Database Management System)                      *   /\|  *
00004 //                                                                   *  /  \  *
00005 //                          Created:     20-Nov-98    K.A. Knizhnik  * / [] \ *
00006 //                          Last update: 20-Dec-98    K.A. Knizhnik  * GARRET *
00007 //-------------------------------------------------------------------*--------*
00008 // Array type for table record fields
00009 //-------------------------------------------------------------------*--------*
00010 
00011 #ifndef __ARRAY_H__
00012 #define __ARRAY_H__
00013 
00014 BEGIN_GIGABASE_NAMESPACE
00015 
00019 class GIGABASE_DLL_ENTRY dbAnyArray {
00020     friend class dbTableDescriptor;
00021   protected:
00022     size_t len;
00023 
00024   public:
00025     static void arrayAllocator(dbAnyArray* aArray, void* data, size_t length)
00026     {
00027         aArray->len = length;
00028         *(void**)(aArray+1) = data;
00029     }
00034     size_t length() const { return len; }
00035 
00040     void const* base() const { return *(void**)(this+1); }
00041 };
00042 
00046 template<class T>
00047 class dbArray : public dbAnyArray {
00048     friend class dbTableDescriptor;
00049   protected:
00050     T*     data;
00051     size_t allocated;
00052 
00053     static void arrayAllocator(dbAnyArray* aArray, void* data, size_t length)
00054     {
00055         dbArray<T>* array = (dbArray<T>*)aArray;
00056         array->len = length;
00057         if (array->allocated) {
00058             delete[] array->data;
00059         }
00060         if (data != NULL || length == 0) {
00061             array->data = (T*)data;
00062             array->allocated = 0;
00063         } else {
00064             array->data = new T[length];
00065             array->allocated = length;
00066         }
00067     }
00068 
00069     
00070     inline void memcpy(T* dst, T const* src, size_t len) { 
00071         int n = (int)len;
00072         while (--n >= 0) { 
00073             *dst++ = *src++;
00074         }
00075     }
00076 
00077     inline void memmove(T* dst, T const* src, size_t len) { 
00078         int n = (int)len;
00079         if (dst < src) {
00080             while (--n >= 0) { 
00081                 *dst++ = *src++;
00082             }
00083         } else { 
00084             dst += n;
00085             src += n;       
00086             while (--n >= 0) { 
00087                 *--dst = *--src;
00088             }
00089         }
00090     }
00091 
00092   public:
00093     dbFieldDescriptor* dbDescribeComponents(dbFieldDescriptor* fd) {
00094         fd->type = fd->appType = dbField::tpArray;
00095         fd->dbsSize = sizeof(dbVarying);
00096         fd->alignment = 4;
00097         fd->arrayAllocator = arrayAllocator;
00098         return dbDescribeField(new dbFieldDescriptor(STRLITERAL("[]"), 0, sizeof(T), 0),
00099                                *(T*)fd);
00100     }
00101 
00105     dbArray() {
00106         data = NULL;
00107         len = 0;
00108         allocated = 0;
00109     }
00110 
00115     dbArray(size_t size) {
00116         if (size != 0) {
00117             data = new T[size];
00118         }
00119         len = size;
00120         allocated = size;
00121     }
00122 
00130     dbArray(T const* ptr, size_t size, size_t allocate = 0) {
00131         len = size;
00132         allocated = allocate;
00133         if (allocate != 0) {
00134             assert(allocate >= size);
00135             data = new T[allocate];
00136             memcpy(data, ptr, size);
00137         } else {
00138             data = (T*)ptr;
00139         }
00140     }
00141 
00146     dbArray(dbArray<T> const& arr) { // copy constructor
00147         allocated = arr.allocated;
00148         len = arr.len;
00149         if (allocated) {
00150             data = new T[allocated];
00151             memcpy(data, arr.data, len);
00152         } else {
00153             data = arr.data;
00154         }
00155     }
00156 
00160     ~dbArray() {
00161         if (allocated) {
00162             delete[] data;
00163             data = NULL;
00164         }
00165     }
00166 
00171     dbArray<T>& operator = (dbArray<T> const& arr) {
00172         if (this == &arr) { 
00173             return *this;
00174         }
00175         if (allocated) {
00176             delete[] data;
00177         }
00178         if ((len = arr.len) != 0) {
00179             data = new T[len];
00180             memcpy(data, arr.data, len);
00181         }
00182         allocated = len;
00183         return *this;
00184     }
00185 
00190     T const& last() {
00191         assert(len > 0);
00192         return data[len-1];
00193     }
00194 
00202     void assign(T const* ptr, size_t size, bool copy = true) {
00203         if (allocated) {
00204             delete[] data;
00205         }
00206         len = size;
00207         if (copy && size != 0) {
00208             data = new T[size];
00209             memcpy(data, ptr, size);
00210             allocated = size;
00211         } else {
00212             data = (T*)ptr;
00213             allocated = 0;
00214         }
00215     }
00216 
00222     T const& operator [](size_t index) const {
00223         assert(index < len);
00224         return data[index];
00225     }
00226 
00232     void putat(size_t index, T const& value) {
00233         assert(index < len);
00234         if (!allocated) {
00235             T* copy = new T[len];
00236             memcpy(copy, data, len);
00237             data = copy;
00238             allocated = len;
00239         }
00240         data[index] = value;
00241     }
00242 
00248     T const& getat(size_t index) const {
00249         assert(index < len);
00250         return data[index];
00251     }
00252 
00256     void clear() {
00257         if (allocated) {
00258             delete[] data;
00259         }
00260         data = NULL;
00261         len = 0;
00262         allocated = 0;
00263     }
00264 
00269     void resize(size_t size) {
00270         if (size > len && size > allocated) {
00271             T* p = new T[size];
00272             memcpy(p, data, len);
00273             if (allocated) {
00274                 delete[] data;
00275             }
00276             data = p;
00277             allocated = size;
00278         }
00279         len = size;
00280     }
00281 
00286     void append(T const& value) {
00287         insert(value, len);
00288     }
00289 
00295     void insert(T const& value, size_t index = 0) {
00296         assert(index <= len);
00297         if (len >= allocated) {
00298             size_t newSize = len == 0 ? 8 : len*2;
00299             T* p = new T[newSize];
00300             memcpy(p, data, index);
00301             p[index] = value;
00302             memcpy(p+index+1, data+index, (len-index));
00303             if (allocated) {
00304                 delete[] data;
00305             }
00306             data = p;
00307             allocated = newSize;
00308         } else {
00309             memmove(data+index+1, data+index, (len-index));
00310             data[index] = value;
00311         }
00312         len += 1;
00313     }
00314 
00319     void remove(size_t index) {
00320         assert(index < len);
00321         len -= 1;
00322         if (index != len && !allocated) {
00323             T* p = new T[len];
00324             memcpy(p, data, index);
00325             memcpy(p+index, data+index+1, (len-index));
00326             allocated = len;
00327             data = p;
00328         } else {
00329             memmove(data+index, data+index+1, (len-index));
00330         }
00331     }
00332 
00337     T const* get() const { return data; }
00338 
00343     T* update() { 
00344         if (!allocated) {
00345             T* copy = new T[len];
00346             memcpy(copy, data, len);
00347             data = copy;
00348             allocated = len;
00349         }
00350         return data; 
00351     }
00352 };
00353 
00359 template<class T>
00360 int index(dbArray<T> const& a, T value) {
00361     for (int i = 0, n = a.length(); i < n; i++) {
00362       if (a[i] == value) {
00363           return i;
00364       }
00365     }
00366     return -1;
00367 }
00368 
00374 template<class T>
00375 int rindex(dbArray<T> const& a, T value) {
00376     int i = a.length();
00377     while (--i >= 0 && a[i] != value);
00378     return i;
00379 }
00380 
00381 END_GIGABASE_NAMESPACE
00382 
00383 #endif
00384 

Generated on Thu Nov 24 23:14:29 2005 for GigaBASE by doxygen 1.3.5