109 lines
2.3 KiB
C
109 lines
2.3 KiB
C
/**
|
|
* 日期: 2026-04-01
|
|
* 作者: coffee
|
|
* 描述: 侵入式双向链表基础组件
|
|
* 用法类似内核 list, 节点嵌入到用户结构体中
|
|
*/
|
|
|
|
#ifndef _H_LIST_H_
|
|
#define _H_LIST_H_
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
|
|
|
|
typedef struct HList {
|
|
struct HList *next;
|
|
struct HList *prev;
|
|
} HList;
|
|
|
|
|
|
#define HLIST_HEAD_INIT(name) { &(name), &(name) }
|
|
|
|
#define HLIST_HEAD(name) HList name = HLIST_HEAD_INIT(name)
|
|
|
|
#define HLIST_CONTAINER_OF(ptr, type, member) \
|
|
((type *)((uint8_t *)(ptr) - offsetof(type, member)))
|
|
|
|
#define HLIST_ENTRY(ptr, type, member) \
|
|
HLIST_CONTAINER_OF(ptr, type, member)
|
|
|
|
#define HLIST_FIRST_ENTRY(head, type, member) \
|
|
HLIST_ENTRY((head)->next, type, member)
|
|
|
|
#define HLIST_LAST_ENTRY(head, type, member) \
|
|
HLIST_ENTRY((head)->prev, type, member)
|
|
|
|
#define HLIST_FOR_EACH(pos, head) \
|
|
for ((pos) = (head)->next; (pos) != (head); (pos) = (pos)->next)
|
|
|
|
#define HLIST_FOR_EACH_TYPE(pos, head) \
|
|
for (HList *(pos) = (head)->next; (pos) != (head); (pos) = (pos)->next)
|
|
|
|
#define HLIST_FOR_EACH_SAFE(pos, n, head) \
|
|
for ((pos) = (head)->next, (n) = (pos)->next; (pos) != (head); \
|
|
(pos) = (n), (n) = (pos)->next)
|
|
|
|
#define HLIST_FOR_EACH_SAFE_TYPE(pos, n, head) \
|
|
for (HList *(pos) = (head)->next, (n) = (pos)->next; (pos) != (head); \
|
|
(pos) = (n), (n) = (pos)->next)
|
|
|
|
|
|
/**
|
|
* @brief 初始化链表头或节点
|
|
*/
|
|
void HListInit(HList *list);
|
|
|
|
/**
|
|
* @brief 判断节点是否已经独立初始化
|
|
*/
|
|
uint8_t HListIsSelf(const HList *list);
|
|
|
|
/**
|
|
* @brief 判断链表是否为空
|
|
*/
|
|
uint8_t HListEmpty(const HList *head);
|
|
|
|
/**
|
|
* @brief 获取链表节点数量
|
|
*/
|
|
size_t HListLen(const HList *head);
|
|
|
|
/**
|
|
* @brief 头插
|
|
*/
|
|
void HListAdd(HList *node, HList *head);
|
|
|
|
/**
|
|
* @brief 尾插
|
|
*/
|
|
void HListAddTail(HList *node, HList *head);
|
|
|
|
/**
|
|
* @brief 删除节点, 删除后节点会重新初始化成独立状态
|
|
*/
|
|
void HListDel(HList *node);
|
|
|
|
/**
|
|
* @brief 替换节点
|
|
*/
|
|
void HListReplace(HList *oldNode, HList *newNode);
|
|
|
|
/**
|
|
* @brief 移动节点到目标链表头部
|
|
*/
|
|
void HListMove(HList *node, HList *head);
|
|
|
|
/**
|
|
* @brief 移动节点到目标链表尾部
|
|
*/
|
|
void HListMoveTail(HList *node, HList *head);
|
|
|
|
/**
|
|
* @brief 弹出头节点
|
|
* @return 成功返回节点指针, 空链表返回 NULL
|
|
*/
|
|
HList *HListPop(HList *head);
|
|
|
|
#endif // _H_LIST_H_
|