• Main Page
  • Classes
  • Files
  • File List

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 
00016 #ifdef index // at some platform index(s,c) is defined strchr(s,x)
00017 #undef index
00018 #endif
00019 
00020 #ifdef rindex // at some platform rindex(s,c) is defined strrchr(s,x)
00021 #undef rindex
00022 #endif
00023 
00027 class GIGABASE_DLL_ENTRY dbAnyArray {
00028     friend class dbTableDescriptor;
00029   protected:
00030     size_t len;
00031 
00032   public:
00033     static void arrayAllocator(dbAnyArray* aArray, void* data, size_t length)
00034     {
00035         aArray->len = length;
00036         *(void**)(aArray+1) = data;
00037     }
00042     size_t length() const { return len; }
00043 
00048     void const* base() const { return *(void**)(this+1); }
00049 };
00050 
00054 template<class T>
00055 class dbArray : public dbAnyArray {
00056     friend class dbTableDescriptor;
00057   protected:
00058     T*     data;
00059     size_t allocated;
00060 
00061     static void arrayAllocator(dbAnyArray* aArray, void* data, size_t length)
00062     {
00063         dbArray<T>* array = (dbArray<T>*)aArray;
00064         array->len = length;
00065         if (array->allocated) {
00066             delete[] array->data;
00067         }
00068         if (data != NULL || length == 0) {
00069             array->data = (T*)data;
00070             array->allocated = 0;
00071         } else {
00072             array->data = new T[length];
00073             array->allocated = length;
00074         }
00075     }
00076     
00077     inline void memcpy(T* dst, T const* src, size_t len) { 
00078         int n = (int)len;
00079         while (--n >= 0) { 
00080             *dst++ = *src++;
00081         }
00082     }
00083 
00084     inline void memmove(T* dst, T const* src, size_t len) { 
00085         int n = (int)len;
00086         if (dst < src) {
00087             while (--n >= 0) { 
00088                 *dst++ = *src++;
00089             }
00090         } else { 
00091             dst += n;
00092             src += n;       
00093             while (--n >= 0) { 
00094                 *--dst = *--src;
00095             }
00096         }
00097     }
00098 
00099   public:
00100     dbFieldDescriptor* dbDescribeComponents(dbFieldDescriptor* fd) {
00101         fd->type = fd->appType = dbField::tpArray;
00102         fd->dbsSize = sizeof(dbVarying);
00103         fd->alignment = 4;
00104         fd->arrayAllocator = arrayAllocator;
00105         return dbDescribeField(new dbFieldDescriptor(STRLITERAL("[]"), 0, sizeof(T), 0),
00106                                *(T*)fd);
00107     }
00108 
00112     dbArray() {
00113         data = NULL;
00114         len = 0;
00115         allocated = 0;
00116     }
00117 
00122     dbArray(size_t size) {
00123         data = (size != 0) ? new T[size] : NULL;
00124         len = size;
00125         allocated = size;
00126     }
00127 
00135     dbArray(T const* ptr, size_t size, size_t allocate = 0) {
00136         len = size;
00137         allocated = allocate;
00138         if (allocate != 0) {
00139             assert(allocate >= size);
00140             data = new T[allocate];
00141             memcpy(data, ptr, size);
00142         } else {
00143             data = (T*)ptr;
00144         }
00145     }
00146 
00151     dbArray(dbArray<T> const& arr) { // copy constructor
00152         allocated = arr.allocated;
00153         len = arr.len;
00154         if (allocated) {
00155             data = new T[allocated];
00156             memcpy(data, arr.data, len);
00157         } else {
00158             data = arr.data;
00159         }
00160     }
00161 
00165     ~dbArray() {
00166         if (allocated) {
00167             delete[] data;
00168             data = NULL;
00169         }
00170     }
00171 
00176     dbArray<T>& operator = (dbArray<T> const& arr) {
00177         if (this == &arr) { 
00178             return *this;
00179         }
00180         if (allocated) {
00181             delete[] data;
00182         }
00183         if ((len = arr.len) != 0) {
00184             data = new T[len];
00185             memcpy(data, arr.data, len);
00186         }
00187         allocated = len;
00188         return *this;
00189     }
00190 
00195     T const& last() {
00196         assert(len > 0);
00197         return data[len-1];
00198     }
00199 
00207     void assign(T const* ptr, size_t size, bool copy = true) {
00208         if (allocated) {
00209             delete[] data;
00210         }
00211         len = size;
00212         if (copy && size != 0) {
00213             data = new T[size];
00214             memcpy(data, ptr, size);
00215             allocated = size;
00216         } else {
00217             data = (T*)ptr;
00218             allocated = 0;
00219         }
00220     }
00221 
00227     T const& operator [](size_t index) const {
00228         assert(index < len);
00229         return data[index];
00230     }
00231 
00237     void putat(size_t index, T const& value) {
00238         assert(index < len);
00239         if (!allocated) {
00240             T* copy = new T[len];
00241             memcpy(copy, data, len);
00242             data = copy;
00243             allocated = len;
00244         }
00245         data[index] = value;
00246     }
00247 
00253     T const& getat(size_t index) const {
00254         assert(index < len);
00255         return data[index];
00256     }
00257 
00261     void clear() {
00262         if (allocated) {
00263             delete[] data;
00264         }
00265         data = NULL;
00266         len = 0;
00267         allocated = 0;
00268     }
00269 
00274     void resize(size_t size) {
00275         if (size > len && size > allocated) {
00276             T* p = new T[size];
00277             memcpy(p, data, len);
00278             if (allocated) {
00279                 delete[] data;
00280             }
00281             data = p;
00282             allocated = size;
00283         }
00284         len = size;
00285     }
00286 
00291     void append(T const& value) {
00292         insert(value, len);
00293     }
00294 
00299     bool contains(T const& value) { 
00300         for (int i = 0, n = len; i < n; i++) {
00301             if (data[i] == value) {
00302                 return true;
00303             }
00304         }
00305         return false;
00306     }
00307 
00312     bool appendUnique(T const& value) { 
00313         if (contains(value)) {
00314             return false;
00315         }
00316         insert(value, len);
00317         return true;
00318     }
00319 
00325     void insert(T const& value, size_t index = 0) {
00326         assert(index <= len);
00327         if (len >= allocated) {
00328             size_t newSize = len == 0 ? 8 : len*2;
00329             T* p = new T[newSize];
00330             memcpy(p, data, index);
00331             p[index] = value;
00332             memcpy(p+index+1, data+index, (len-index));
00333             if (allocated) {
00334                 delete[] data;
00335             }
00336             data = p;
00337             allocated = newSize;
00338         } else {
00339             memmove(data+index+1, data+index, (len-index));
00340             data[index] = value;
00341         }
00342         len += 1;
00343     }
00344 
00349     void remove(size_t index) {
00350         assert(index < len);
00351         len -= 1;
00352         if (index != len && !allocated) {
00353             T* p = new T[len];
00354             memcpy(p, data, index);
00355             memcpy(p+index, data+index+1, (len-index));
00356             allocated = len;
00357             data = p;
00358         } else {
00359             memmove(data+index, data+index+1, (len-index));
00360         }
00361     }
00362 
00367     T const* get() const { return data; }
00368 
00373     T* update() { 
00374         if (!allocated) {
00375             T* copy = new T[len];
00376             memcpy(copy, data, len);
00377             data = copy;
00378             allocated = len;
00379         }
00380         return data; 
00381     }
00382 };
00383 
00389 template<class T>
00390 int index(dbArray<T> const& a, T value) {
00391     for (int i = 0, n = a.length(); i < n; i++) {
00392       if (a[i] == value) {
00393           return i;
00394       }
00395     }
00396     return -1;
00397 }
00398 
00404 template<class T>
00405 int rindex(dbArray<T> const& a, T value) {
00406   int i = (int)a.length();
00407     while (--i >= 0 && a[i] != value);
00408     return i;
00409 }
00410 
00411 END_GIGABASE_NAMESPACE
00412 
00413 #endif
00414 

Generated on Mon Aug 23 2010 00:04:01 for GigaBASE by  doxygen 1.7.1