样例工程目录结构
WQiang authored at 2021-12-01 10:47:56
6.98 KiB
microCLib
#pragma once

#ifndef __MyList_H__
#define __MyList_H__

#include "Type.h"
#include "Debug.h"

/**
 * 侵入式双向循环链表
 * 参考Linux内核链表实现
 * 使用方法:在结构体中包含 ListHead 成员
 */

/* 链表节点定义 */
typedef struct ListNode
{
    struct ListNode* Previous;
    struct ListNode* Next;
} ListNode;

/* 链表头定义(与节点结构相同) */
typedef ListNode ListHead;

/**
 * 初始化链表头
 * @param head 链表头指针
 */
static inline void InitListHead(ListHead* head)
{
    head->Previous = head;
    head->Next = head;
}

/**
 * 判断链表是否为空
 * @param head 链表头指针
 * @return true 表示空,false 表示非空
 */
static inline bool ListIsEmpty(const ListHead* head)
{
    return head->Next == head;
}

/**
 * 判断链表是否只有一个节点(只有头节点)
 * @param head 链表头指针
 * @return true 表示只有头节点,false 表示有多于一个节点
 */
static inline bool ListIsSingle(const ListHead* head)
{
    return head->Next == head->Previous;
}

/**
 * 在两个节点之间插入新节点
 * @param prev 前驱节点
 * @param next 后继节点
 * @param newNode 要插入的新节点
 */
static inline void ListInsertBetween(ListNode* prev, ListNode* next, ListNode* newNode)
{
    next->Previous = newNode;
    newNode->Next = next;
    newNode->Previous = prev;
    prev->Next = newNode;
}

/**
 * 在链表头部插入节点(在head之后插入)
 * @param head 链表头指针
 * @param newNode 要插入的新节点
 */
static inline void ListAdd(ListHead* head, ListNode* newNode)
{
    ListInsertBetween(head, head->Next, newNode);
}

/**
 * 在链表尾部插入节点(在head之前插入,即链表末尾)
 * @param head 链表头指针
 * @param newNode 要插入的新节点
 */
static inline void ListAddTail(ListHead* head, ListNode* newNode)
{
    ListInsertBetween(head->Previous, head, newNode);
}

/**
 * 从链表中删除节点
 * @param node 要删除的节点
 */
static inline void ListDel(ListNode* node)
{
    node->Previous->Next = node->Next;
    node->Next->Previous = node->Previous;
    node->Previous = NULL;
    node->Next = NULL;
}

/**
 * 从链表中删除节点并重新初始化
 * @param node 要删除的节点
 */
static inline void ListDelInit(ListNode* node)
{
    ListDel(node);
    InitListHead(node);
}

/**
 * 将节点从一个链表移动到另一个链表的头部
 * @param head 目标链表头指针
 * @param node 要移动的节点
 */
static inline void ListMove(ListHead* head, ListNode* node)
{
    ListDel(node);
    ListAdd(head, node);
}

/**
 * 将节点从一个链表移动到另一个链表的尾部
 * @param head 目标链表头指针
 * @param node 要移动的节点
 */
static inline void ListMoveTail(ListHead* head, ListNode* node)
{
    ListDel(node);
    ListAddTail(head, node);
}

/**
 * 遍历链表(不安全,不能在遍历时删除节点)
 * @param pos 当前遍历到的节点指针
 * @param head 链表头指针
 */
#define ListForEach(pos, head) \
    for (pos = (head)->Next; pos != (head); pos = pos->Next)

/**
 * 遍历链表(安全版本,可以在遍历时删除节点)
 * @param pos 当前遍历到的节点指针
 * @param n 用于临时存储下一个节点的指针
 * @param head 链表头指针
 */
#define ListForEachSafe(pos, n, head) \
    for (pos = (head)->Next, n = pos->Next; pos != (head); \
         pos = n, n = pos->Next)

/**
 * 遍历链表,从尾部开始(不安全)
 * @param pos 当前遍历到的节点指针
 * @param head 链表头指针
 */
#define ListForEachPrev(pos, head) \
    for (pos = (head)->Previous; pos != (head); pos = pos->Previous)

/**
 * 遍历链表,从尾部开始(安全版本)
 * @param pos 当前遍历到的节点指针
 * @param n 用于临时存储上一个节点的指针
 * @param head 链表头指针
 */
#define ListForEachPrevSafe(pos, n, head) \
    for (pos = (head)->Previous, n = pos->Previous; pos != (head); \
         pos = n, n = pos->Previous)

/**
 * 通过链表节点获取父结构体指针
 * @param node 链表节点指针
 * @param type 父结构体类型
 * @param member 链表节点在父结构体中的成员名
 */
#define ListEntry(node, type, member) \
    container_of(node, type, member)

/**
 * 遍历链表并获取父结构体(不安全版本)
 * @param pos 存储父结构体指针的变量
 * @param head 链表头指针
 * @param type 父结构体类型
 * @param member 链表节点在父结构体中的成员名
 */
#define ListForEachEntry(pos, head, type, member) \
    for (pos = ListEntry((head)->Next, type, member); \
         &pos->member != (head); \
         pos = ListEntry(pos->member.Next, type, member))

/**
 * 遍历链表并获取父结构体(安全版本)
 * @param pos 存储父结构体指针的变量
 * @param n 临时存储下一个父结构体指针的变量
 * @param head 链表头指针
 * @param type 父结构体类型
 * @param member 链表节点在父结构体中的成员名
 */
#define ListForEachEntrySafe(pos, n, head, type, member) \
    for (pos = ListEntry((head)->Next, type, member), \
         n = ListEntry(pos->member.Next, type, member); \
         &pos->member != (head); \
         pos = n, n = ListEntry(n->member.Next, type, member))

/**
 * 遍历链表并获取父结构体,从尾部开始(不安全版本)
 * @param pos 存储父结构体指针的变量
 * @param head 链表头指针
 * @param type 父结构体类型
 * @param member 链表节点在父结构体中的成员名
 */
#define ListForEachEntryPrev(pos, head, type, member) \
    for (pos = ListEntry((head)->Previous, type, member); \
         &pos->member != (head); \
         pos = ListEntry(pos->member.Previous, type, member))

/* 链表相关函数声明 */

/**
 * 获取链表长度
 * @param head 链表头指针
 * @return 链表节点数量(不包括头节点)
 */
uint ListGetLength(ListHead* head);

/**
 * 获取链表第一个节点的数据(如果为空返回NULL)
 * @param head 链表头指针
 * @param type 父结构体类型
 * @param member 链表节点在父结构体中的成员名
 */
#define ListFirstEntry(head, type, member) \
    (ListIsEmpty(head) ? NULL : ListEntry((head)->Next, type, member))

/**
 * 获取链表最后一个节点的数据(如果为空返回NULL)
 * @param head 链表头指针
 * @param type 父结构体类型
 * @param member 链表节点在父结构体中的成员名
 */
#define ListLastEntry(head, type, member) \
    (ListIsEmpty(head) ? NULL : ListEntry((head)->Previous, type, member))

/**
 * 获取下一个节点的数据
 * @param node 当前节点
 * @param type 父结构体类型
 * @param member 链表节点在父结构体中的成员名
 */
#define ListNextEntry(node, type, member) \
    (ListEntry((node)->member.Next, type, member))

/**
 * 获取上一个节点的数据
 * @param node 当前节点
 * @param type 父结构体类型
 * @param member 链表节点在父结构体中的成员名
 */
#define ListPrevEntry(node, type, member) \
    (ListEntry((node)->member.Previous, type, member))

#endif