}
return list;
}
static int _length_of(struct single_list * list)
{
return list->size;
}
static void _clear_list(struct single_list * list)
{
struct slist_node * p = list->head;
struct slist_node * p2;
while(p)
{
p2 = p;
p = p->next;
if(list->free_node) list->free_node(p2);
else free(p2);
}
list->head = 0;
list->tail = 0;
list->size = 0;
}
static void _delete_single_list(struct single_list *list)
{
list->clear(list);
free(list);
}
struct single_list * new_single_list(list_op_free_node op_free, list_op_key_hit_test op_cmp)
{
struct single_list *list = (struct single_list *)malloc(sizeof(struct single_list));
list->head = 0;
list->tail = 0;
list->size = 0;
list->free_node = op_free;
list->key_hit_test = op_cmp;
list->add = _add_node;
list->insert = _insert_node;
list->replace = _replace;
list->find_by_key = _find_by_key;
list->first = _first_of;
list->last = _last_of;
list->at = _node_at;
list->take_at = _take_at;
list->take_by_key = _take_by_key;
list->remove = _remove_node;
list->remove_at = _remove_at;
list->remove_by_key = _remove_by_key;
list->length = _length_of;
list->clear = _clear_list;
list->deletor = _delete_single_list;
return list;
}
上面的代码就不一一细说了,下面是测试代码:
/* call 1 or N arguments function of struct */
#define ST_CALL(THIS,func,args...) ((THIS)->func(THIS,args))
/* call none-arguments function of struct */
#define ST_CALL_0(THIS,func) ((THIS)->func(THIS))
struct int_node {
struct slist_node node;
int id;
};
struct string_node {
struct slist_node node;
char name[16];
};
static int int_free_flag = 0;
static void _int_child_free(struct slist_node *node)
{
free(node);
if(!int_free_flag)
{
int_free_flag = 1;
printf("int node free\n");
}
}
static int _int_slist_hittest(struct slist_node * node, void *key)
{
struct int_node * inode = NODE_T(node, struct int_node);
int ikey = (int)key;
return (inode->id == ikey 0 : 1);
}
static int string_free_flag = 0;
static void _string_child_free(struct slist_node *node)
{
free(node);
if(!string_free_flag)
{
string_free_flag = 1;
printf("string node free\n");
}
}
static int _string_slist_hittest(struct slist_node * node, void *key)
{
struct string_node * sn = (struct string_node*)node;
return strcmp(sn->name, (char*)key);
}
void int_slist_test()
{
struct single_list * list = new_single_list(_int_child_free, _int_slist_hittest);
struct int_node * node = 0;
struct slist_node * bn = 0;
int i = 0;
printf("create list && nodes:\n");
for(; i < 100; i++)
{
node = (struct int_node*)malloc(sizeof(struct int_node));
node->id = i;
if(i%10)
{
list->add(list, node);
}
else
{
list->insert(list, 1, node);
}
}
printf("create 100 nodes end\n----\n");
printf("first is : %d, last is: %d\n----\n",
NODE_T( ST_CALL_0(list, first), struct int_node )->id,
NODE_T( ST_CALL_0(list, last ), struct int_node )->id);
assert(list->size == 100);
printf("list traverse:\n");
for(i = 0; i < 100; i++)
{
if(i%10 == 0) printf("\n");
bn = list->at(list, i);
node = NODE_T(bn, struct int_node);
printf(" %d", node->id);
}
printf("\n-----\n");
printf("find by key test, key=42:\n");
bn = list->find_by_key(list, (void*)42);
assert(bn != 0);
node = NODE_T(bn, struct int_node);
printf("find node(key=42), %d\n------\n", node->id);
printf("remove node test, remove the 10th node:\n");
bn = list->at(list, 10);
node = NODE_T(bn, struct int_node);
printf(" node 10 is: %d\n", node->id);
printf(" now remove node 10\n");
list->remove_at(lis