diff --git a/Array.h b/Array.h index 3b791d5..85e09a4 100644 --- a/Array.h +++ b/Array.h @@ -1,251 +1,250 @@ -#ifndef ARRAY_INCLUDED - -#include -#include -#include -#include -/*带有assert的安全分配内存*/ -void *malloc_s(int _size){ - assert(_size > 0); - void *malloc_ptr = malloc(_size); - assert(malloc_ptr != NULL); - return malloc_ptr; -} -/*字符串变量的创建与复制*/ -char *malloc_s_strcpy(const char *const src){ - //申请char[]时需要多分配几个位置用于存放'\0'结束符 - char *dst = malloc_s(strlen(src)+2); - strcpy(dst, src); - return dst; -} -/*MARCO:根据类型安全分配内存*/ -#define MALLOC_S(TypeName) (TypeName *)(malloc_s(sizeof(TypeName))) -/*链表单元*/ -struct Array_{ - void *p; /*内容数据*/ - struct Array_ *next; -}; -/*通过单向链表实现的动态数组,需要指定内置数据的类型*/ -struct Array{ - struct Array_ *front, *back; /*头尾节点*/ - int TypeSize; /*内置类型的大小(不包含动态数据的纯大小)*/ - int size; /*总体大小*/ -}; -/*链表初始化*/ -void Array_create(struct Array *a, int ts) -{ - assert("Array_create" && ts > 0); - a->TypeSize = ts; - a->size = 0; - a->back = a->front = NULL; -} -void Array_release_(struct Array_ *a, struct Array_ *back, void (*rel)(void *)){ - if(a == back) return ; - Array_release_(a->next, back, rel); - rel(a->p); - free(a->p); - free(a); -} -/*释放动态分配的内存,需要指定释放内部动态成员的方法*/ -void Array_release(struct Array *a, void (*rel)(void *)){ - Array_release_(a->front, a->back, rel); - a->size = 0; - a->back = a->front = NULL; -} -/*返回指定位置的Array_*指针 -配合PAT宏获取内部数据*/ -struct Array_ *Array(struct Array *a, int pos){ - assert("Array[pos]" && pos >= 0 && pos < a->size); - struct Array_ *node = a->front; - for(int i = 0; i < pos; i ++) node = node->next; - return node; -} -/*在pos前插入*/ -void Array_insert(struct Array *a, void *p, int pos) -{ - assert("Array_insert" && pos >= 0 && pos <= a->size); - struct Array_ *newNode, *node = a->front; - newNode = MALLOC_S(struct Array_); - newNode->p = malloc_s(a->TypeSize); - memcpy(newNode->p, p, a->TypeSize); - if(pos == 0){ - newNode->next = a->front; - a->front = newNode; - }else{ - for(int i = 0; i < pos-1; i ++) node = node->next; - newNode->next = node->next; - node->next = newNode; - } - a->size += 1; -} -/*删除pos位置的Array_节点*/ -void Array_delete_pos(struct Array *a, int pos, void (*rel_)(void *)){ - assert("Array_delete" && pos >= 0 && pos < a->size && a->size != 0); - struct Array_ *node = a->front, *freeNode; - if(pos == 0){ - freeNode = a->front; - a->front = a->front->next; - rel_(freeNode->p); - free(freeNode); - }else{ - for(int i = 0; i < pos-1; i ++) node = node->next; - freeNode = node->next; - node->next = node->next->next; - rel_(freeNode->p); - free(freeNode); - } - a->size--; -} -/*删除node所指向的Array节点*/ -void Array_delete_p(struct Array *a, struct Array_ *node, void (*rel_)(void *)){ - assert("Array_delete_p" && node != a->back); - struct Array_ *freeNode; - if(node == a->front){ - freeNode = a->front; - a->front = a->front->next; - rel_(freeNode->p); - free(freeNode); - }else{ - freeNode = node->next; - node->next = node->next->next; - rel_(freeNode->p); - free(freeNode); - } - a->size--; -} -/*交换内容,即p指针*/ -void Array__swap(struct Array_ *a, struct Array_ *b){ - void *t = b->p; - b->p = a->p; - a->p = t; -} -/* -带有reverse选项的冒泡排序,默认(reverse == 0)是升序 -func(a,b)为排序所依据的比较函数 -a>b:>0 -a==b:0 -a < b:<0 -*/ -void Array_sort(struct Array *a, int (*func)(void *, void *), int reverse){ - reverse = reverse ? -1 : 1; - struct Array_ *sorted = a->back, *p; - while(a->front->next != sorted){ - for(p = a->front; p->next != sorted; p = p->next) - if(reverse*func(p->p,p->next->p) > 0) - Array__swap(p, p->next); - sorted = p; - } -} -/*指定类型 转换(void)Array.p中的内容*/ -#define PAT(TypeName, Array_Pointer) ((TypeName *)Array_Pointer->p) -/*链表的遍历*/ -#define Range(arr) for(struct Array_ *p = arr.front; p != arr.back; p = p->next) -/*链表指定类型的初始化*/ -#define DEF_ARRAY(Type, name) - - -void DoNothing(){} -/*记录每Array容器对象的信息*/ -struct ArrayObjects{ - void *p_obj; /*Array对象的地址*/ -}; -/*为每一个Array容器类实现释放管理*/ -struct ArrayClass{ - char *TypeName; /*容器内置类型的名称*/ - void (*rel_)(void *);/*释放Array对象内部单个元素数据的方式*/ - struct Array objects;/*该内置类型所有Array对象的信息*/ -}; -/*存储所有Array容器类*/ -struct Array ArrayList; -/*以TypeName注册一个新的ArrayClass,并且指定Rel__Func为释放单个元素的方式*/ -void ArrayClass_Reg(char *TypeName, void (*Rel__Func)(void *p)){ - struct ArrayClass ac; - ac.TypeName = malloc_s_strcpy(TypeName); - ac.rel_ = Rel__Func; - Array_create(&ac.objects, sizeof(struct ArrayObjects)); - Array_insert(&ArrayList, &ac, 0); -} -/*向给定TypName的ArrayClass注册一个新的对象,对象地址为p_obj*/ -void ArrayObj_Reg(char *TypeName, void *p_obj){ - struct Array_ *p; - for(p = ArrayList.front; p != ArrayList.back; p = p->next) - if(strcmp(((struct ArrayClass*)p->p)->TypeName, TypeName) == 0) - break; - Array_insert((&((struct ArrayClass*)p->p)->objects), &(struct ArrayObjects){p_obj}, 0); -} - -/*释放ArrayList中单个元素占用的资源*/ -void ArrayList_Rel_(void *p_class){ - free(((struct ArrayClass *)p_class)->TypeName); - Array_release(&((struct ArrayClass *)p_class)->objects, DoNothing); -} -/*初始化Array_List*/ -void ArrayList_Init(){ - Array_create(&ArrayList, sizeof(struct ArrayClass)); -} -/*释放ArrayList占用的资源*/ -void ArrayList_Rel(){ - Array_release(&ArrayList, ArrayList_Rel_); -} -/*主动提前释放资源,对于局部变量,需要在其被编译器释放前主动释放占用资源,防止内存泄漏*/ -void Array_Obj_PreRelease(struct Array *unrel_obj){ - for(struct Array_ *p = ArrayList.front; p != ArrayList.back; p = p->next) - for(struct Array_ *q = ((struct ArrayClass *)p->p)->objects.front; q != ((struct ArrayClass *)p->p)->objects.back; q = q->next) - if(unrel_obj == ((struct ArrayObjects*)q->p)->p_obj){ - printf("%s\n", ((struct ArrayClass *)p->p)->TypeName); - Array_release(unrel_obj, ((struct ArrayClass *)p->p)->rel_); - Array_delete_p(&((struct ArrayClass *)p->p)->objects, q, DoNothing); - return ; - } - assert("Array_Obj_PreRelease:NotFound"); -} -/*根据ArrayObj反查ArrayClass*/ -struct ArrayClass *ArrayList_Find_Class_From_Obj(struct Array *a){ - for(struct Array_ *p = ArrayList.front; p != ArrayList.back; p = p->next) - for(struct Array_ *q = ((struct ArrayClass *)p->p)->objects.front; q != ((struct ArrayClass *)p->p)->objects.back; q = q->next) - if(a == ((struct ArrayObjects*)q->p)->p_obj) - return (struct ArrayClass *)p->p; - assert("ArrayList_Find_Class_From_Obj:NotFound"); -} -/*重写简化的Array_delete*/ -void Array_deletepos(struct Array *a, int pos){ - Array_delete_pos(a, pos, ArrayList_Find_Class_From_Obj(a)->rel_); -} -void Array_deletep(struct Array *a, struct Array_ *node){ - Array_delete_p(a, node, ArrayList_Find_Class_From_Obj(a)->rel_); -} -/*MARCO:为Type注册一个新的ArrayClass,并且指定Rel__Func为释放单个元素的方式*/ -#define DECLARE_ARRAY(Type, RelFunc) ArrayClass_Reg(#Type, RelFunc); -/* -MARCO:为内置类型为Type的ArrayClass创建一个新的对象,名称为ArrName -Example: -struct ARRAY(a, struct A); -^^^^^^___________________^ -*/ -#define ARRAY(ArrName, Type) \ - Array ArrName; \ - Array_create(&ArrName, sizeof(Type)); \ - ArrayObj_Reg(#Type, &ArrName) - -#define ARRAY_BIND(ArrName, Type) \ - Array_create(&ArrName, sizeof(Type)); \ - ArrayObj_Reg(#Type, &ArrName); - -/* -Example: - -struct A{ - int a; -}; -void rel_(void*p){} -int main(){ - Array_Class_Init(); - DECLARE_ARRAY(struct A, rel_) - struct ARRAY(a, struct A); - - Array_Obj_PreRelease(&a); - Array_Class_Rel(); -} -*/ -#endif +#ifndef ARRAY_INCLUDED + +#include +#include +#include +#include +/*带有assert的安全分配内存*/ +void *malloc_s(int _size){ + assert(_size > 0); + void *malloc_ptr = malloc(_size); + assert(malloc_ptr != NULL); + return malloc_ptr; +} +/*字符串变量的创建与复制*/ +char *malloc_s_strcpy(const char *const src){ + //申请char[]时需要多分配几个位置用于存放'\0'结束符 + char *dst = malloc_s(strlen(src)+2); + strcpy(dst, src); + return dst; +} +/*MARCO:根据类型安全分配内存*/ +#define MALLOC_S(TypeName) (TypeName *)(malloc_s(sizeof(TypeName))) +/*链表单元*/ +struct Array_{ + void *p; /*内容数据*/ + struct Array_ *next; +}; +/*通过单向链表实现的动态数组,需要指定内置数据的类型*/ +struct Array{ + struct Array_ *front, *back; /*头尾节点*/ + int TypeSize; /*内置类型的大小(不包含动态数据的纯大小)*/ + int size; /*总体大小*/ +}; +/*链表初始化*/ +void Array_create(struct Array *a, int ts) +{ + assert("Array_create" && ts > 0); + a->TypeSize = ts; + a->size = 0; + a->back = a->front = NULL; +} +void Array_release_(struct Array_ *a, struct Array_ *back, void (*rel)(void *)){ + if(a == back) return ; + Array_release_(a->next, back, rel); + rel(a->p); + free(a->p); + free(a); +} +/*释放动态分配的内存,需要指定释放内部动态成员的方法*/ +void Array_release(struct Array *a, void (*rel)(void *)){ + Array_release_(a->front, a->back, rel); + a->size = 0; + a->back = a->front = NULL; +} +/*返回指定位置的Array_*指针 +配合PAT宏获取内部数据*/ +struct Array_ *Array(struct Array *a, int pos){ + assert("Array[pos]" && pos >= 0 && pos < a->size); + struct Array_ *node = a->front; + for(int i = 0; i < pos; i ++) node = node->next; + return node; +} +/*在pos前插入*/ +void Array_insert(struct Array *a, void *p, int pos) +{ + assert("Array_insert" && pos >= 0 && pos <= a->size); + struct Array_ *newNode, *node = a->front; + newNode = MALLOC_S(struct Array_); + newNode->p = malloc_s(a->TypeSize); + memcpy(newNode->p, p, a->TypeSize); + if(pos == 0){ + newNode->next = a->front; + a->front = newNode; + }else{ + for(int i = 0; i < pos-1; i ++) node = node->next; + newNode->next = node->next; + node->next = newNode; + } + a->size += 1; +} +/*删除pos位置的Array_节点*/ +void Array_delete_pos(struct Array *a, int pos, void (*rel_)(void *)){ + assert("Array_delete" && pos >= 0 && pos < a->size && a->size != 0); + struct Array_ *node = a->front, *freeNode; + if(pos == 0){ + freeNode = a->front; + a->front = a->front->next; + rel_(freeNode->p); + free(freeNode); + }else{ + for(int i = 0; i < pos-1; i ++) node = node->next; + freeNode = node->next; + node->next = node->next->next; + rel_(freeNode->p); + free(freeNode); + } + a->size--; +} +/*删除node所指向的Array节点*/ +void Array_delete_p(struct Array *a, struct Array_ *node, void (*rel_)(void *)){ + assert("Array_delete_p" && node != a->back); + struct Array_ *freeNode; + if(node == a->front){ + freeNode = a->front; + a->front = a->front->next; + rel_(freeNode->p); + free(freeNode); + }else{ + freeNode = node->next; + node->next = node->next->next; + rel_(freeNode->p); + free(freeNode); + } + a->size--; +} +/*交换内容,即p指针*/ +void Array__swap(struct Array_ *a, struct Array_ *b){ + void *t = b->p; + b->p = a->p; + a->p = t; +} +/* +带有reverse选项的冒泡排序,默认(reverse == 0)是升序 +func(a,b)为排序所依据的比较函数 +a>b:>0 +a==b:0 +a < b:<0 +*/ +void Array_sort(struct Array *a, int (*func)(void *, void *), int reverse){ + reverse = reverse ? -1 : 1; + struct Array_ *sorted = a->back, *p; + while(a->front->next != sorted){ + for(p = a->front; p->next != sorted; p = p->next) + if(reverse*func(p->p,p->next->p) > 0) + Array__swap(p, p->next); + sorted = p; + } +} +/*指定类型 转换(void)Array.p中的内容*/ +#define PAT(TypeName, Array_Pointer) ((TypeName *)Array_Pointer->p) +/*链表的遍历*/ +#define Range(arr) for(struct Array_ *p = arr.front; p != arr.back; p = p->next) +/*链表指定类型的初始化*/ +#define DEF_ARRAY(Type, name) + + +void DoNothing(){} +/*记录每Array容器对象的信息*/ +struct ArrayObjects{ + void *p_obj; /*Array对象的地址*/ +}; +/*为每一个Array容器类实现释放管理*/ +struct ArrayClass{ + char *TypeName; /*容器内置类型的名称*/ + void (*rel_)(void *);/*释放Array对象内部单个元素数据的方式*/ + struct Array objects;/*该内置类型所有Array对象的信息*/ +}; +/*存储所有Array容器类*/ +struct Array ArrayList; +/*以TypeName注册一个新的ArrayClass,并且指定Rel__Func为释放单个元素的方式*/ +void ArrayClass_Reg(char *TypeName, void (*Rel__Func)(void *p)){ + struct ArrayClass ac; + ac.TypeName = malloc_s_strcpy(TypeName); + ac.rel_ = Rel__Func; + Array_create(&ac.objects, sizeof(struct ArrayObjects)); + Array_insert(&ArrayList, &ac, 0); +} +/*向给定TypName的ArrayClass注册一个新的对象,对象地址为p_obj*/ +void ArrayObj_Reg(char *TypeName, void *p_obj){ + struct Array_ *p; + for(p = ArrayList.front; p != ArrayList.back; p = p->next) + if(strcmp(((struct ArrayClass*)p->p)->TypeName, TypeName) == 0) + break; + Array_insert((&((struct ArrayClass*)p->p)->objects), &(struct ArrayObjects){p_obj}, 0); +} + +/*释放ArrayList中单个元素占用的资源*/ +void ArrayList_Rel_(void *p_class){ + free(((struct ArrayClass *)p_class)->TypeName); + Array_release(&((struct ArrayClass *)p_class)->objects, DoNothing); +} +/*初始化Array_List*/ +void ArrayList_Init(){ + Array_create(&ArrayList, sizeof(struct ArrayClass)); +} +/*释放ArrayList占用的资源*/ +void ArrayList_Rel(){ + Array_release(&ArrayList, ArrayList_Rel_); +} +/*主动提前释放资源,对于局部变量,需要在其被编译器释放前主动释放占用资源,防止内存泄漏*/ +void Array_Obj_PreRelease(struct Array *unrel_obj){ + for(struct Array_ *p = ArrayList.front; p != ArrayList.back; p = p->next) + for(struct Array_ *q = ((struct ArrayClass *)p->p)->objects.front; q != ((struct ArrayClass *)p->p)->objects.back; q = q->next) + if(unrel_obj == ((struct ArrayObjects*)q->p)->p_obj){ + Array_release(unrel_obj, ((struct ArrayClass *)p->p)->rel_); + Array_delete_p(&((struct ArrayClass *)p->p)->objects, q, DoNothing); + return ; + } + assert("Array_Obj_PreRelease:NotFound"); +} +/*根据ArrayObj反查ArrayClass*/ +struct ArrayClass *ArrayList_Find_Class_From_Obj(struct Array *a){ + for(struct Array_ *p = ArrayList.front; p != ArrayList.back; p = p->next) + for(struct Array_ *q = ((struct ArrayClass *)p->p)->objects.front; q != ((struct ArrayClass *)p->p)->objects.back; q = q->next) + if(a == ((struct ArrayObjects*)q->p)->p_obj) + return (struct ArrayClass *)p->p; + assert("ArrayList_Find_Class_From_Obj:NotFound"); +} +/*重写简化的Array_delete*/ +void Array_deletepos(struct Array *a, int pos){ + Array_delete_pos(a, pos, ArrayList_Find_Class_From_Obj(a)->rel_); +} +void Array_deletep(struct Array *a, struct Array_ *node){ + Array_delete_p(a, node, ArrayList_Find_Class_From_Obj(a)->rel_); +} +/*MARCO:为Type注册一个新的ArrayClass,并且指定Rel__Func为释放单个元素的方式*/ +#define DECLARE_ARRAY(Type, RelFunc) ArrayClass_Reg(#Type, RelFunc); +/* +MARCO:为内置类型为Type的ArrayClass创建一个新的对象,名称为ArrName +Example: +struct ARRAY(a, struct A); +^^^^^^___________________^ +*/ +#define ARRAY(ArrName, Type) \ + Array ArrName; \ + Array_create(&ArrName, sizeof(Type)); \ + ArrayObj_Reg(#Type, &ArrName) + +#define ARRAY_BIND(ArrName, Type) \ + Array_create(&ArrName, sizeof(Type)); \ + ArrayObj_Reg(#Type, &ArrName); + +/* +Example: + +struct A{ + int a; +}; +void rel_(void*p){} +int main(){ + Array_Class_Init(); + DECLARE_ARRAY(struct A, rel_) + struct ARRAY(a, struct A); + + Array_Obj_PreRelease(&a); + Array_Class_Rel(); +} +*/ +#endif #define ARRAY_INCLUDED \ No newline at end of file