aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcathook <cat.hook31894@gmail.com>2013-11-25 00:37:21 +0800
committercathook <cat.hook31894@gmail.com>2013-11-25 00:37:21 +0800
commit24ec80854b0145eac5f6401ca34ee82121468064 (patch)
tree945192058d2c6a983aa5142ba393e76572a5c211
parent3f420e030428bef9327b458154386dfc62ca6319 (diff)
parent213a03a1d060b4d41e9978c022f880f5a8a510c6 (diff)
downloadctl-24ec80854b0145eac5f6401ca34ee82121468064.tar.gz
ctl-24ec80854b0145eac5f6401ca34ee82121468064.tar.zst
ctl-24ec80854b0145eac5f6401ca34ee82121468064.zip
Merge branch 'feature-vector'
-rw-r--r--include/vector.h118
-rw-r--r--src/vector.c159
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));
+ }
}