RTU_ALL_AI/release/inc/list.h

204 lines
5.2 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @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_ */