-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathjlist.h
269 lines (246 loc) · 8.32 KB
/
jlist.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
/*******************************************
* SPDX-License-Identifier: MIT *
* Copyright (C) 2024-.... Jing Leng *
* Contact: Jing Leng <[email protected]> *
* https://github.com/lengjingzju/jcore *
*******************************************/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief 双向循环链表的头和成员
* @note 双向循环链表添加删除更简单,但是成员也是两个指针,更浪费空间
*/
struct jdlist_head {
struct jdlist_head *next, *prev;
};
/**
* @brief 判断双向循环链表是否为空
* @param head [IN] 链表头
* @return 链表为空时返回真,否则返回假
* @note 无
*/
#define jdlist_empty(head) ((head)->next == (head))
/**
* @brief 从节点的双向链表成员指针获取节点的指针
* @param ptr [IN] 节点的链表成员指针
* @param type [IN] 节点结构体的类型名
* @param member [IN] 节点的链表成员名
* @return 返回节点的指针
* @note 无
*/
#define jdlist_entry(ptr, type, member) ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
/**
* @brief 遍历双向循环链表的循环头
* @param pos [OUT] 被赋值当前节点的指针
* @param head [IN] 链表头
* @param member [IN] 节点的链表成员名
* @return 不是函数,无返回概念
* @note 一般是操作pos,不能在循环体内部进行添加删除节点操作
*/
#define jdlist_for_each_entry(pos, head, member) \
for (pos = jdlist_entry((head)->next, typeof(*pos), member); \
&pos->member != (head); \
pos = jdlist_entry(pos->member.next, typeof(*pos), member))
/**
* @brief 安全遍历双向循环链表的循环头
* @param pos [OUT] 给他赋值当前节点的指针
* @param n [OUT] 给他赋值后一节点的指针
* @param head [IN] 链表头
* @param member [IN] 节点的链表成员名
* @return 不是函数,无返回概念
* @note 一般是操作pos,可以在循环体内部进行添加删除节点操作
*/
#define jdlist_for_each_entry_safe(pos, n, head, member) \
for (pos = jdlist_entry((head)->next, typeof(*pos), member), \
n = jdlist_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = jdlist_entry(n->member.next, typeof(*n), member))
/**
* @brief 初始化双向循环链表头
* @param head [INOUT] 链表头
* @return 无返回值
* @note 无
*/
static inline void jdlist_init_head(struct jdlist_head *head)
{
head->next = head;
head->prev = head;
}
static inline void __jdlist_add(struct jdlist_head *_new,
struct jdlist_head *prev, struct jdlist_head *next)
{
next->prev = _new;
_new->next = next;
_new->prev = prev;
prev->next = _new;
}
/**
* @brief 加入新节点到指定节点后面
* @param _new [INOUT] 要加入的节点
* @param list [INOUT] 参考位置的节点
* @return 无返回值
* @note 无
*/
static inline void jdlist_add(struct jdlist_head *_new, struct jdlist_head *list)
{
__jdlist_add(_new, list, list->next);
}
/**
* @brief 加入新节点到指定节点前面
* @param _new [INOUT] 要加入的节点
* @param list [INOUT] 参考位置的节点
* @return 无返回值
* @note 无
*/
static inline void jdlist_add_tail(struct jdlist_head *_new, struct jdlist_head *list)
{
__jdlist_add(_new, list->prev, list);
}
/**
* @brief 从链表中删除指定节点
* @param _del [INOUT] 要删除的节点
* @return 无返回值
* @note 一般是操作pos,可以在循环体内部进行添加删除节点操作
*/
static inline void jdlist_del(struct jdlist_head *_del)
{
struct jdlist_head *prev = _del->prev;
struct jdlist_head *next = _del->next;
next->prev = prev;
prev->next = next;
jdlist_init_head(_del);
}
/**
* @brief 单向循环链表的成员
* @note 单向循环链表添加删除稍显复杂,但是只有一个指针,更省空间
*/
struct jslist {
struct jslist *next;
};
/**
* @brief 单向循环链表的头
* @note 单向循环链表多记录prev是为了添加到链表尾部更快速
*/
struct jslist_head {
struct jslist *next, *prev;
};
/**
* @brief 判断单向循环链表是否为空
* @param head [IN] 链表头
* @return 链表为空时返回真,否则返回假
* @note 无
*/
#define jslist_empty(head) ((head)->next == (struct jslist *)(head))
/**
* @brief 从节点的单向链表成员指针获取节点的指针
* @param ptr [IN] 节点的链表成员指针
* @param type [IN] 节点结构体的类型名
* @param member [IN] 节点的链表成员名
* @return 返回节点的指针
* @note 无
*/
#define jslist_entry(ptr, type, member) ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
/**
* @brief 遍历单向循环链表的循环头
* @param pos [OUT] 被赋值当前节点的指针
* @param head [IN] 链表头
* @param member [IN] 节点的链表成员名
* @return 不是函数,无返回概念
* @note 一般是操作pos,不能在循环体内部进行添加删除节点操作
*/
#define jslist_for_each_entry(pos, head, member) \
for (pos = jslist_entry((head)->next, typeof(*pos), member); \
&pos->member != (struct jslist *)(head); \
pos = jslist_entry(pos->member.next, typeof(*pos), member))
/**
* @brief 安全遍历单向循环链表的循环头
* @param p [OUT] 给他赋值前一节点的指针
* @param pos [OUT] 给他赋值当前节点的指针
* @param n [OUT] 给他赋值后一节点的指针
* @param head [IN] 链表头
* @param member [IN] 节点的链表成员名
* @return 不是函数,无返回概念
* @note 一般是操作pos,可以在循环体内部进行添加删除节点操作
* 注意修改时注意重新赋值,例如删除pos节点需要再循环体内部设置"pos = p;"
*/
#define jslist_for_each_entry_safe(p, pos, n, head, member) \
for (p = jslist_entry((head), typeof(*pos), member), \
pos = jslist_entry((head)->next, typeof(*pos), member), \
n = jslist_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (struct jslist *)(head); \
p = pos, pos = n, n = jslist_entry(n->member.next, typeof(*n), member))
/**
* @brief 初始化单向循环链表头
* @param head [INOUT] 链表头
* @return 无返回值
* @note 无
*/
static inline void jslist_init_head(struct jslist_head *head)
{
head->next = (struct jslist *)head;
head->prev = (struct jslist *)head;
}
/**
* @brief 在链表首部加入新节点
* @param _new [INOUT] 要加入的节点
* @param head [INOUT] 链表头
* @return 无返回值
* @note 无
*/
static inline void jslist_add_head(struct jslist *_new, struct jslist_head *head)
{
if (head->next == (struct jslist *)head) {
head->prev = _new;
}
_new->next = head->next;
head->next = _new;
}
/**
* @brief 在链表尾部加入新节点
* @param _new [INOUT] 要加入的节点
* @param head [INOUT] 链表头
* @return 无返回值
* @note 无
*/
static inline void jslist_add_head_tail(struct jslist *_new, struct jslist_head *head)
{
_new->next = head->prev->next;
head->prev->next = _new;
head->prev = _new;
}
/**
* @brief 在链表指定节点的后边加入新节点
* @param _new [INOUT] 要加入的节点
* @param prev [INOUT] 参考位置的节点
* @param head [INOUT] 链表头
* @return 无返回值
* @note 无
*/
static inline void jslist_add(struct jslist *_new, struct jslist *prev, struct jslist_head *head)
{
if (prev->next == (struct jslist *)head) {
head->prev = _new;
}
_new->next = prev->next;
prev->next = _new;
}
/**
* @brief 从链表中删除指定节点
* @param _del [INOUT] 要删除的节点
* @param prev [INOUT] 要删除的节点的前一节点
* @return 无返回值
* @note 一般是操作pos,可以在循环体内部进行添加删除节点操作
*/
static inline void jslist_del(struct jslist *_del, struct jslist *prev, struct jslist_head *head)
{
if (_del->next == (struct jslist *)head) {
head->prev = prev;
}
prev->next = _del->next;
_del->next = NULL;
}
#ifdef __cplusplus
}
#endif