RTU_ALL_AI/release/inc/list.h

173 lines
4.0 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 内核风格侵入式双向循环链表纯头文件C/C++ 兼容)
*
* 用法:将 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)
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;
}
/* ---- 添加 ---- */
static inline void list_add(struct list_head *node, struct list_head *head)
{
__list_add(node, head, head->next);
}
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);
}
/* ---- 替换 ---- */
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)
#define list_first_entry_or_null(h, type, member) \
(list_empty(h) ? NULL : list_first_entry(h, type, member))
/* ---- 遍历 ---- */
#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
#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))
#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))
/* ---- 拼接 ---- */
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