00001
00025 #include "vector.h"
00026 #include <stdlib.h>
00027 #include <string.h>
00028 #include <assert.h>
00029
00030
00031
00044 #ifdef _MSC_VER
00045 __inline
00046 #else
00047 inline
00048 #endif
00049 static Bool Resize(Vector *vec, unsigned int newSize) {
00050 void *newArray;
00051
00052 if ((newArray = realloc(vec->array, vec->itemSize * newSize)) == NULL) {
00053
00054 return FALSE;
00055 }
00056
00057 vec->array = newArray;
00058
00059 vec->size = newSize;
00060
00061 return TRUE;
00062 }
00063
00076 #define Enlarge(vec, inc) \
00077 Resize(vec, \
00078 ((inc) > (vec)->size << 1) ? (inc) + ((vec)->size << 1) : (vec)->size << 1)
00079
00088 #define Shrink(vec) \
00089 if (((vec)->size > (vec)->minSize) && \
00090 (((vec)->size >> 2) >= (vec)->items)) \
00091 Resize(vec, \
00092 ((vec)->size >> 1 > (vec)->minSize) ? (vec)->size >> 1 : (vec)->minSize)
00093
00105 static void HeapMoveDown(Vector *vec, unsigned int index, void *temp) {
00106 void *child;
00107 unsigned int childInd;
00108
00109
00110 assert(vec->lessOp != NULL);
00111
00112 for (; (childInd = HEAP_CHILD_INDEX(index)) <= vec->items; index = childInd) {
00113 child = &(((char*)vec->array)[childInd * vec->itemSize]);
00114 if ((childInd < (vec->items - 1)) &&
00115 (*(vec->lessOp))(vec->itemSize + (char*)child, child)) {
00116 childInd++;
00117 child = (char*)child + vec->itemSize;
00118 }
00119 if ((*(vec->lessOp))(child, temp)) {
00120 memcpy(&((char *)vec->array)[index * vec->itemSize], child,
00121 vec->itemSize);
00122 }
00123 else
00124 break;
00125 }
00126
00127 memcpy(&(((char *)vec->array)[index * vec->itemSize]), temp, vec->itemSize);
00128 }
00129
00130
00131
00132
00133 Bool VectorInit(Vector *vec, unsigned int initSize) {
00134
00135 assert(vec != NULL);
00136
00137 assert(initSize >= vec->minSize);
00138
00139 if ((vec->array = malloc(vec->itemSize * initSize)) == NULL) {
00140
00141 return FALSE;
00142 }
00143 #ifndef NDEBUG
00144
00145
00146 memset(vec->array, 0xCD, vec->itemSize * initSize);
00147 #endif
00148
00149 vec->size = initSize;
00150 vec->items = 0;
00151
00152 return TRUE;
00153 }
00154
00155 void VectorDestroy(Vector *vec) {
00156
00157 if (vec->destructOp && (vec->items > 0)) {
00158 void *item;
00159 unsigned int loop = vec->items;
00160
00161 for (item = vec->array; loop > 0; loop--,
00162 item = (char*)item + vec->itemSize) {
00163
00164 (*(vec->destructOp))(item);
00165 }
00166 }
00167
00168 if (vec->array != NULL) {
00169 free(vec->array);
00170 }
00171 #ifndef NDEBUG
00172
00173 memset(vec, 0xAB, sizeof(Vector));
00174 #endif
00175 }
00176
00177 Bool VectorCopy(Vector *target, Vector *source){
00178 void *array;
00179
00180 if ((array = malloc(source->itemSize * source->size)) == NULL) {
00181
00182 return FALSE;
00183 }
00184
00185 *target = *source;
00186
00187 target->array = array;
00188
00189 memcpy(target->array, source->array, source->itemSize * source->items);
00190
00191 return TRUE;
00192 }
00193
00194 void VectorClear(Vector *vec) {
00195
00196 if (vec->destructOp && (vec->items > 0)) {
00197 void *item;
00198 unsigned int loop = vec->items;
00199
00200 for (item = vec->array; loop > 0; loop--,
00201 item = (char*)item + vec->itemSize) {
00202
00203 (*(vec->destructOp))(item);
00204 }
00205 }
00206
00207 vec->items = 0;
00208
00209 Shrink(vec);
00210 }
00211
00212 void *VectorAdd(Vector *vec) {
00213
00214 if (vec->items == vec->size) {
00215
00216 if (!Resize(vec, vec->size << 1)) {
00217
00218 return NULL;
00219 }
00220 }
00221
00222 return &(((char *)vec->array)[vec->items++ * vec->itemSize]);
00223 }
00224
00225 void *VectorPush(Vector *vec, void *item) {
00226 void *newItem;
00227
00228 if (vec->items == vec->size) {
00229
00230 if (!Resize(vec, vec->size << 1)) {
00231
00232 return NULL;
00233 }
00234 }
00235
00236 memcpy(newItem = &(((char *)vec->array)[vec->items++ * vec->itemSize]),
00237 item, vec->itemSize);
00238
00239 return newItem;
00240 }
00241
00242 void *VectorHeapPush(Vector *vec, void *item) {
00243 void *parent;
00244 unsigned int index = vec->items++, parentInd;
00245
00246 assert(vec->lessOp != NULL);
00247
00248 if (vec->items == vec->size) {
00249
00250 if (!Resize(vec, vec->size << 1)) {
00251
00252 return NULL;
00253 }
00254 }
00255 for (; parentInd = HEAP_PARENT_INDEX(index),
00256 index && (*(vec->lessOp))(item,
00257 (parent = &((char *)vec->array)[parentInd * vec->itemSize]));
00258 index = parentInd) {
00259
00260 memcpy(&(((char *)vec->array)[index * vec->itemSize]), parent,
00261 vec->itemSize);
00262 }
00263
00264 memcpy(parent = &(((char *)vec->array)[index * vec->itemSize]), item,
00265 vec->itemSize);
00266 return parent;
00267 }
00268
00269 void VectorPop(Vector *vec) {
00270
00271 if (vec->items > 0) {
00272 vec->items--;
00273
00274 if (vec->destructOp) {
00275 (*(vec->destructOp))
00276 (&(((char *)vec->array)[vec->items * vec->itemSize]));
00277 }
00278
00279 Shrink(vec);
00280 }
00281 }
00282
00283 void VectorHeapPop(Vector *vec) {
00284
00285 if (vec->items > 0) {
00286 vec->items--;
00287
00288 if (vec->destructOp) {
00289 (*(vec->destructOp))(vec->array);
00290 }
00291
00292
00293 HeapMoveDown(vec, 0,
00294 &(((char *)vec->array)[vec->items * vec->itemSize]));
00295
00296 Shrink(vec);
00297 }
00298 }
00299
00300 void VectorHeapSort(Vector *vec) {
00301 void *lastItem;
00302 unsigned int items;
00303 #ifdef _MSC_VER
00304
00305 char tempVal[1024];
00306 assert(vec->itemSize <= 1024);
00307 #else
00308 char tempVal[vec->itemSize];
00309 #endif
00310
00311 if (vec->items == 0) return;
00312
00313 VectorMakeHeap(vec);
00314
00315 items = vec->items--;
00316 lastItem = &(((char *)vec->array)[vec->items * vec->itemSize]);
00317
00318 for (; vec->items < 0xFFFFFFFF; vec->items--,
00319 lastItem = (char*)lastItem - vec->itemSize) {
00320
00321 memcpy(tempVal, lastItem, vec->itemSize);
00322
00323 memcpy(lastItem, vec->array, vec->itemSize);
00324
00325 HeapMoveDown(vec, 0, tempVal);
00326 }
00327
00328 vec->items = items;
00329 }
00330
00331 void *VectorInsertMany(Vector *vec, unsigned int index, unsigned int count) {
00332 void *dest;
00333 unsigned int newSize = vec->items + count;
00334
00335 assert(index <= vec->items);
00336
00337 if (newSize > vec->size) {
00338
00339 if (!Enlarge(vec, newSize)) {
00340
00341 return NULL;
00342 }
00343 }
00344
00345 dest = &(((char *)vec->array)[index * vec->itemSize]);
00346
00347 memmove((char*)dest + count * vec->itemSize, dest,
00348 vec->itemSize * (vec->items - index));
00349
00350 vec->items = newSize;
00351 #ifndef NDEBUG
00352
00353 memset(dest, 0xCD, vec->itemSize * count);
00354 #endif
00355
00356 return dest;
00357 }
00358
00359 void VectorRemoveMany(Vector *vec, unsigned int index, unsigned int count) {
00360 void *trg, *item;
00361 unsigned int loop;
00362
00363 assert(index < vec->items);
00364
00365 assert(count <= (vec->items - index));
00366
00367 item = trg = &(((char *)vec->array)[index * vec->itemSize]);
00368
00369 if (vec->destructOp) {
00370
00371 for (loop = count; loop > 0; loop--, item = (char*)item + vec->itemSize) {
00372
00373 (*vec->destructOp)(trg);
00374 }
00375 }
00376 else {
00377
00378 item = (char*)trg + count * vec->itemSize;
00379 }
00380
00381
00382 memmove(trg, item, vec->itemSize * (vec->items - (index + count)));
00383
00384 vec->items -= count;
00385
00386 Shrink(vec);
00387 }
00388
00389 void VectorMakeHeap(Vector *vec) {
00390 unsigned int loop;
00391 void *item;
00392 #ifdef _MSC_VER
00393
00394 char tempVal[1024];
00395 assert(vec->itemSize <= 1024);
00396 #else
00397 char tempVal[vec->itemSize];
00398 #endif
00399
00400 if (vec->items == 0) return;
00401 loop = vec->items >> 1;
00402 item = &(((char *)vec->array)[loop * vec->itemSize]);
00403
00404 for (; loop < 0xFFFFFFFF; loop--, item = (char*)item - vec->itemSize) {
00405
00406 memcpy(tempVal, item, vec->itemSize);
00407
00408 HeapMoveDown(vec, loop, tempVal);
00409 }
00410 }
00411
00412 Bool VectorReserve(Vector *vec, unsigned int size) {
00413
00414 if (size > vec->size) {
00415
00416 return Resize(vec, size);
00417 }
00418
00419 return TRUE;
00420 }
00421
00422 void GenericPointerFree(void *item) {
00423 if (*(char**)item != NULL) {
00424 free(*((void **)item));
00425 }
00426 }
00427