diff options
Diffstat (limited to 'src/vector.c')
-rw-r--r-- | src/vector.c | 159 |
1 files changed, 110 insertions, 49 deletions
diff --git a/src/vector.c b/src/vector.c index babcd74..e47ccd5 100644 --- a/src/vector.c +++ b/src/vector.c @@ -1,5 +1,5 @@ -#include "utility.h" #include "vector.h" +#include "utility.h" #include <stdlib.h> #include <stddef.h> @@ -13,83 +13,144 @@ typedef struct{ char buf[]; } VectorHeader; -#define getHeader(X) ((VectorHeader*)(pCHAR(X)-offsetof(VectorHeader,buf))) -#define getTotal(X) ((X)->size*(X)->mem_count+sizeof(VectorHeader)) +#define getHeader(X) ((VectorHeader*)(pChar(X)-sizeof(VectorHeader)) +#define getTotal2(X,Y) ((Y)*(X)+sizeof(VectorHeader)) +#define getTotal(X) getTotal2((X)->mem_count,(X)->size) -void* ctl_vector_initX(void** ptr, size_t size, uint init_count){ +/********************** initalize *************************/ +pvoid ctl_vector_initX(ppvoid v, size_t size, uint count){ VectorHeader *tmp; int mem = 0; if(init_count >= 1) for(mem = 1; mem < init_count; mem *= 2); - - tmp = ctl_malloc(sizeof(VectorHeader) + (mem * size)); + + tmp = (VectorHeader*)ctl_malloc(getTotal2(mem, size)); tmp->size = size; tmp->use_count = init_count; tmp->mem_count = mem; - if(ptr != NULL){ - *ptr = pVOID(tmp->buf); + if(v != NULL){ + *v = pVoid(tmp->buf); } - return pVOID(tmp->buf); + return pVoid(tmp->buf); +} + +/******************** destructure *************************/ +pvoid ctl_vector_freeX(ppvoid v){ + free(pVoid(getHeader(*v))); + *v = NULL; + return NULL; +} + +/******************** methods about get??? ****************/ +int ctl_vector_getSizeX(ppvoid v){ + return getHeader(*v)->use_count; +} + +pcvoid ctl_vector_getEntryX(ppvoid v, uint index); + return pcVoid(pChar(*v) + getHeader(*v)->size * index); } -void* ctl_vector_freeX(void **ptr){ - free(pVOID(getHeader(*ptr))); - return (*ptr = NULL); +int ctl_vector_getEntrySizeX(ppvoid v){ + return getHeader(*v)->size; } -int ctl_vector_addBackX(void** ptr, void* entry){ - VectorHeader *tmp = getHeader(*ptr); +/******************** methods about set??? ****************/ +int ctl_vector_setSizeX(ppvoid v, uint count){ + VectorHeader *tmp = getHeader(*v); + + int mem = 0; + if(count >= 1) + for(mem = 1; mem < count; mem *= 2); + tmp->use_count = count; + tmp->mem_count = mem; + + tmp = (VectorHeader*)ctl_realloc(pVoid(tmp), getTotal(tmp)); + *v = pVoid(tmp->buf); + + return tmp->use_count; +} +pvoid ctl_vector_setEntryX(ppvoid v, uint index, pcvoid data){ + VectorHeader *tmp = getHeader(*v); + memcpy(pVoid(v->buf + index * tmp->size), data, tmp->size); +} + +/************** add/del element on the back ***************/ +int ctl_vector_addBackX(ppvoid v, pcvoid entry){ + VectorHeader *tmp = getHeader(*v); if(tmp->use_count + 1 > tmp->mem_count){ if(tmp->mem_count == 0) tmp->mem_count = 1; else tmp->mem_count *= 2; - tmp = (VectorHeader*)realloc(pVOID(tmp), getTotal(tmp)); - *ptr = pVOID(tmp->buf); + tmp = (VectorHeader*)realloc(pVoid(tmp), getTotal(tmp)); + *v = pVoid(tmp->buf); } - memcpy(tmp->buf + tmp->size * tmp->use_count, entry, tmp->size); - return ++tmp->use_count; + memcpy(v->buf + tmp->size * tmp->use_count, entry, tmp->size); + tmp->use_count++; + return tmp->use_count; } -int ctl_vector_delBackX(void** ptr){ - VectorHeader *tmp = getHeader(*ptr); +int ctl_vector_delBackX(ppvoid v){ + VectorHeader *tmp = getHeader(*v); if((tmp->use_count - 1) * 2 < tmp->mem_count){ tmp->mem_count /= 2; tmp = (VectorHeader*)realloc(pVOID(tmp), getTotal(tmp)); - *ptr = pVOID(tmp->buf); + *v = pVOID(tmp->buf); } - return (--tmp->use_count); -} -int ctl_vector_setSizeX(void** ptr, uint count){ - VectorHeader *tmp = getHeader(*ptr); - - int mem = 0; - if(count >= 1) - for(mem = 1; mem < count; mem *= 2); - tmp->mem_count = mem; - - tmp = (VectorHeader*)realloc(pVOID(tmp), getTotal(tmp)); - *ptr = pVOID(tmp->buf); - return (tmp->use_count = count); -} -void* ctl_vector_setEntryX(void** ptr, uint index, void* data){ - VectorHeader *tmp = getHeader(*ptr); - void* dst = pVOID(tmp->buf + tmp->size * index); - memcpy(dst, data, tmp->size); - return dst; + tmp->use_count--; + return tmp->use_count; } +//int ctl_vector_addFrontX(ppvoid v, pcvoid entry); +//int ctl_vector_delFrontX(ppvoid v); -int ctl_vector_getSizeX (void** ptr){ - return getHeader(*ptr)->use_count; +int ctl_vector_catX(ppvoid v, ppcvoid v2){ + int count0 = getHeader(*v)->use_count; + int count2 = getHeader(*v)->use_count; + ctl_vector_setSize(v, count0 + count2); + int i; + for(i = 0; i < count2; i++) + ctl_vector_setEntry(v, count0 + i, ctl_vector_getEntry(v2, i)); + return count0 + count2; } - -void* ctl_vector_getEntryX (void** ptr, uint index){ - VectorHeader *tmp = getHeader(*ptr); - return pVOID(tmp->buf + tmp->size * index); +pvoid ctl_vector_copyX(ppvoid v, ppcvoid v2){ + VectorHeader *tmp = getHeader(*v2); + pvoid *p = malloc(getTotal(*v2)); + memcpy(p, *v2, getTotal(*v2)); + if(*v != NULL){ + ctl_vector_free(v); + *v = p; + } + return p; } - -int ctl_vector_getEntrySizeX(void** ptr){ - return getHeader(*ptr)->mem_count; +int ctl_vector_replaceX( ppvoid v , uint start1, uint length1 + ppcvoid v2, uint start2, int length2){ + int end1 = start1 + length1 - 1; + int end2 = start2 + abs(length2) - 1, step2 = 1; + if(length2 < 0){ + length2 *= -1; + step2 *= -1; + ctl_swap(int, start2, end2); + } + if (length1 < length2){ // need increase size + int sz0 = ctl_vector_getSize(v); + int delta = length2 - length1; + ctl_vector_setSize(v, sz0 + delta); + int i; + for(i = sz0 + delta - 1; i - delta > end1; i--){ + ctl_vector_setEntry(v, i, ctl_vector_getEntry(v, i - delta)); + } + }else if(length1 > length2){ // need decrease size + int sz0 = ctl_vector_getSize(v); + int delta = length1 - length2; + int i; + for(i = end1 - delta + 1; i + delta < sz0; i++){ + ctl_vector_setEntry(v, i, ctl_vector_getEntry(v, i + delta)); + } + ctl_vector_setSize(v, sz0 - delta); + } + for( ; start2 != end2; start2 += step2, start1 += 1){ + ctl_vector_setEntry(v, start1, ctl_vector_getEntry(v2, start2)); + } } |