zoukankan      html  css  js  c++  java
  • m2014_c:C 工具库1:list

    转自:http://www.cnblogs.com/sniperHW/archive/2012/04/02/2429607.html

    近来考虑将项目基础框架的开发语言从C++换成C,免不了要编写一大堆的基础工具。

    本篇为第一篇,list,提供的接口和操作方式与std::list相似.后续将会陆续贴出map,vector,memory pool,

    hash_table等工具。

    list.h

    复制代码
    #ifndef _LIST_H
    #define _LIST_H

    struct list;
    struct node;
    struct fix_obj_pool;

    struct list_iter
    {
    struct node **next;
    struct node *n;
    };

    struct fix_obj_pool *list_create_obj_pool(unsigned int val_size,int default_size,int align4);

    struct list* list_create(unsigned int val_size,struct fix_obj_pool*);
    void list_destroy(struct list**);

    struct list_iter list_begin(struct list*);
    struct list_iter list_end(struct list*);
    struct list_iter list_rbegin(struct list*);
    struct list_iter list_rend(struct list*);

    unsigned int list_size(struct list*);
    void list_insert_before(struct list*,struct list_iter,void*);
    void list_insert_after(struct list*,struct list_iter,void*);
    void list_push_back(struct list*,void*);
    void list_push_front(struct list*,void*);
    void list_pop_back(struct list*,void*);
    void list_pop_front(struct list*,void*);
    int list_is_empty(struct list*);

    #ifndef LIST_INSERT_BEFORE
    #define LIST_INSERT_BEFORE(TYPE,LIST,IT,VAL)
    {TYPE val = VAL;list_insert_before(LIST,IT,&val);}
    #endif

    #ifndef LIST_INSERT_AFTER
    #define LIST_INSERT_AFTER(TYPE,LIST,IT,VAL)
    {TYPE val = VAL;list_insert_after(LIST,IT,&val);}
    #endif

    #ifndef LIST_PUSH_BACK
    #define LIST_PUSH_BACK(TYPE,LIST,VAL)
    {TYPE val = VAL;list_push_back(LIST,&val);}
    #endif

    #ifndef LIST_PUSH_FRONT
    #define LIST_PUSH_FRONT(TYPE,LIST,VAL)
    {TYPE val = VAL;list_push_front(LIST,&val);}
    #endif

    #ifndef LIST_POP_FRONT
    #define LIST_POP_FRONT(TYPE,LIST)
    ({ TYPE __result;
    do list_pop_front(LIST,&__result);
    while(0);
    __result;})
    #endif

    #ifndef LIST_POP_BACK
    #define LIST_POP_BACK(TYPE,LIST)
    ({ TYPE __result;
    do list_pop_back(LIST,&__result);
    while(0);
    __result;})
    #endif




    struct list_iter list_find(struct list*,void*);

    #ifndef LIST_FIND
    #define LIST_FIND(TYPE,L,VAL)
    ({ TYPE val = VAL;struct list_iter it;
    do it = list_find(L,&val);
    while(0);
    it;})
    #endif

    int list_remove(struct list*,void*);

    #ifndef LIST_REMOVE
    #define LIST_REMOVE(TYPE,L,VAL)
    ({ TYPE val = VAL;int ret;
    do ret = list_remove(L,&val);
    while(0);
    ret;})
    #endif

    struct list_iter list_erase(struct list*,struct list_iter);

    struct list_iter iter_next(struct list_iter);
    void *iter_get_val(struct list_iter,void*);
    void iter_set_val(struct list_iter,void*);
    int iter_is_equal(struct list_iter a,struct list_iter b);


    #ifndef ITER_GET_VAL
    #define ITER_GET_VAL(TYPE,NODE)
    ({ TYPE __result;
    do iter_get_val(NODE,&__result);
    while(0);
    __result;})
    #endif

    #ifndef ITER_SET_VAL
    #define ITER_SET_VAL(TYPE,NODE,VAL)
    {TYPE val=VAL;iter_set_val(NODE,&val);}
    #endif

    #endif
    复制代码



    list.c

    复制代码
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <assert.h>
    #include "list.h"
    #include "../mem/fix_obj_pool/fix_obj_pool.h"
    struct node
    {
    struct node *next;
    struct node *pre;
    unsigned int val_size;
    union{
    char value[1];
    unsigned int pad;
    };
    };

    struct list
    {
    unsigned int size;
    struct node head;
    struct node end;
    struct fix_obj_pool *obj_pool;//产生node使用的内存池
    };

    struct fix_obj_pool *list_create_obj_pool(unsigned int val_size,int default_size,int align4)
    {
    struct node dummmy;
    unsigned int node_size = sizeof(dummmy) + val_size - sizeof(dummmy.pad);
    struct fix_obj_pool *pool = create_pool(node_size,default_size,align4);
    return pool;
    }

    struct list* list_create(unsigned int val_size,struct fix_obj_pool *obj_pool)
    {
    struct list *_list = malloc(sizeof(*_list));
    if(_list)
    {
    _list->size = 0;
    _list->head.val_size = _list->end.val_size = val_size;
    _list->head.next = &_list->end;
    _list->end.pre = &_list->head;
    _list->head.pre = _list->end.next = 0;
    _list->obj_pool = obj_pool;
    }
    return _list;
    }

    void list_destroy(struct list **_list)
    {
    assert(_list);
    assert(*_list);
    if((*_list)->size > 0)
    {
    struct node *cur = (*_list)->head.next;
    while(cur != &(*_list)->end)
    {
    struct node *next = cur->next;
    if((*_list)->obj_pool)
    pool_dealloc((*_list)->obj_pool,cur);
    else
    free(cur);
    cur = next;
    }
    }
    free(*_list);
    *_list = 0;
    }

    inline struct list_iter list_begin(struct list *_list)
    {
    assert(_list);
    struct list_iter it;
    it.n = _list->head.next;
    it.next = &(it.n->next);
    return it;
    }

    inline struct list_iter list_end(struct list *_list)
    {
    assert(_list);
    struct list_iter it;
    it.n = &_list->end;
    it.next = 0;
    return it;
    }

    inline struct list_iter list_rbegin(struct list *_list)
    {
    assert(_list);
    struct list_iter it;
    it.n = _list->end.pre;
    it.next = &(it.n->pre);
    return it;
    }

    inline struct list_iter list_rend(struct list *_list)
    {
    assert(_list);
    struct list_iter it;
    it.n = &_list->head;
    it.next = 0;
    return it;
    }

    inline unsigned int list_size(struct list *_list)
    {
    assert(_list);
    return _list->size;
    }

    void list_insert_after(struct list *l,struct list_iter it,void *val)
    {
    assert(l);
    struct node *new_node;
    if(l->obj_pool)
    new_node = pool_alloc(l->obj_pool);
    else
    new_node = malloc(sizeof(*new_node) + l->head.val_size - sizeof(new_node->pad));
    if(new_node)
    {
    new_node->val_size = l->head.val_size;
    memcpy(new_node->value,val,l->head.val_size);
    struct node *n = it.n;
    struct node *N = n->next;
    n->next = N->pre = new_node;
    new_node->next = N;
    new_node->pre = n;
    ++l->size;
    }
    }

    void list_insert_before(struct list *l, struct list_iter it,void *val)
    {
    assert(l);
    struct node *new_node;
    if(l->obj_pool)
    new_node = pool_alloc(l->obj_pool);
    else
    new_node = malloc(sizeof(*new_node) + l->head.val_size - sizeof(new_node->pad));
    if(new_node)
    {
    new_node->val_size = l->head.val_size;
    memcpy(new_node->value,val,l->head.val_size);
    struct node *n = it.n;
    struct node *P = n->pre;
    n->pre = P->next = new_node;
    new_node->next = n;
    new_node->pre = P;
    ++l->size;
    }
    }

    void list_push_back(struct list *_list,void *val)
    {
    assert(_list);
    struct list_iter end = list_end(_list);
    list_insert_before(_list,end,val);
    }

    void list_push_front(struct list *_list,void *val)
    {
    assert(_list);
    struct list_iter begin = list_begin(_list);
    list_insert_before(_list,begin,val);
    }

    void list_pop_back(struct list *_list,void *out)
    {
    assert(_list);
    if(_list->size > 0)
    {
    struct node *_node = _list->end.pre;
    memcpy(out,_node->value,_node->val_size);
    struct node *pre = _node->pre;
    struct node *next = _node->next;
    pre->next = next;
    next->pre = pre;
    if(_list->obj_pool)
    pool_dealloc(_list->obj_pool,_node);
    else
    free(_node);
    //free(_node);
    --_list->size;
    }
    }

    void list_pop_front(struct list *_list,void *out)
    {
    assert(_list);
    if(_list->size > 0)
    {
    struct node *_node = _list->head.next;
    memcpy(out,_node->value,_node->val_size);
    struct node *pre = _node->pre;
    struct node *next = _node->next;
    pre->next = next;
    next->pre = pre;
    if(_list->obj_pool)
    pool_dealloc(_list->obj_pool,_node);
    else
    free(_node);
    --_list->size;
    }
    }

    inline int list_is_empty(struct list *_list)
    {
    assert(_list);
    return _list->size == 0;
    }

    struct list_iter list_find(struct list *l,void *v)
    {
    assert(l);
    struct list_iter it;
    it.n = 0;
    struct node *cur = l->head.next;
    while(cur != &l->end)
    {

    if(memcmp(cur->value,v,l->head.val_size) == 0)
    //找到目标
    break;
    cur = cur->next;
    }

    if(cur != &l->end)
    {
    it.n = cur;
    it.next = &cur->next;
    }
    else
    {
    it.n = &l->end;
    it.next = 0;
    }
    return it;
    }

    int list_remove(struct list *l,void *v)
    {
    assert(l);
    struct list_iter it = list_find(l,v);
    if(it.n == 0)
    return 0;
    list_erase(l,it);
    return 1;
    }

    struct list_iter list_erase(struct list *l,struct list_iter it)
    {
    assert(l);
    struct list_iter it_next = iter_next(it);
    struct node *n = it.n;
    struct node *P = n->pre;
    struct node *N = n->next;
    P->next = N;
    N->pre = P;
    if(l->obj_pool)
    pool_dealloc(l->obj_pool,n);
    else
    free(n);
    --l->size;
    return it_next;
    }

    inline struct list_iter iter_next(struct list_iter it)
    {
    if(it.next == 0)
    return it;
    struct list_iter it_next;
    it_next.n = (*it.next);
    if(it.next == &it.n->next)
    it_next.next = &(it_next.n->next);
    else if(it.next == &it.n->pre)
    it_next.next = &(it_next.n->pre);
    else
    {
    assert(0);
    }
    return it_next;
    }

    inline int iter_is_equal(struct list_iter a,struct list_iter b)
    {
    return a.n == b.n;
    }

    void *iter_get_val(struct list_iter iter,void *v)
    {
    struct node *n = iter.n;
    memcpy(v,n->value,n->val_size);
    }

    void iter_set_val(struct list_iter iter,void *v)
    {
    struct node *n = iter.n;
    memcpy(n->value,v,n->val_size);
    }
    复制代码

    test.c

    复制代码
    #include <stdio.h>
    #include "list.h"
    #include "../mem/fix_obj_pool/fix_obj_pool.h"

    int main()
    {
    struct fix_obj_pool *obj_pool = list_create_obj_pool(sizeof(int),4096,0);
    struct list *l = list_create(sizeof(int),obj_pool);
    LIST_PUSH_BACK(int,l,1);
    LIST_PUSH_BACK(int,l,2);
    LIST_PUSH_BACK(int,l,3);
    LIST_PUSH_BACK(int,l,4);
    struct list_iter it = LIST_FIND(int,l,2);
    LIST_INSERT_BEFORE(int,l,it,5);
    LIST_INSERT_AFTER(int,l,it,6);
    it = list_begin(l);
    struct list_iter end = list_end(l);

    for( ; !iter_is_equal(it,end); )
    {
    if(ITER_GET_VAL(int,it) == 3)
    it = list_erase(l,it);
    else
    it = iter_next(it);
    }

    it = list_begin(l);
    while(!iter_is_equal(it,end))
    {
    printf("%d ",ITER_GET_VAL(int,it));
    it = iter_next(it);
    }

    printf("free size:%d ",get_free_size(obj_pool));

    list_destroy(&l);
    printf("free size:%d ",get_free_size(obj_pool));
    destroy_pool(&obj_pool);

    return 0;
    }
  • 相关阅读:
    postgresql 在linux下导出数据
    第一次linux下安装nginx记录
    第一次搭建redis集群
    手动mvn install指令向maven本地仓库安装jar包
    windows10下Kafka环境搭建
    在win10环境下搭建 solr 开发环境
    git 常用命令
    生成文件夹的树结构信息
    List集合和JSON互转工具类
    Cmd命令 查看端口被占用
  • 原文地址:https://www.cnblogs.com/pricks/p/3811194.html
Copyright © 2011-2022 走看看