/*********************************************************************************************
* @Copyright (c) , All rights reserved.
* @file: ListHead.hpp
* @version: ver 1.0
* @author: 闹闹
* @brief:
* @change:
* @email: 1319144981@qq.com
* Date Version Changed By Changes
* 2021/5/10 9:49:00 1.0 闹闹 create
写一句自己最喜欢的话吧。
为天地立心,为生民立命,为往圣继绝学,为万世开太平。
**********************************************************************************************/
/**********************************************************************************************
* modify_author: 闹闹
* modify_time: 2021/5/10 13:05:53
* modify_content:
* modify_reference:
* modify_other:
参考链接: https://blog.csdn.net/dijkstar/article/details/19249219
https://blog.csdn.net/weixin_40746176/article/details/100530190
https://blog.csdn.net/u014453898/article/details/53741921
https://blog.csdn.net/szullc/article/details/86565368
使用方法: https://blog.csdn.net/wanshilun/article/details/79747710
* modify_version: 1.0.0.2
**********************************************************************************************/
#pragma once
#ifndef __LISTHEAD_H__
#define __LISTHEAD_H__
#define LIST_POISON1 ((void *) 0x00100100)
#define LIST_POISON2 ((void *) 0x00200200)
#ifndef ARCH_HAS_PREFETCH
#define ARCH_HAS_PREFETCH
static inline void prefetch(const void *x) { ; }
static inline void prefetchw(const void *x) { ; }
#endif
/******************************************************************************
* @FuncName:
* @Author: 闹闹
* @Brief: 定义一个结构体,只含有表示前驱和后继的指针,它就是我们的主角了
* @Version: 1.0.0.1
* @Date: 2021/5/10 9:56
* @InputParameter:
* @OutputParameter:
* @Returns:
* @Others:
******************************************************************************/
struct list_head {
struct list_head *next, *prev;
};
/******************************************************************************
* @FuncName:
* @Author: 闹闹
* @Brief: 静态初始化
* @Version: 1.0.0.1
* @Date: 2021/5/10 9:56
* @InputParameter:
* @OutputParameter:
* @Returns:
* @Others:
******************************************************************************/
#define LIST_HEAD_INIT(name){&(name),&(name)}
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
//
//#ifndef offsetof
//#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
//#endif
//#define container_of(ptr, type, member) ({ \
// const typeof( ((type *)0)->member ) *__mptr = (ptr); \
// (type *)( (char *)__mptr - offsetof(type,member) );})
#define INIT_LIST_HEAD(listPtr) do{\
(listPtr)->next = (listPtr); (listPtr)->prev = (listPtr);\
}while(0)
/******************************************************************************
* @FuncName:
* @Author: 闹闹
* @Brief: 将一个元素插入到两个元素之间, 即将 new插入到prev和next中, 这个函数是下面在头部和尾部插入的实现基础
* @Version: 1.0.0.1
* @Date: 2021/5/10 9:56
* @InputParameter:
* @OutputParameter:
* @Returns:
* @Others:
******************************************************************************/
static inline void __list_add(struct list_head *newptr,struct list_head *prev,struct list_head *next){
// 前后向指针的改写赋值
next->prev = newptr;
newptr->next = next;
newptr->prev = prev;
prev->next = newptr;
}
/******************************************************************************
* @FuncName:
* @Author: 闹闹
* @Brief: 在头部插入,在头指针和第一个元素间插入,
* @Version: 1.0.0.1
* @Date: 2021/5/10 9:56
* @InputParameter: newptr 新指针 head 链表头指针
* @OutputParameter:
* @Returns:
* @Others:
******************************************************************************/
static inline void list_add(struct list_head *newptr, struct list_head *head){
__list_add(newptr, head, head->next);
}
/******************************************************************************
* @FuncName:
* @Author: 闹闹
* @Brief: 在尾部插入,在最后一个元素间和头指针间插入, 因为是循环链表嘛~
* @Version: 1.0.0.1
* @Date: 2021/5/10 9:56
* @InputParameter: newptr 新指针 head 链表头指针
* @OutputParameter:
* @Returns:
* @Others:
******************************************************************************/
static inline void list_add_tail(struct list_head *newptr, struct list_head *head){
__list_add(newptr, head->prev, head);
}
/******************************************************************************
* @FuncName:
* @Author: 闹闹
* @Brief: 删除两个元素之间的元素~
* @Version: 1.0.0.1
* @Date: 2021/5/10 9:56
* @InputParameter:
* @OutputParameter:
* @Returns:
* @Others:
******************************************************************************/
static inline void __list_del(struct list_head * prev, struct list_head * next){
next->prev = prev;
prev->next = next;
}
/******************************************************************************
* @FuncName:
* @Author: 闹闹
* @Brief: 删除一个已知元素entry
* @Version: 1.0.0.1
* @Date: 2021/5/10 9:56
* @InputParameter:
* @OutputParameter:
* @Returns:
* @Others:
******************************************************************************/
static inline void list_del(struct list_head *entry){
__list_del(entry->prev, entry->next);
entry->next = (list_head *)LIST_POISON1;
entry->prev = (list_head *)LIST_POISON2;
}
static inline void list_del_init(struct list_head *entry){
__list_del(entry->prev, entry->next);
INIT_LIST_HEAD(entry);
}
/******************************************************************************
* @FuncName:
* @Author: 闹闹
* @Brief: 指针的变换
* @Version: 1.0.0.1
* @Date: 2021/5/10 9:56
* @InputParameter:
* @OutputParameter:
* @Returns:
* @Others:
******************************************************************************/
static inline void list_replace(struct list_head *old,struct list_head *newptr){
newptr->next = old->next;
newptr->next->prev = newptr;
newptr->prev = old->prev;
newptr->prev->next = newptr;
}
static inline void list_replace_init(struct list_head *old,struct list_head *newptr){
list_replace(old, newptr);
INIT_LIST_HEAD(old);
}
/******************************************************************************
* @FuncName:
* @Author: 闹闹
* @Brief: 将一个元素list 移动到另一个链表的head的头部
* @Version: 1.0.0.1
* @Date: 2021/5/10 9:56
* @InputParameter:
* @OutputParameter:
* @Returns:
* @Others:
******************************************************************************/
static inline void list_move(struct list_head *list, struct list_head *head){
// 从原处的list后摘掉
__list_del(list->prev,list->next);
// 添加到新链表的头部
list_add(list, head);
}
/******************************************************************************
* @FuncName:
* @Author: 闹闹
* @Brief: 将一个元素list 移动到另一个链表head的队尾
* @Version: 1.0.0.1
* @Date: 2021/5/10 9:56
* @InputParameter:
* @OutputParameter:
* @Returns:
* @Others:
******************************************************************************/
static inline void list_move_tail(struct list_head *list,struct list_head *head){
// 从原处的list后摘掉
__list_del(list->prev,list->next);
// 添加到新链表的队尾
list_add_tail(list, head);
}
/******************************************************************************
* @FuncName:
* @Author: 闹闹
* @Brief: 链表是否为空
* @Version: 1.0.0.1
* @Date: 2021/5/10 9:56
* @InputParameter:
* @OutputParameter:
* @Returns:
* @Others:
******************************************************************************/
static inline int list_empty(struct list_head *head){
return head->next == head;
}
/******************************************************************************
* @FuncName:
* @Author: 闹闹
* @Brief: list 是否为最后一个元素
* @Version: 1.0.0.1
* @Date: 2021/5/10 9:56
* @InputParameter:
* @OutputParameter:
* @Returns:
* @Others:
******************************************************************************/
static inline int list_is_last(const struct list_head *list, const struct list_head *head){
return list->next == head;
}
/******************************************************************************
* @FuncName:
* @Author: 闹闹
* @Brief: 检查链表是否为空并且没有被改变
* @Version: 1.0.0.1
* @Date: 2021/5/10 9:56
* @InputParameter:
* @OutputParameter:
* @Returns:
* @Others:
******************************************************************************/
static inline int list_empty_careful(const struct list_head *head){
struct list_head *next = head->next;
return (next == head) && (next == head->prev);
}
/******************************************************************************
* @FuncName:
* @Author: 闹闹
* @Brief: 拆分操作, 将一个队列由指定的位置拆成两个队列
* @Version: 1.0.0.1
* @Date: 2021/5/10 9:56
* @InputParameter:
* @OutputParameter:
* @Returns:
* @Others: list是新队列的head指针, 包括的元素从原head队列的第一个元素到entry, head队列仅包括余下的元素
******************************************************************************/
static inline void __list_cut_position(struct list_head *list,struct list_head *head, struct list_head *entry){
struct list_head *new_first = entry->next;
list->next = head->next;
list->next->prev = list;
list->prev = entry;
entry->next = list;
head->next = new_first;
new_first->prev = head;
}
/******************************************************************************
* @FuncName:
* @Author: 闹闹
* @Brief: 将list列表中除了list当前节点本身的其余部分,插入到prev和next之间
* @Version: 1.0.0.1
* @Date: 2021/5/10 9:56
* @InputParameter:
* @OutputParameter:
* @Returns:
* @Others:
******************************************************************************/
static inline void __list_splice(const struct list_head *list,struct list_head *prev){
struct list_head *first = list->next;
struct list_head *last = list->prev;
struct list_head *at = prev->next;
first->prev = prev;
prev->next = first;
last->next = at;
at->prev = last;
}
/******************************************************************************
* @FuncName:
* @Author: 闹闹
* @Brief: 将一个列表插入到另一个列表的头部
* @Version: 1.0.0.1
* @Date: 2021/5/10 9:56
* @InputParameter:
* @OutputParameter:
* @Returns:
* @Others:
******************************************************************************/
static inline void list_splice(struct list_head *list,struct list_head *head){
if (!list_empty(list))
__list_splice(list, head);
}
/******************************************************************************
* @FuncName:
* @Author: 闹闹
* @Brief: 连接两个列表并重新初始化清空的列表。
* @Version: 1.0.0.1
* @Date: 2021/5/10 9:56
* @InputParameter:
* @OutputParameter:
* @Returns:
* @Others:
******************************************************************************/
static void list_splice_init(struct list_head *list,struct list_head *head){
if (!list_empty(list)) {
__list_splice(list, head);
INIT_LIST_HEAD(list);
}
}
/******************************************************************************
* @FuncName:
* @Author: 闹闹
* @Brief: 将一个列表插入到另一个列表的尾部
* @Version: 1.0.0.1
* @Date: 2021/5/10 9:56
* @InputParameter:
* @OutputParameter:
* @Returns:
* @Others:
******************************************************************************/
static inline void list_splice_tail(struct list_head *list,struct list_head *head){
if (!list_empty(list))
__list_splice(list, head->prev);
}
/******************************************************************************
* @FuncName:
* @Author: 闹闹
* @Brief: 得到链表中的对象
* @Version: 1.0.0.1
* @Date: 2021/5/10 9:56
* @InputParameter:
* @OutputParameter:
* @Returns:
* @Others:
******************************************************************************/
#define list_entry(ptr, type, member) \
((type *)((char *)(ptr)-(size_t)(&((type *)0)->member)))
/******************************************************************************
* @FuncName:
* @Author: 闹闹
* @Brief: 得到链表第一个元素
* @Version: 1.0.0.1
* @Date: 2021/5/10 9:56
* @InputParameter:
* @OutputParameter:
* @Returns:
* @Others:
* list_first_entry - get the first element from a list
* @ptr: the list head to take the element from.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*
* Note, that list is expected to be not empty.
******************************************************************************/
#define list_first_entry(ptr, type, member) \
list_entry((ptr)->next, type, member)
/******************************************************************************
* @FuncName:
* @Author: 闹闹
* @Brief: 链表遍历,从前向后
* @Version: 1.0.0.1
* @Date: 2021/5/10 9:56
* @InputParameter:
* @OutputParameter:
* @Returns:
* @Others:
* list_for_each - iterate over a list
* @pos: the &struct list_head to use as a loop counter.
* @head: the head for your list.
******************************************************************************/
#define list_for_each(pos, head) \
for (pos = (head)->next, prefetch(pos->next); pos != (head); \
pos = pos->next, prefetch(pos->next))
/******************************************************************************
* @FuncName:
* @Author: 闹闹
* @Brief: 链表遍历,从前向后
* @Version: 1.0.0.1
* @Date: 2021/5/10 9:56
* @InputParameter:
* @OutputParameter:
* @Returns:
* @Others:
* __list_for_each - iterate over a list
* @pos: the &struct list_head to use as a loop cursor.
* @head: the head for your list.
*
此变体与list_for_each()的不同之处在于它是最简单的列表迭代代码,不需要预取。对于知道列表非常短(空)的代码,使用此选项比上式减少很多时间。
******************************************************************************/
#define __list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
/******************************************************************************
* @FuncName:
* @Author: 闹闹
* @Brief: 链表遍历,从后向前
* @Version: 1.0.0.1
* @Date: 2021/5/10 9:56
* @InputParameter:
* @OutputParameter:
* @Returns:
* @Others:
* list_for_each_prev - iterate over a list backwards
* @pos: the &struct list_head to use as a loop counter.
* @head: the head for your list.。
******************************************************************************/
#define list_for_each_prev(pos, head) \
for (pos = (head)->prev, prefetch(pos->prev); pos != (head); \
pos = pos->prev, prefetch(pos->prev))
/******************************************************************************
* @FuncName:
* @Author: 闹闹
* @Brief: 链表遍历,从后向前,对列表进行迭代,以防向后删除列表项
* @Version: 1.0.0.1
* @Date: 2021/5/10 9:56
* @InputParameter:
* @OutputParameter:
* @Returns:
* @Others:
* list_for_each_prev_safe - iterate over a list safe against removal of list entry backwards
* @pos: the &struct list_head to use as a loop cursor.
* @n: another &struct list_head to use as temporary storage
* @head: the head for your list.
******************************************************************************/
#define list_for_each_prev_safe(pos, n, head) \
for (pos = (head)->prev, n = pos->prev; prefetch(pos->prev), pos != (head); \
pos =n, n = pos->prev)
/******************************************************************************
* @FuncName:
* @Author: 闹闹
* @Brief: 链表遍历,从前向后,对列表进行迭代以防止删除列表项
* @Version: 1.0.0.1
* @Date: 2021/5/10 9:56
* @InputParameter:
* @OutputParameter:
* @Returns:
* @Others:
* list_for_each_safe - iterate over a list safe against removal of list entry
* @pos: the &struct list_head to use as a loop counter.
* @n: another &struct list_head to use as temporary storage
* @head: the head for your list.
******************************************************************************/
#define list_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)
/******************************************************************************
* @FuncName:
* @Author: 闹闹
* @Brief: 链表遍历,从前向后,迭代给定类型的列表
* @Version: 1.0.0.1
* @Date: 2021/5/10 9:56
* @InputParameter:
* @OutputParameter:
* @Returns:
* @Others:
* list_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop counter.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
******************************************************************************/
#define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member); \
prefetch(pos->member.next), &pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
/******************************************************************************
* @FuncName:
* @Author: 闹闹
* @Brief: 链表遍历,从后向前,迭代给定类型的列表
* @Version: 1.0.0.1
* @Date: 2021/5/10 9:56
* @InputParameter:
* @OutputParameter:
* @Returns:
* @Others:
* list_for_each_entry_reverse - iterate backwards over list of given type.
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
******************************************************************************/
#define list_for_each_entry_reverse(pos, head, member) \
for (pos = list_entry((head)->prev, typeof(*pos), member); \
prefetch(pos->member.prev), &pos->member != (head); \
pos = list_entry(pos->member.prev, typeof(*pos), member))
/******************************************************************************
* @FuncName:
* @Author: 闹闹
* @Brief: 为每个项目准备一个pos条目,以便在列表中使用list_for_each_entry_continue()
* @Version: 1.0.0.1
* @Date: 2021/5/10 9:56
* @InputParameter:
* @OutputParameter:
* @Returns:
* @Others:
* list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
* @pos: the type * to use as a start point
* @head: the head of the list
* @member: the name of the list_struct within the struct.
*
* Prepares a pos entry for use as a start point in list_for_each_entry_continue().
******************************************************************************/
#define list_prepare_entry(pos, head, member) \
((pos) ? : list_entry(head, typeof(*pos), member))
/******************************************************************************
* @FuncName:
* @Author: 闹闹
* @Brief: 继续迭代给定类型列表
* @Version: 1.0.0.1
* @Date: 2021/5/10 9:56
* @InputParameter:
* @OutputParameter:
* @Returns:
* @Others:
* list_for_each_entry_continue - continue iteration over list of given type
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*
* Continue to iterate over list of given type, continuing after
* the current position.
******************************************************************************/
#define list_for_each_entry_continue(pos, head, member) \
for (pos = list_entry(pos->member.next, typeof(*pos), member); \
prefetch(pos->member.next), &pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
/******************************************************************************
* @FuncName:
* @Author: 闹闹
* @Brief: 从当前点迭代给定类型的列表
* @Version: 1.0.0.1
* @Date: 2021/5/10 9:56
* @InputParameter:
* @OutputParameter:
* @Returns:
* @Others:
* list_for_each_entry_from - iterate over list of given type from the current point
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*
* Iterate over list of given type, continuing from current position.
******************************************************************************/
#define list_for_each_entry_from(pos, head, member) \
for (; prefetch(pos->member.next), &pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
/******************************************************************************
* @FuncName:
* @Author: 闹闹
* @Brief: 从当前点迭代给定类型的列表,迭代给定类型的列表,以防止删除列表项
* @Version: 1.0.0.1
* @Date: 2021/5/10 9:56
* @InputParameter:
* @OutputParameter:
* @Returns:
* @Others:
* list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
* @pos: the type * to use as a loop counter.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
******************************************************************************/
#define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_entry((head)->next, 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))
/******************************************************************************
* @FuncName:
* @Author: 闹闹
* @Brief: 迭代给定类型的列表,在当前点之后继续,防止删除列表条目。
* @Version: 1.0.0.1
* @Date: 2021/5/10 9:56
* @InputParameter:
* @OutputParameter:
* @Returns:
* @Others:
* list_for_each_entry_safe_continue
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
* Iterate over list of given type, continuing after current point,
* safe against removal of list entry.
******************************************************************************/
#define list_for_each_entry_safe_continue(pos, n, head, member) \
for (pos = list_entry(pos->member.next, 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))
/******************************************************************************
* @FuncName:
* @Author: 闹闹
* @Brief: 从当前点遍历给定类型的列表删除列表条目。
* @Version: 1.0.0.1
* @Date: 2021/5/10 9:56
* @InputParameter:
* @OutputParameter:
* @Returns:
* @Others:
* list_for_each_entry_safe_from
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*
* Iterate over list of given type from current point, safe against
* removal of list entry.
******************************************************************************/
#define list_for_each_entry_safe_from(pos, n, head, member) \
for (n = list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, typeof(*n), member))
/******************************************************************************
* @FuncName:
* @Author: 闹闹
* @Brief: 向后迭代给定类型的列表,防止删除列表条目的数目。
* @Version: 1.0.0.1
* @Date: 2021/5/10 9:56
* @InputParameter:
* @OutputParameter:
* @Returns:
* @Others:
* list_for_each_entry_safe_reverse
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*
* Iterate backwards over list of given type, safe against removal
* of list entry.
******************************************************************************/
#define list_for_each_entry_safe_reverse(pos, n, head, member) \
for (pos = list_entry((head)->prev, typeof(*pos), member), \
n = list_entry(pos->member.prev, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.prev, typeof(*n), member))
#endif //__LISTHEAD_H__
/************************ (C) COPYRIGHT LEI *****END OF FILE****/
example
#include "stdio.h"
#include <stdlib.h>
#include <string.h>
#include "ListHead.hpp"
//自定义的数据结构
struct list_test_struct
{
struct list_head list;
int key;
int data;
};
void main()
{
struct list_head list = { 0 }; //定义链表(头)
struct list_head *pos = NULL;
struct list_head *n = NULL;
int i = 0;
printf("定义链表\n");
printf("初始化链表!\r\n");
INIT_LIST_HEAD(&list); //初始化链表(头尾相接,形成空链表循环)
//判断链表是否为空
printf("判断链表是否为空:");
if (list_empty(&list)) {
printf("空\r\n");
}
else {
printf("非空\r\n");
}
//批量添加节点
printf("批量添加节点:\r\n");
for (i = 0; i < 10; i++)
{
int key = i; //key
int data = i * 10; //data
struct list_test_struct *st = (struct list_test_struct*)malloc(sizeof(struct list_test_struct));
st->key = key;
st->data = data;
list_add(&st->list, &list);
}
//显示列表所有节点
printf("显示列表所有节点:\r\n");
list_for_each(pos, &list)
{
struct list_test_struct *st = list_entry(pos, struct list_test_struct, list);
printf("\t node:key(%d),data(%d)\r\n", st->key, st->data);
}
//释放所有节点资源
printf("释放所有节点资源!\r\n");
list_for_each_safe(pos, n, &list)
{
struct list_test_struct *st = list_entry(pos, struct list_test_struct, list);
list_del(pos); //删除节点,删除节点必须在删除节点内存之前
free(st); //释放节点内存
}
system("psuse");
}