//
// coreList.h
// hehe
//
// Created by yin on 16/8/24.
// Copyright © 2016年 yin. All rights reserved.
//
#ifndef coreList_h
#define coreList_h
#define LIST_POISON1 ((struct list_head *) 0x0)
#define LIST_POISON2 ((struct list_head *) 0x0)
struct list_head {
struct list_head *next, *prev;/* next後指針,prev前指針 */
};
/** \brief 鏈表頭初始化 */
#define LIST_HEAD_INIT(name) { &(name), &(name) }
/** \brief 鏈表頭初始化 */
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
/** \brief 初始化鏈表頭
\param[in] ptr 鏈表結構指針
\return 無
*/
#define INIT_LIST_HEAD(ptr) { \
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
}
static inline void __list_add(struct list_head *new_head,
struct list_head *prev,
struct list_head *next)
{
/* 添加到鏈表 */
next->prev = new_head;
new_head->next = next;
new_head->prev = prev;
prev->next = new_head;
}
/** \brief 添加新的鏈表元素到鏈表頭
\param[in] new_head 待添加鏈表結構指針
\param[in] head 鏈表頭結構指針
\\return 無
*/
static inline void list_add(struct list_head *new_head, struct list_head *head)
{
/* 添加到鏈表頭 */
__list_add(new_head, head, head->next);
}
/** \brief 添加新的鏈表元素到鏈表尾
\param[in] new_head 待添加鏈表結構指針
\param[in] head 鏈表頭結構指針
\\return 無
*/
static inline void list_add_tail(struct list_head *new_head, struct list_head *head)
{
/* 添加到鏈表尾 */
__list_add(new_head, head->prev, head);
}
static inline void __list_del(struct list_head * prev, struct list_head * next)
{
/* 從鏈表刪除 */
next->prev = prev;
prev->next = next;
}
/** \brief 從鏈表刪除節點
\param[in] entry 待刪除鏈表結構指針
\\return 無
*/
static inline void list_del(struct list_head *entry)
{
/* 刪除鏈表記錄 */
__list_del(entry->prev, entry->next);
entry->next = LIST_POISON1;
entry->prev = LIST_POISON2;
}
/** \brief 判斷鏈表是否為空
\param[in] head 鏈表頭指針
\return 無
*/
static inline int list_empty(struct list_head *head)
{
/* 判斷鏈表是否為空 */
return head->next == head;
}
/** \brief 刪除指定鏈表元素並初始化
\param[in] entry 待刪除並初始化的鏈表元素
\\return 無
*/
static inline void list_del_init(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
INIT_LIST_HEAD(entry);
}
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;
}
/** \brief 合並鏈表
\param[in] list 待合並的新鏈表
\param[in] head 合並的舊鏈表
\\return 無
*/
static inline void list_splice(struct list_head *list, struct list_head *head)
{
if (!list_empty(list))
__list_splice(list, head);
}
/** \brief 合並鏈表並初始化新鏈表頭
\param[in] list 待添加的新鏈表頭
\param[in] head 合並新鏈表的位置
\\return 無
*/
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);
}
}
/** \brief 轉移鏈表元素到新鏈表頭
\param[in] list 舊鏈表的鏈表頭
\param[in] head 新鏈表的鏈表頭
\\return 無
*/
static inline void list_move(struct list_head *list, struct list_head *head)
{
__list_del(list->prev, list->next);
list_add(list, head);
}
/** \brief 轉移鏈表元素到新鏈表尾
\param[in] list 舊鏈表的鏈表頭
\param[in] head 新鏈表的鏈表頭
\\return 無
*/
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);
}
/** \brief 通過鏈表地址獲得結構體指針
\param[in] ptr 鏈表結構指針
\param[in] type 結構體類型
\param[in] member 結構體中鏈表所表示的字段
\return 無
*/
#define list_entry(ptr, type, member) ((type *)(void *)((char *)(ptr) - (char*)(void*)(&((type*)0)->member)))
/** \brief 向後遍歷鏈表
\attention 遍歷過程中不允許刪除鏈表元素
\param[in] pos 當前所指向的鏈表節點
\param[in] head 鏈表頭指針
\return 無
*/
#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); \
pos = pos->next)
/** \brief 從pos的下一個節點, 向後遍歷鏈表
\attention 遍歷過程中不允許刪除鏈表元素
\param[in] pos 指定的鏈表節點
\param[in] head 鏈表頭指針
\return 無
*/
#define list_for_each_continue(pos, head)\
for ((pos) = (pos)->next; (pos) != (head); (pos) = (pos)->next)
/** \brief 向後遍歷鏈表
\attention 用戶必須自行在遍歷過程中刪除鏈表元素,否則將導致死循環
\param[in] pos 當前所指向的鏈表節點
\param[in] head 鏈表頭指針
\return 無
*/
#define list_for_del_each(pos, head) \
for (pos = (head)->next; pos != (head); \
pos = (head)->next)
/** \brief 向後遍歷鏈表
\attention 遍歷過程中支持用戶自行刪除鏈表元素,用戶可自行決定是否刪除
\param[in] pos 當前所指向的鏈表節點
\param[in] n 循環臨時值
\param[in] head 鏈表頭指針
\return 無
*/
#define list_for_each_safe(pos, n, head) for (pos = (head)->next, n = pos->next; pos != (head); pos = n, n = pos->next)
/** \brief 從pos的下一個節點開始, 向後遍歷鏈表
\attention 遍歷過程中支持用戶自行刪除鏈表元素,用戶可自行決定是否刪除
\param[in] pos 指定的鏈表節點
\param[in] n 循環臨時值
\param[in] head 鏈表頭指針
\return 無
*/
#define list_for_each_safe_continue(pos, n, head)\
for ((pos) = (pos)->next, n = (pos)->next; pos != (head); \
(pos) = n, n = (pos)->next)
#define list_for_each_prev_safe(pos, p, head)\
for(pos = (head)->prev, p = pos->prev; pos != (head);\
pos = p, p = pos->prev)
/** \brief 向前遍歷鏈表
\attention 遍歷過程中不允許刪除鏈表元素
\param[in] pos 當前所指向的鏈表節點
\param[in] head 鏈表頭指針
\return 無
*/
#define list_for_each_prev(pos, head) \
for (pos = (head)->prev; pos != (head); pos = pos->prev)
/** \brief 向後遍歷鏈表,並獲得鏈表所在結構體指針
\attention 遍歷過程中不允許刪除鏈表元素
\param[in] pos 鏈表所在結構體指針
\param[in] type 結構體類型
\param[in] head 鏈表頭指針
\param[in] member 結構體成員名
\return 無
*/
#define list_for_each_entry(pos, head, member,type) \
for (pos = list_entry((head)->next, type, member); \
&pos->member != (head); \
pos = list_entry(pos->member.next, type, member))
#define INIT_LIST_NODE(ptr) { (ptr)->next = LIST_POISON1; (ptr)->prev = LIST_POISON2; }
#define IS_LIST_NODE_INIT(ptr) ((LIST_POISON1 == (ptr)->next) && (LIST_POISON2 == (ptr)->prev))
#endif /* coreList_h */
實例:
#include
#include
#include "coreList.h"
typedef struct tagCAR_S
{
struct list_head node;
int id;
}CAR_S;
typedef struct tagPOLICE_S
{
int serNum;
struct list_head carHead;
int carNum;
}POLICE_S;
int main(void)
{
struct list_head *cur = NULL;
POLICE_S *p = NULL;
CAR_S *car = NULL;
p = (POLICE_S *)malloc(sizeof(POLICE_S));
if (NULL == p)
{
return -1;
}
INIT_LIST_HEAD(&p->carHead);
for (int i = 0; i < 10; ++i)
{
car = (CAR_S*)malloc(sizeof(CAR_S));
if (NULL == car)
{
return -1;
}
car->id = i;
list_add_tail(&car->node, &p->carHead);
p->carNum++;
}
list_for_each(cur, &p->carHead)
{
car = list_entry(cur, CAR_S, node);
printf("id = %d\n", car->id);
}
return 0;
}