204 lines
5.2 KiB
C
204 lines
5.2 KiB
C
/**
|
||
* @file list.h
|
||
* @brief Linux 内核风格侵入式双向循环链表(纯头文件,C/C++ 兼容)
|
||
* @details 将 struct list_head 嵌入宿主结构体,通过 list_entry 取回宿主指针。
|
||
* 所有操作 O(1),遍历 O(n)。
|
||
* C++ 兼容:变量名不使用 new/class/typeof 等关键字。
|
||
*/
|
||
|
||
#ifndef _LIST_H_
|
||
#define _LIST_H_
|
||
|
||
#include <stddef.h>
|
||
|
||
#ifdef __cplusplus
|
||
extern "C"
|
||
{
|
||
#endif
|
||
|
||
/* ---- 链表节点 ---- */
|
||
struct list_head
|
||
{
|
||
struct list_head *next;
|
||
struct list_head *prev;
|
||
};
|
||
|
||
/* ---- 初始化 ---- */
|
||
#define LIST_HEAD_INIT(n) { &(n), &(n) }
|
||
#define LIST_HEAD(n) struct list_head n = LIST_HEAD_INIT(n)
|
||
|
||
/**
|
||
* @brief 运行时初始化链表头
|
||
*/
|
||
static inline void INIT_LIST_HEAD(struct list_head *h)
|
||
{
|
||
h->next = h;
|
||
h->prev = h;
|
||
}
|
||
|
||
/* ---- 内部辅助:在 prev 和 next 之间插入 node ---- */
|
||
static inline void __list_add(struct list_head *node,
|
||
struct list_head *prev,
|
||
struct list_head *next)
|
||
{
|
||
next->prev = node;
|
||
node->next = next;
|
||
node->prev = prev;
|
||
prev->next = node;
|
||
}
|
||
|
||
/* ---- 内部辅助:移除 prev 和 next 之间的节点 ---- */
|
||
static inline void __list_del(struct list_head *prev,
|
||
struct list_head *next)
|
||
{
|
||
next->prev = prev;
|
||
prev->next = next;
|
||
}
|
||
|
||
/* ---- 添加操作 ---- */
|
||
|
||
/** 头插法:插入到 head 之后(作为第一个元素) */
|
||
static inline void list_add(struct list_head *node, struct list_head *head)
|
||
{
|
||
__list_add(node, head, head->next);
|
||
}
|
||
|
||
/** 尾插法:插入到 head 之前(作为最后一个元素) */
|
||
static inline void list_add_tail(struct list_head *node, struct list_head *head)
|
||
{
|
||
__list_add(node, head->prev, head);
|
||
}
|
||
|
||
/* ---- 删除操作 ---- */
|
||
|
||
/** 从链表移除节点(不释放内存) */
|
||
static inline void list_del(struct list_head *e)
|
||
{
|
||
__list_del(e->prev, e->next);
|
||
}
|
||
|
||
/** 移除并重新初始化节点(安全删除,防止悬空指针) */
|
||
static inline void list_del_init(struct list_head *e)
|
||
{
|
||
__list_del(e->prev, e->next);
|
||
INIT_LIST_HEAD(e);
|
||
}
|
||
|
||
/* ---- 移动操作 ---- */
|
||
|
||
/** 将节点移动到新链表头部 */
|
||
static inline void list_move(struct list_head *l, struct list_head *h)
|
||
{
|
||
__list_del(l->prev, l->next);
|
||
list_add(l, h);
|
||
}
|
||
|
||
/** 将节点移动到新链表尾部 */
|
||
static inline void list_move_tail(struct list_head *l, struct list_head *h)
|
||
{
|
||
__list_del(l->prev, l->next);
|
||
list_add_tail(l, h);
|
||
}
|
||
|
||
/* ---- 替换操作 ---- */
|
||
|
||
/** 用 node 替换 old */
|
||
static inline void list_replace(struct list_head *old, struct list_head *node)
|
||
{
|
||
node->next = old->next;
|
||
node->next->prev = node;
|
||
node->prev = old->prev;
|
||
node->prev->next = node;
|
||
}
|
||
|
||
/** 替换后初始化被替换节点 */
|
||
static inline void list_replace_init(struct list_head *old,
|
||
struct list_head *node)
|
||
{
|
||
list_replace(old, node);
|
||
INIT_LIST_HEAD(old);
|
||
}
|
||
|
||
/* ---- 判断操作 ---- */
|
||
|
||
/** 判断链表是否为空 */
|
||
static inline int list_empty(const struct list_head *h)
|
||
{
|
||
return h->next == h;
|
||
}
|
||
|
||
/** 判断节点是否已链入链表 */
|
||
static inline int list_is_linked(const struct list_head *e)
|
||
{
|
||
return e->next != e;
|
||
}
|
||
|
||
/* ---- 节点 ↔ 宿主指针转换 ---- */
|
||
|
||
/** 从链表节点指针取回宿主结构体指针 */
|
||
#define list_entry(ptr, type, member) \
|
||
((type *)((char *)(ptr) - offsetof(type, member)))
|
||
|
||
/** 获取第一个宿主元素 */
|
||
#define list_first_entry(h, type, member) \
|
||
list_entry((h)->next, type, member)
|
||
|
||
/** 获取最后一个宿主元素 */
|
||
#define list_last_entry(h, type, member) \
|
||
list_entry((h)->prev, type, member)
|
||
|
||
/** 安全获取第一个元素(链表空返回 NULL) */
|
||
#define list_first_entry_or_null(h, type, member) \
|
||
(list_empty(h) ? NULL : list_first_entry(h, type, member))
|
||
|
||
/* ---- 遍历操作 ---- */
|
||
|
||
/** 遍历链表节点(仅获取 struct list_head 指针) */
|
||
#define list_for_each(pos, head) \
|
||
for (pos = (head)->next; pos != (head); pos = pos->next)
|
||
|
||
/** 安全遍历节点(可在遍历中删除 pos) */
|
||
#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_first_entry(head, __typeof__(*pos), member); \
|
||
&pos->member != (head); \
|
||
pos = list_entry(pos->member.next, __typeof__(*pos), member))
|
||
|
||
/** 安全遍历宿主元素(可在遍历中删除 pos) */
|
||
#define list_for_each_entry_safe(pos, n, head, member) \
|
||
for (pos = list_first_entry(head, __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))
|
||
|
||
/* ---- 拼接操作 ---- */
|
||
|
||
/** 将 src 链表拼接到 dst 头部,src 被清空 */
|
||
static inline void list_splice_init(struct list_head *src,
|
||
struct list_head *dst)
|
||
{
|
||
if (!list_empty(src))
|
||
{
|
||
struct list_head *f = src->next;
|
||
struct list_head *l = src->prev;
|
||
struct list_head *a = dst->next;
|
||
|
||
f->prev = dst;
|
||
dst->next = f;
|
||
l->next = a;
|
||
a->prev = l;
|
||
INIT_LIST_HEAD(src);
|
||
}
|
||
}
|
||
|
||
#ifdef __cplusplus
|
||
}
|
||
#endif
|
||
|
||
#endif /* _LIST_H_ */
|