64,652
社区成员
发帖
与我相关
我的任务
分享
/*******************************************************************************
文件名 : zlist.h
相关文件 :
文件实现功能 : 使用模板类封装linux内核链表
作者 : <zison sun>
版本 : 1.0
--------------------------------------------------------------------------------
多线程安全性 :
异常时安全性 :
--------------------------------------------------------------------------------
备注 :
--------------------------------------------------------------------------------
修改记录 :
日 期 版本 修改人 修改内容
2011/11/01 1.0 <孙志新> 创建
*******************************************************************************/
#ifndef ZLIST_H
#define ZLIST_H
#include "list.h"
class ZListNode
{
public:
struct list_head list;
};
template <typename T>
class Zlist
{
public:
Zlist(void)
{
m_iElmCount=0;
INIT_LIST_HEAD(&m_ListHead);
}
// Zlist<T> & oprator=(const Zlist<T> & L );
~Zlist(void)
{
Release();
}
//在表头增加
void Add(T * p)
{
m_iElmCount++;
list_add(&p->list,&m_ListHead);
}
//在表尾增加
void AddTail(T * p)
{
m_iElmCount++;
list_add_tail(&p->list,&m_ListHead);
}
//删除节点
void Delete(T * p)
{
if(m_iElmCount <= 0)
return ;
list_del(&p->list);
m_iElmCount--;
}
bool IsMember(T * p)
{
int index = GetIndex(p);
if (-1 == index)
{
return false;
}
else
{
return true;
}
}
void Delete(int index)
{
T * tmp;
if(index >= m_iElmCount)
return ;
tmp = GetAt(index);
list_del(&tmp->list);
m_iElmCount--;
}
//获取序号为index的节点
T * GetAt(int index)
{
T * tmp;
int i=0;
struct list_head* pos, *q;
if(index >= m_iElmCount)
{
return NULL;
}
list_for_each_safe(pos,q,&m_ListHead)
{
tmp= list_entry(pos);
if(index == i)
{
return tmp;
}
else
{
i++;
}
}
return NULL;
}
int GetIndex(T * p)
{
int i=0;
struct list_head* pos, *q;
list_for_each_safe(pos,q,&m_ListHead)
{
if( p == list_entry(pos) )
{
return i;
}
else
{
i++;
}
}
return -1;
}
//获取元素个数
inline int GetElmNum()
{
return m_iElmCount;
}
//是否为空
bool IsEmpty()
{
return list_empty_careful(&m_ListHead);
}
void Release()
{
struct list_head* pos, *q;
T * tmp;
list_for_each_safe(pos,q,&m_ListHead)
{
tmp= list_entry(pos);
list_del(pos);
delete tmp;
tmp = NULL;
}
m_iElmCount = 0;
}//释放链表
private:
struct list_head m_ListHead ;
int m_iElmCount;
T * list_entry(void * ptr)
{
T * tmp;
struct list_head *__mptr = (struct list_head *)(ptr);
tmp = (T *)( (char *) __mptr - offsetof(TestData,list) );
return tmp;
}
};
#endif
/*******************************************************************************
文件名 : Tmeplate_Test.h
相关文件 :
文件实现功能 : 介绍如何使用Linux内核链表模板类ZList
作者 : <zison sun>
版本 : 1.0
--------------------------------------------------------------------------------
多线程安全性 :
异常时安全性 :
--------------------------------------------------------------------------------
备注 :
--------------------------------------------------------------------------------
修改记录 :
日 期 版本 修改人 修改内容
2011/11/01 1.0 <孙志新> 创建
*******************************************************************************/
#include "stdafx.h"
#include "zlist.h"
//任何使用ZList的类都需要继承自ZListNode
class TestData :public ZListNode
{
public:
int index;
char szText[5];
} ;
int _tmain(int argc, _TCHAR* argv[])
{
Zlist<TestData> list; //申明链表
TestData * oneData = NULL;
//添加元素
for(int i =0;i <10;i++)
{
TestData * pTD = new TestData;
pTD->index = i;
sprintf(pTD->szText,"%d",i);
//list.Add(pTD); //加入到链表头,使用ListAddTail则添加到尾部
list.AddTail(pTD); //加入到链表尾部
//记录一个元素用来用来演示下面的删除等操作。
if(6 == i)
{
oneData = pTD;
}
}
//获取成员序号,若添加方式是ListAdd,所以对应关系为
//0-9 1-8 2-7 3-6 ,,index应该为3
//若添加方式为ListAddTail,则序号为6
int index = list.GetIndex(oneData);
//查找是否存在某个元素
bool isIn = list.IsMember(oneData);
//遍历列表
TestData * tmp;
for(int j=0;j<list.GetElmNum();j++)
{
tmp = list.GetAt(j);
}
//两种删除方式
list.Delete(0);
list.Delete(oneData);
//查找是否存在某个元素,此元素目前已不在list中
isIn = list.IsMember(oneData);
for(int j=0;j<list.GetElmNum();j++)
{
tmp = list.GetAt(j);
}
list.Release();
return 0;
}
/*******************************************************************************
文件名 : list.h
相关文件 :
文件实现功能 : linux内核链表的定义
作者 : <linux>
版本 : 1.0
--------------------------------------------------------------------------------
多线程安全性 :
异常时安全性 :
--------------------------------------------------------------------------------
备注 :
--------------------------------------------------------------------------------
修改记录 :
日 期 版本 修改人 修改内容
2011/11/01 1.0 <孙志新> 修改
*******************************************************************************/
#ifndef _LINUX_LIST_H
#define _LINUX_LIST_H
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
/*
#define container_of(ptr, type, member) ( { \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) ); } )
*/
static inline void prefetch(const void *x) {;}
static inline void prefetchw(const void *x) {;}
#define LIST_POISON1 ((void *) 0x00100100)
#define LIST_POISON2 ((void *) 0x00200200)
struct list_head {
struct list_head *next, *prev;
};
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
#define INIT_LIST_HEAD(ptr) do { \
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
} while (0)
/*
* Insert a new entry between two known consecutive entries.
*
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static inline void __list_add(struct list_head *newelm,
struct list_head *prev,
struct list_head *next)
{
next->prev = newelm;
newelm->next = next;
newelm->prev = prev;
prev->next = newelm;
}
/**
* list_add - add a new entry
* @new: new entry to be added
* @head: list head to add it after
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
static inline void list_add(struct list_head *newelm, struct list_head *head)
{
__list_add(newelm, head, head->next);
}
/**
* list_add_tail - add a new entry
* @new: new entry to be added
* @head: list head to add it before
*
* Insert a new entry before the specified head.
* This is useful for implementing queues.
*/
static inline void list_add_tail(struct list_head *newelm, struct list_head *head)
{
__list_add(newelm, head->prev, head);
}
static inline void __list_del(struct list_head * prev, struct list_head * next)
{
next->prev = prev;
prev->next = next;
}
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = (struct list_head *)LIST_POISON1;
entry->prev = (struct list_head *)LIST_POISON2;
}
static inline void list_del_init(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
INIT_LIST_HEAD(entry);
}
static inline void list_move(struct list_head *list, struct list_head *head)
{
__list_del(list->prev, list->next);
list_add(list, head);
}
static inline void list_move_tail(struct list_head *list,
struct list_head *head)
{
__list_del(list->prev, list->next);
list_add_tail(list, head);
}
static inline int list_empty(const struct list_head *head)
{
return head->next == head;
}
static inline int list_empty_careful(const struct list_head *head)
{
struct list_head *next = head->next;
return (next == head) && (next == head->prev);
}
static inline void __list_splice(struct list_head *list,
struct list_head *head)
{
struct list_head *first = list->next;
struct list_head *last = list->prev;
struct list_head *at = head->next;
first->prev = head;
head->next = first;
last->next = at;
at->prev = last;
}
/**
* list_splice - join two lists
* @list: the new list to add.
* @head: the place to add it in the first list.
*/
static inline void list_splice(struct list_head *list, struct list_head *head)
{
if (!list_empty(list))
__list_splice(list, head);
}
/**
* list_splice_init - join two lists and reinitialise the emptied list.
* @list: the new list to add.
* @head: the place to add it in the first list.
*
* The list at @list is reinitialised
*/
static inline void list_splice_init(struct list_head *list,
struct list_head *head)
{
if (!list_empty(list)) {
__list_splice(list, head);
INIT_LIST_HEAD(list);
}
}
#if 0
#define list_entry(ptr, type, member) container_of(ptr, type, member)
#endif
#define list_for_each(pos, head) \
for (pos = (head)->next; prefetch(pos->next), pos != (head); \
pos = pos->next)
#define __list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
#define list_for_each_prev(pos, head) \
for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \
pos = pos->prev)
#define list_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)
#define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member); \
prefetch(pos->member.next), &pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
#define list_for_each_entry_reverse(pos, head, member) \
for (pos = list_entry((head)->prev, typeof(*pos), member); \
prefetch(pos->member.prev), &pos->member != (head); \
pos = list_entry(pos->member.prev, typeof(*pos), member))
#define list_prepare_entry(pos, head, member) \
((pos) ? : list_entry(head, typeof(*pos), member))
#define list_for_each_entry_continue(pos, head, member) \
for (pos = list_entry(pos->member.next, typeof(*pos), member); \
prefetch(pos->member.next), &pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
#define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member), \
n = list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, typeof(*n), member))
#endif
/*******************************************************************************
文件名 : Tmeplate_Test.h
相关文件 :
文件实现功能 : 介绍如何使用Linux内核链表模板类ZList
作者 : <zison sun>
版本 : 1.0
--------------------------------------------------------------------------------
多线程安全性 :
异常时安全性 :
--------------------------------------------------------------------------------
备注 :
--------------------------------------------------------------------------------
修改记录 :
日 期 版本 修改人 修改内容
2011/11/01 1.1 <孙志新> 创建
*******************************************************************************/
#include "stdafx.h"
#include "zlist.h"
//任何使用ZList的类都需要继承自ZListNode
class TestData :public ZListNode
{
public:
int index;
char szText[5];
} ;
int _tmain(int argc, _TCHAR* argv[])
{
Zlist<TestData> list; //申明链表
TestData * oneData = NULL;
//添加元素
for(int i =0;i <10;i++)
{
TestData * pTD = new TestData;
pTD->index = i;
sprintf(pTD->szText,"%d",i);
//list.push_front(pTD); //加入到链表头,使用ListAddTail则添加到尾部
list.push_back(*pTD); //加入到链表尾部
//记录一个元素用来用来演示下面的删除等操作。
if(6 == i)
{
oneData = pTD;
}
}
//获取成员序号,若添加方式是ListAdd,所以对应关系为
//0-9 1-8 2-7 3-6 ,,index应该为3
//若添加方式为ListAddTail,则序号为6,返回-1表示没有此元素
//int index = list.GetIndex(oneData);
//查找是否存在某个元素
bool isIn = list.ismember(*oneData);
//遍历列表
TestData * tmp;
for(int j=0;j<list.size();j++)
{
tmp = list.get_at(j);
}
//两种删除方式
list.erase(0);
list.erase(*oneData);
//查找是否存在某个元素,此元素目前已不在list中
isIn = list.ismember(*oneData);
for(int j=0;j<list.size();j++)
{
tmp = list.get_at(j);
}
TestData td_f = list.front();
TestData td_l = list.back();
TestData * pTD_s = new TestData;
pTD_s->index = 6;
sprintf(pTD_s->szText,"%d",6);
list.insert(100,*pTD_s);
for(int j=0;j<list.size();j++)
{
tmp = list.get_at(j);
}
list.clear();
return 0;
}
/*******************************************************************************
文件名 : zlist.h
相关文件 :
文件实现功能 : 使用模板类封装linux内核链表
作者 : <zison sun>
版本 : 1.0
--------------------------------------------------------------------------------
多线程安全性 :
异常时安全性 :
--------------------------------------------------------------------------------
备注 :
--------------------------------------------------------------------------------
修改记录 :
日 期 版本 修改人 修改内容
2011/11/01 1.1 <孙志新> 创建
*******************************************************************************/
#ifndef ZLIST_H
#define ZLIST_H
#include "list.h"
class ZListNode
{
public:
struct list_head list;
};
template <typename T>
class Zlist
{
public:
/************************************************************************
* 名称: Zlist
* 功能: 构造函数
* 输入:
* 返回:
************************************************************************/
Zlist(void)
{
m_iElmCount=0;
INIT_LIST_HEAD(&m_ListHead);
}
/************************************************************************
* 名称: ~Zlist
* 功能: 析构函数
* 输入:
* 返回:
************************************************************************/
~Zlist(void)
{
clear();
}
public:
/************************************************************************
* 名称: push_front
* 功能: 在链表头部插入元素
* 输入: T * ,元素地址
* 返回: void
************************************************************************/
void push_front(T & e)
{
m_iElmCount++;
list_add(&e.list,&m_ListHead);
}
/************************************************************************
* 名称: push_back
* 功能: 在链表尾部插入元素
* 输入: T & ,要增加的元素的引用
* 返回: void
************************************************************************/
void push_back(T & e)
{
m_iElmCount++;
list_add_tail(&e.list,&m_ListHead);
}
/************************************************************************
* 名称: pop_front
* 功能: 删除链表第一个元素
* 输入: 无
* 返回: void
************************************************************************/
void pop_front()
{
remove(0);
}
/************************************************************************
* 名称: pop_back
* 功能: 删除链表最后一个元素
* 输入: 无
* 返回: void
************************************************************************/
void pop_back()
{
remove(m_iElmCount -1);
}
/************************************************************************
* 名称: back
* 功能: 返回链表最后一个元素的引用
* 输入: 无
* 返回: T &
************************************************************************/
T & front()
{
T * first = get_at(0);
return *first;
}
/************************************************************************
* 名称: back
* 功能: 返回链表最后一个元素的引用
* 输入: 无
* 返回: T &
************************************************************************/
T & back()
{
T * last = get_at(m_iElmCount -1);
return *last;
}
/************************************************************************
* 名称: insert
* 功能: 在链表指定位置插入一个元素
* 输入: int,插入的位置,如果loc 大于等于当前元素个数,此时相当于调用push_back
* 当loc <=0 ,相当于调用push_front
* 输入: const T & ,要插入的元素
* 返回: T &
************************************************************************/
void insert(int loc,T & e)
{
T * tmp;
int i=0;
struct list_head* pos, *q;
if(loc <= 0)
{
push_front(e);
return ;
}
if(loc >= m_iElmCount)
{
push_back(e);
return ;
}
list_for_each_safe(pos,q,&m_ListHead)
{
if(loc == i)
{
tmp= list_entry(pos);
list_add(&e.list,pos->prev);
return ;
}
else
{
i++;
}
}
}
/************************************************************************
* 名称: remove
* 功能: 在链表删除指定元素,元素内存由用户自己释放
* 输入: T & ,要删除的元素的引用
* 返回: void
************************************************************************/
void erase(T & e)
{
if(m_iElmCount <= 0)
return ;
list_del(&e.list);
// delete &e;
m_iElmCount--;
}
/************************************************************************
* 名称: remove
* 功能: 在链表删除指定元素
* 输入: int ,要删除的元素在链表中得序号
* 返回: void
************************************************************************/
void erase(int index)
{
T * tmp;
if(index >= m_iElmCount)
return ;
tmp = get_at(index);
list_del(&tmp->list);
//delete tmp;
m_iElmCount--;
}
/************************************************************************
* 名称: ismember
* 功能: 判断元素是否是存在于list
* 输入: const T & ,要进行判断的元素
* 返回: bool
************************************************************************/
bool ismember(const T & e)
{
int index = index_of(&e);
if (-1 == index)
{
return false;
}
else
{
return true;
}
}
/************************************************************************
* 名称: size
* 功能: 返回当前链表中元素的个数
* 输入: 无
* 返回: int ,元素个数
************************************************************************/
inline int size()
{
return m_iElmCount;
}
/************************************************************************
* 名称: empty
* 功能: 判断当前链表是否为空
* 输入: 无
* 返回: bool
************************************************************************/
bool empty()
{
return list_empty_careful(&m_ListHead);
}
/************************************************************************
* 名称: clear
* 功能: 删除链表中所有的元素
* 输入: 无
* 返回: void
************************************************************************/
void clear()
{
struct list_head* pos, *q;
T * tmp;
list_for_each_safe(pos,q,&m_ListHead)
{
tmp= list_entry(pos);
list_del(pos);
delete tmp;
tmp = NULL;
}
m_iElmCount = 0;
}
/************************************************************************
* 名称: get_at
* 功能: 获取链表中指定序号的元素
* 输入: 无
* 返回: T &
************************************************************************/
T * get_at(int index)
{
T * tmp;
int i=0;
struct list_head* pos, *q;
if(index >= m_iElmCount)
{
return NULL;
}
list_for_each_safe(pos,q,&m_ListHead)
{
tmp= list_entry(pos);
if(index == i)
{
return tmp;
}
else
{
i++;
}
}
return NULL;
}
/************************************************************************
* 名称: index_of
* 功能: 获取链表中指定元素的序号
* 输入: const T * ,元素地址
* 返回: int ,序号,返回-1表示list中不存在此元素
************************************************************************/
int index_of(const T * p)
{
int i=0;
struct list_head* pos, *q;
list_for_each_safe(pos,q,&m_ListHead)
{
if( p == list_entry(pos) )
{
return i;
}
else
{
i++;
}
}
return -1;
}
private:
T * list_entry(void * ptr)
{
T * tmp;
struct list_head *__mptr = (struct list_head *)(ptr);
tmp = (T *)( (char *) __mptr - offsetof(TestData,list) );
return tmp;
}
private:
struct list_head m_ListHead;
int m_iElmCount;
};
#endif