component/inc/mlist.h

269 lines
9.4 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.

/***
* @Author:
* @Date: 2023-04-04 08:39:32
* @LastEditors: xxx
* @LastEditTime: 2023-04-04 08:46:20
* @Description:双向链表操作接口 该双向链表的操作请参照Linux内核 (include/linux/list.h)
* @email:
* @Copyright (c) 2023 by xxx, All Rights Reserved.
*/
#ifndef __LIST_H
#define __LIST_H
#include <stdbool.h>
#include "data_type_def.h"
typedef struct list_head
{
struct list_head *next;
struct list_head *prev;
} list_head_t;
/**
* 获得链表元素所在实体的地址, 该实体在链表中保存
*
* @param ptr: 链表的入口指针
* @param type: 结构类型
* @param member: 元素结构中链表变量的名字
*
* @return 指向该元素所在实体的指针
*/
#define list_entry_addr_find(ptr, type, member) \
((type *)((char *)(ptr) - (char *)(&((type *)NULL)->member)))
/**
* 移除并返回链表中首元素所在的实体,该实体在链表中不保存
*
* @param head: 链表的入口指针
* @param type: 结构类型
* @param member: 指向该链表的第一个元素的指针
*
* @return 表首元素所在实体的指针,链表为空则返回空指针
*/
#define list_entry_decap(head, type, member) \
( \
(list_empty(head)) ? (type *)NULL \
: (list_entry_addr_find(list_next_elem_get(head), type, member)))
#define list_entry_get_head(head, type, member) \
((list_empty(head)) ? (type *)NULL : (list_entry_addr_find((head)->next, type, member)))
/**
* 移除并返回链表尾部所在实体,该实体在链表中不保存
*
* @param head: 链表入口指针
* @param type: 链表所在结构体的名称
* @param member: 结构体中,链表变量的名称
*
* @return 表尾部所在实体指针,链表为空则返回空指针
*/
#define list_entry_curtail(head, type, member) \
((list_empty(head)) ? (type *)NULL \
: (list_entry_addr_find(list_curtail(head), type, member)))
/**
* 正向遍历链表,在该遍历中不能对链表做删除操作 -- list_for_each
*
* @param pos: 链表元素计数器
* @param head: 链表的入口指针
*/
#define list_for_each_forwards(pos, head) \
for ((pos) = (head)->next; (pos) != (head); (pos) = (pos)->next)
/**
* 反向遍历链表,在该遍历中不能对链表做删除操作
*
* @param pos: 链表元素计数器
* @param head: 链表的入口指针
*/
#define list_for_each_backwards(pos, head) \
for ((pos) = (head)->prev; (pos) != (head); (pos) = (pos)->prev)
/**
* 链表遍历,支持删除操作
*
* @param pos: 链表元素计数器
* @param n: 临时链表元素
* @param head: 链表入口指针
*/
#define list_for_each_safe(pos, n, head) \
for ((pos) = (head)->next, n = (pos)->next; (pos) != (head); \
(pos) = n, n = (pos)->next)
/**
* 遍历链表所在实体,不可删除实体
*
* @param pos: 链表元素计数器
* @param head: 链表入口指针
* @param type: 链表所在结构体的名称
* @param member: 结构体中,链表变量的名称
*/
#define list_entry_for_each(pos, head, type, member) \
for ((pos) = list_entry_addr_find((head)->next, type, member); \
&(pos)->member != (head); \
(pos) = list_entry_addr_find((pos)->member.next, type, member))
/**
* 遍历链表所在实体, 支持删除操作
*
* @param pos: 链表元素计数器
* @param n: 临时链表元素
* @param head: 链表入口指针
* @param type: 链表所在结构体的名称
* @param member: 结构体中,链表变量的名称
*/
#define list_entry_for_each_safe(pos, n, head, type, member) \
for ((pos) = list_entry_addr_find((head)->next, type, member), \
n = list_entry_addr_find((pos)->member.next, type, member); \
&(pos)->member != (head); \
(pos) = n, n = list_entry_addr_find(n->member.next, type, member))
/**
* 计算链表中元素的个数
*/
#define list_count(head, count) \
do \
{ \
count = 0; \
for (list_head_t *pos = (head)->next; pos != (head); pos = pos->next) \
{ \
count++; \
} \
} while (0)
/**
* 将实体按顺序插入到链表中合适的地方顺序由函数funcCompare来决定 -- list_sorted_add
*
* @param new_entry: 所要插入的实体
* @param head: 链表头
* @param type: 链表所在结构体的名称
* @param member: 结构体中,链表变量的名称
* @param func_compare: 顺序比较函数,声明bool func_compare(Node* A, Node* B)
* 如果 A < B, 返回 true, 否则返回 false
* @param pos: 链表元素计数器
*/
#define list_entry_sorted_add(new_entry, head, type, member, func_compare, pos) \
do \
{ \
type *entry_a = NULL; \
type *entry_b = NULL; \
for ((pos) = (head)->next; (pos) != (head); (pos) = (pos)->next) \
{ \
entry_a = list_entry_addr_find((new_entry), type, member); \
entry_b = list_entry_addr_find((pos), type, member); \
if (func_compare(entry_a, entry_b)) \
{ \
break; \
} \
} \
if ((pos) != (head)) \
{ \
list_insert_forwards((new_entry), (pos)); \
} \
else \
{ \
list_add_to_tail((new_entry), (head)); \
} \
} while (__LINE__ == -1)
/**
* 链表头初始化
*
* @param ptr: 需要被初始化的链表头指针
*/
void list_init(list_head_t *const ptr);
/**
* 在指定位置之前插入新的元素
*
* @param new_entry: 需要放入链表中的新元素
* @param pos: 链表中放入新元素的位置指针
*/
void list_insert_forwards(list_head_t *const new_entry, list_head_t *const pos);
/**
* 在指定位置之后插入新的元素
*
* @param new_entry: 需要放入链表中的新元素
* @param pos: 链表中放入新元素的位置指针
*/
void list_insert_backwards(list_head_t *const new_entry, list_head_t *const pos);
/**
* 在链表尾部之后插入新的元素 -- list_append
*
* @param new_entry: 需要放入链表尾部的新元素
* @param list: 链表头指针
*/
void list_add_to_tail(list_head_t *const new_entry, list_head_t *const list);
/**
* 在链表头部之后插入新的元素
*
* @param new_entry: 需要放入链表尾部的新元素
* @param list: 链表头指针
*/
void list_add_to_head(list_head_t *const new_entry, list_head_t *const list);
/**
* 将指定元素从链表中删除
*
* @param elem: 需要删除的链表元素
*/
void list_del(list_head_t *const elem);
/**
* 将链表的尾元素删除并返回
*
* @param head: 链表指针
*
* @return 链表尾元素
*/
list_head_t *list_curtail(const list_head_t *const head);
/**
* 判断链表是否为空
*
* @param head: 链表头指针
*
* @return 为空时返回TRUE否则为FALSE
*/
bool list_empty(const list_head_t *const head);
/**
* 获取链表中第一个元素的地址 -- list_get_head
*
* @param head: 链表头指针
*
* @return 首元素的地址
*/
list_head_t *list_first_elem_look(const list_head_t *const head);
/**
* 取出给定位置的下一个元素
*
* @param pos: 链表元素地址
*
* @return 下一个链表元素地址
*/
list_head_t *list_next_elem_get(const list_head_t *const pos);
/**
* 将一个元素从一个链表中移除,然后再插入另外一个链表中的头部
*
* @param elem: 被移除的链表元素
* @param head: 新链表头
*/
void list_move_to_another_head(list_head_t *const elem, list_head_t *const head);
/**
* 将一个元素从一个链表中移除,然后再放入另外一个链表中的尾部
*
* @param elem: 被移除的链表元素
* @param head: 新链表头
*/
void list_move_to_another_tail(list_head_t *const elem, list_head_t *const head);
#endif
/**
* @}
*/