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