diff options
author | cathook <cat.hook31894@gmail.com> | 2013-11-25 00:37:21 +0800 |
---|---|---|
committer | cathook <cat.hook31894@gmail.com> | 2013-11-25 00:37:21 +0800 |
commit | 24ec80854b0145eac5f6401ca34ee82121468064 (patch) | |
tree | 945192058d2c6a983aa5142ba393e76572a5c211 | |
parent | 3f420e030428bef9327b458154386dfc62ca6319 (diff) | |
parent | 213a03a1d060b4d41e9978c022f880f5a8a510c6 (diff) | |
download | ctl-24ec80854b0145eac5f6401ca34ee82121468064.tar.gz ctl-24ec80854b0145eac5f6401ca34ee82121468064.tar.zst ctl-24ec80854b0145eac5f6401ca34ee82121468064.zip |
Merge branch 'feature-vector'
-rw-r--r-- | include/vector.h | 118 | ||||
-rw-r--r-- | src/vector.c | 159 |
2 files changed, 210 insertions, 67 deletions
diff --git a/include/vector.h b/include/vector.h index b665df0..6dcc244 100644 --- a/include/vector.h +++ b/include/vector.h @@ -3,30 +3,112 @@ #include "utility.h" -void* ctl_vector_initX(void** ptr, size_t size, uint init_count); -void* ctl_vector_freeX(void** ptr); +/**********************************************************/ +/* This object is an array with dynamic table size. */ +/* methods: */ +/* init(addr of the vector, size per entry, size) */ +/* The vector's type depends on what user want to */ +/* store. For example: if you want an array for int, */ +/* you should decleare like "int* v", and call the */ +/* init() like this "init(&v, sizeof(int), 5)", and */ +/* it will initalize an array with 5 elements. */ +/* */ +/* free(addr of the vector) */ +/* Free the memory the vector use. Yous should call */ +/* it when you don't need the container. */ +/* */ +/* */ +/* getSize(addr of the vector) */ +/* Return the number of elements. */ +/* */ +/* getEntrySize(addr of the vector) */ +/* Return the size per entry, it dependent on what */ +/* type of data you store in the container. */ +/* */ +/* getEntry(addr of the vector, index) */ +/* Return a const pointer which point to the entry */ +/* with the index you give. */ +/* */ +/* */ +/* setSize(addr of the vector, new_size) */ +/* Resize the table to new_size. Note that it won't */ +/* initalize the newly element if you increase size. */ +/* */ +/* setEntry(addr of the vector, index, data) */ +/* Let the element with index you give be data. */ +/* */ +/* */ +/* addBack(addr of the vector, data) */ +/* Add an element which contain data at the back of */ +/* the vector. */ +/* */ +/* delBack(addr of the vector) */ +/* Remove the last element of the vector. */ +/* */ +/* addFront(addr of the vector, data) !! UNFINISHED !! */ +/* Add an element which contain data at the front of */ +/* the vector. */ +/* */ +/* delFront(addr of the vector) !! UNFINISHED !! */ +/* Remove the first element of the vector. */ +/* */ +/* */ +/* cat(addr of the v1, addr of the v2) */ +/* Concatenate the vector2 to the back of vector1. */ +/* */ +/* copy(addr of the v1, addr of the v2) */ +/* Let the contain in the v1 be the one in the v2 */ +/* */ +/* replace(addr of the v1, a, b, addr of the v2, x, y) */ +/* If b == 0, it will insert v2[x ... x+y-1] into */ +/* the place between v[a] */ +/* and v[a-1] */ +/* If y >= 0, it will replace v1[a ... a+b-1] */ +/* to v2[x ... x+y-1] */ +/* If y < 0, it will replace v1[a ... a+b-1] */ +/* to v2[x-y-1 ... x] with */ +/* reverse order. */ +/* */ +/**********************************************************/ -int ctl_vector_addBackX(void** ptr, void* entry); -int ctl_vector_delBackX(void** ptr); +pvoid ctl_vector_initX(ppvoid v, size_t size, uint count); +pvoid ctl_vector_freeX(ppvoid v); -int ctl_vector_setSizeX (void** ptr, uint count); -void* ctl_vector_setEntryX(void** ptr, uint index, void* data); +int ctl_vector_getSizeX (ppvoid v); +pcvoid ctl_vector_getEntryX (ppvoid v, uint index); +int ctl_vector_getEntrySizeX(ppvoid v); -int ctl_vector_getSizeX (void** ptr); -void* ctl_vector_getEntryX (void** ptr, uint index); -int ctl_vector_getEntrySizeX(void** ptr); +int ctl_vector_setSizeX (ppvoid v, uint count); +pvoid ctl_vector_setEntryX(ppvoid v, uint index, pcvoid data); -#define ctl_vector_init(X,Y,Z) ctl_vector_initX(ppVOID(X),Y,Z) -#define ctl_vector_free(X) ctl_vector_freeX(ppVOID(X)) +int ctl_vector_addBackX (ppvoid v, pcvoid entry); +int ctl_vector_delBackX (ppvoid v); +//int ctl_vector_addFrontX(ppvoid v, pcvoid entry); +//int ctl_vector_delFrontX(ppvoid v); -#define ctl_vector_addBack(X,Y) ctl_vector_addBackX(ppVOID(X),pVOID(Y)) -#define ctl_vector_delBack(X) ctl_vector_delBackX(ppVOID(X)) +int ctl_vector_catX (ppvoid v, ppcvoid v2); +pvoid ctl_vector_copyX (ppvoid v, ppcvoid v2); +int ctl_vector_replaceX(ppvoid v , uint i1, uint ct1, + ppcvoid v2, uint j1, int ct2); -#define ctl_vector_setSize(X,Y) ctl_vector_setSizeX (ppVOID(X),Y) -#define ctl_vector_setEntry(X,Y,Z) ctl_vector_setEntryX(ppVOID(X),Y,pVOID(Z)) +#define ctl_vector_init(X,Y,Z) ctl_vector_initX(ppVoid(X),Y,Z) +#define ctl_vector_free(X) ctl_vector_freeX(ppVoid(X)) -#define ctl_vector_getSize(X) ctl_vector_getSizeX (ppVOID(X)) -#define ctl_vector_getEntry(X,Y) ctl_vector_getEntryX (ppVOID(X),Y) -#define ctl_vector_getEntrySize(X) ctl_vector_getEntrySizeX(ppVOID(X)) +#define ctl_vector_getSize(X) ctl_vector_getSizeX (ppVoid(X)) +#define ctl_vector_getEntry(X,Y) ctl_vector_getEntryX (ppVoid(X),Y) +#define ctl_vector_getEntrySize(X) ctl_vector_getEntrySizeX(ppVoid(X)) + +#define ctl_vector_setSize(X,Y) ctl_vector_setSizeX (ppVoid(X),Y) +#define ctl_vector_setEntry(X,Y,Z) ctl_vector_setEntryX(ppVoid(X),Y,pcVoid(Z)) + +#define ctl_vector_addBack(X,Y) ctl_vector_addBackX(ppVoid(X),pcVoid(Y)) +#define ctl_vector_delBack(X) ctl_vector_delBackX(ppVoid(X)) +//#define ctl_vector_addFront(X,Y) ctl_vector_addBackX(ppVoid(X),pcVoid(Y)) +//#define ctl_vector_delFront(X) ctl_vector_delBackX(ppVoid(X)) + +#define ctl_vector_cat(X,Y) ctl_vector_catX (ppVoid(X),ppcVoid(Y)) +#define ctl_vector_copy(X,Y) ctl_vector_copyX(ppVoid(X),ppcVoid(Y)) +#define ctl_vector_replace(X,Y,Z,A,B,C) ctl_vector_replaceX( ppVoid(X),Y,Z,\ + ppcVoid(A),B,C) #endif /* __vector_h__ */ 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)); + } } |