00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef __ARRAY_H__
00012 #define __ARRAY_H__
00013
00014 BEGIN_FASTDB_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 FASTDB_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*const*)(this+1); }
00049 };
00050
00051
00055 template<class T>
00056 class dbArray : public dbAnyArray {
00057 friend class dbTableDescriptor;
00058 protected:
00059 T* data;
00060 size_t allocated;
00061
00062 static void arrayAllocator(dbAnyArray* aArray, void* data, size_t length)
00063 {
00064 dbArray* array = (dbArray*)aArray;
00065 array->len = length;
00066 if (array->allocated) {
00067 delete[] array->data;
00068 }
00069 if (data != NULL || length == 0) {
00070 array->data = (T*)data;
00071 array->allocated = 0;
00072 } else {
00073 array->data = new T[length];
00074 array->allocated = length;
00075 }
00076 }
00077
00078 inline void memcpy(T* dst, T const* src, size_t len) {
00079 int n = (int)len;
00080 while (--n >= 0) {
00081 *dst++ = *src++;
00082 }
00083 }
00084
00085 inline void memmove(T* dst, T const* src, size_t len) {
00086 int n = (int)len;
00087 if (dst < src) {
00088 while (--n >= 0) {
00089 *dst++ = *src++;
00090 }
00091 } else {
00092 dst += n;
00093 src += n;
00094 while (--n >= 0) {
00095 *--dst = *--src;
00096 }
00097 }
00098 }
00099
00100 public:
00101 dbFieldDescriptor* dbDescribeComponents(dbFieldDescriptor* fd) {
00102 fd->type = fd->appType = dbField::tpArray;
00103 fd->dbsSize = sizeof(dbVarying);
00104 fd->alignment = 4;
00105 fd->arrayAllocator = arrayAllocator;
00106 return dbDescribeField(new dbFieldDescriptor("[]", 0, sizeof(T), 0),
00107 *(T*)fd);
00108 }
00109
00113 dbArray() {
00114 data = NULL;
00115 len = 0;
00116 allocated = 0;
00117 }
00118
00123 dbArray(size_t size) {
00124 data = (size != 0) new T[size] : NULL;
00125 len = size;
00126 allocated = size;
00127 }
00128
00136 dbArray(T const* ptr, size_t size, size_t allocate = 0) {
00137 len = size;
00138 allocated = allocate;
00139 if (allocate != 0) {
00140 assert(allocate >= size);
00141 data = new T[allocate];
00142 memcpy(data, ptr, size);
00143 } else {
00144 data = (T*)ptr;
00145 }
00146 }
00147
00152 dbArray(dbArray const& arr) {
00153 allocated = arr.allocated;
00154 len = arr.len;
00155 if (allocated) {
00156 data = new T[allocated];
00157 memcpy(data, arr.data, len);
00158 } else {
00159 data = arr.data;
00160 }
00161 }
00162
00166 ~dbArray() {
00167 if (allocated) {
00168 delete[] data;
00169 }
00170 }
00171
00176 dbArray& operator = (dbArray 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
00248
00254 T const& getat(size_t index) const {
00255 assert(index < len);
00256 return data[index];
00257 }
00258
00262 void clear() {
00263 if (allocated) {
00264 delete[] data;
00265 }
00266 data = NULL;
00267 len = 0;
00268 allocated = 0;
00269 }
00270
00275 void resize(size_t size) {
00276 if (size > len && size > allocated) {
00277 T* p = new T[size];
00278 memcpy(p, data, len);
00279 if (allocated) {
00280 delete[] data;
00281 }
00282 data = p;
00283 allocated = size;
00284 }
00285 len = size;
00286 }
00287
00292 void append(T const& value) {
00293 insert(value, len);
00294 }
00295
00303 int bsearch(T value) {
00304 size_t l = 0, r = len;
00305 while (l < r) {
00306 size_t m = (l + 1) >> 1;
00307 if (data[m] < value) {
00308 l = m + 1;
00309 } else {
00310 r = m;
00311 }
00312 }
00313 return r;
00314 }
00315
00321 void insert(T const& value, size_t index = 0) {
00322 assert(index <= len);
00323 if (len >= allocated) {
00324 size_t newSize = len == 0 ? 8 : len*2;
00325 T* p = new T[newSize];
00326 memcpy(p, data, index);
00327 p[index] = value;
00328 memcpy(p+index+1, data+index, (len-index));
00329 if (allocated) {
00330 delete[] data;
00331 }
00332 data = p;
00333 allocated = newSize;
00334 } else {
00335 memmove(data+index+1, data+index, (len-index));
00336 data[index] = value;
00337 }
00338 len += 1;
00339 }
00340
00345 void remove(size_t index) {
00346 assert(index < len);
00347 len -= 1;
00348 if (index != len && !allocated) {
00349 T* p = new T[len];
00350 memcpy(p, data, index);
00351 memcpy(p+index, data+index+1, (len-index));
00352 allocated = len;
00353 data = p;
00354 } else {
00355 memmove(data+index, data+index+1, (len-index));
00356 }
00357 }
00358
00363 T const* get() const { return data; }
00364
00369 T* update() {
00370 if (!allocated) {
00371 T* copy = new T[len];
00372 memcpy(copy, data, len);
00373 data = copy;
00374 allocated = len;
00375 }
00376 return data;
00377 }
00378 };
00379
00385 template<class T>
00386 int index(dbArray<T> const& a, T value) {
00387 for (int i = 0, n = a.length(); i < n; i++) {
00388 if (a[i] == value) {
00389 return i;
00390 }
00391 }
00392 return -1;
00393 }
00394
00400 template<class T>
00401 int rindex(dbArray<T> const& a, T value) {
00402 int i = a.length();
00403 while (--i >= 0 && a[i] != value);
00404 return i;
00405 }
00406
00407 END_FASTDB_NAMESPACE
00408
00409 #endif
00410