00001
00002
00003
00004
00005
00006
00007
00008
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) {
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