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, int n) { 
00071         while (--n >= 0) { 
00072             *dst++ = *src++;
00073         }
00074     }
00075 
00076     inline void memmove(T* dst, T const* src, int n) { 
00077         if (dst < src) {
00078             while (--n >= 0) { 
00079                 *dst++ = *src++;
00080             }
00081         } else { 
00082             dst += n;
00083             src += n;       
00084             while (--n >= 0) { 
00085                 *--dst = *--src;
00086             }
00087         }
00088     }
00089 
00090   public:
00091     dbFieldDescriptor* dbDescribeComponents(dbFieldDescriptor* fd) {
00092         fd->type = fd->appType = dbField::tpArray;
00093         fd->dbsSize = sizeof(dbVarying);
00094         fd->alignment = 4;
00095         fd->arrayAllocator = arrayAllocator;
00096         return dbDescribeField(new dbFieldDescriptor(STRLITERAL("[]"), 0, sizeof(T), 0),
00097                                *(T*)fd);
00098     }
00099 
00103     dbArray() {
00104         data = NULL;
00105         len = 0;
00106         allocated = 0;
00107     }
00108 
00113     dbArray(size_t size) {
00114         if (size != 0) {
00115             data = new T[size];
00116         }
00117         len = size;
00118         allocated = size;
00119     }
00120 
00128     dbArray(T const* ptr, size_t size, size_t allocate = 0) {
00129         len = size;
00130         allocated = allocate;
00131         if (allocate != 0) {
00132             assert(allocate >= size);
00133             data = new T[allocate];
00134             memcpy(data, ptr, size);
00135         } else {
00136             data = (T*)ptr;
00137         }
00138     }
00139 
00144     dbArray(dbArray<T> const& arr) { // copy constructor
00145         allocated = arr.allocated;
00146         len = arr.len;
00147         if (allocated) {
00148             data = new T[allocated];
00149             memcpy(data, arr.data, len);
00150         } else {
00151             data = arr.data;
00152         }
00153     }
00154 
00158     ~dbArray() {
00159         if (allocated) {
00160             delete[] data;
00161             data = NULL;
00162         }
00163     }
00164 
00169     dbArray<T>& operator = (dbArray<T> const& arr) {
00170         if (this == &arr) { 
00171             return *this;
00172         }
00173         if (allocated) {
00174             delete[] data;
00175         }
00176         if ((len = arr.len) != 0) {
00177             data = new T[len];
00178             memcpy(data, arr.data, len);
00179         }
00180         allocated = len;
00181         return *this;
00182     }
00183 
00188     T const& last() {
00189         assert(len > 0);
00190         return data[len-1];
00191     }
00192 
00200     void assign(T const* ptr, size_t size, bool copy = true) {
00201         if (allocated) {
00202             delete[] data;
00203         }
00204         len = size;
00205         if (copy && size != 0) {
00206             data = new T[size];
00207             memcpy(data, ptr, size);
00208             allocated = size;
00209         } else {
00210             data = (T*)ptr;
00211             allocated = 0;
00212         }
00213     }
00214 
00220     T const& operator [](size_t index) const {
00221         assert(index < len);
00222         return data[index];
00223     }
00224 
00230     void putat(size_t index, T const& value) {
00231         assert(index < len);
00232         if (!allocated) {
00233             T* copy = new T[len];
00234             memcpy(copy, data, len);
00235             data = copy;
00236             allocated = len;
00237         }
00238         data[index] = value;
00239     }
00240 
00246     T const& getat(size_t index) const {
00247         assert(index < len);
00248         return data[index];
00249     }
00250 
00254     void clear() {
00255         if (allocated) {
00256             delete[] data;
00257         }
00258         data = NULL;
00259         len = 0;
00260         allocated = 0;
00261     }
00262 
00267     void resize(size_t size) {
00268         if (size > len && size > allocated) {
00269             T* p = new T[size];
00270             memcpy(p, data, len);
00271             if (allocated) {
00272                 delete[] data;
00273             }
00274             data = p;
00275             allocated = size;
00276         }
00277         len = size;
00278     }
00279 
00284     void append(T const& value) {
00285         insert(value, len);
00286     }
00287 
00293     void insert(T const& value, size_t index = 0) {
00294         assert(index <= len);
00295         if (len >= allocated) {
00296             size_t newSize = len == 0 ? 8 : len*2;
00297             T* p = new T[newSize];
00298             memcpy(p, data, index);
00299             p[index] = value;
00300             memcpy(p+index+1, data+index, (len-index));
00301             if (allocated) {
00302                 delete[] data;
00303             }
00304             data = p;
00305             allocated = newSize;
00306         } else {
00307             memmove(data+index+1, data+index, (len-index));
00308             data[index] = value;
00309         }
00310         len += 1;
00311     }
00312 
00317     void remove(size_t index) {
00318         assert(index < len);
00319         len -= 1;
00320         if (index != len && !allocated) {
00321             T* p = new T[len];
00322             memcpy(p, data, index);
00323             memcpy(p+index, data+index+1, (len-index));
00324             allocated = len;
00325             data = p;
00326         } else {
00327             memmove(data+index, data+index+1, (len-index));
00328         }
00329     }
00330 
00335     T const* get() const { return data; }
00336 
00341     T* update() { 
00342         if (!allocated) {
00343             T* copy = new T[len];
00344             memcpy(copy, data, len);
00345             data = copy;
00346             allocated = len;
00347         }
00348         return data; 
00349     }
00350 };
00351 
00357 template<class T>
00358 int index(dbArray<T> const& a, T value) {
00359     for (int i = 0, n = a.length(); i < n; i++) {
00360       if (a[i] == value) {
00361           return i;
00362       }
00363     }
00364     return -1;
00365 }
00366 
00372 template<class T>
00373 int rindex(dbArray<T> const& a, T value) {
00374     int i = a.length();
00375     while (--i >= 0 && a[i] != value);
00376     return i;
00377 }
00378 
00379 END_GIGABASE_NAMESPACE
00380 
00381 #endif
00382 

Generated on Thu Feb 12 18:46:26 2004 for GigaBASE by doxygen 1.3.5