Blender V4.3
BLI_linklist.c
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
13#include <stdlib.h>
14
15#include "MEM_guardedalloc.h"
16
17#include "BLI_linklist.h"
18#include "BLI_memarena.h"
19#include "BLI_mempool.h"
20#include "BLI_utildefines.h"
21
22#include "BLI_strict_flags.h" /* Keep last. */
23
25{
26 int len;
27
28 for (len = 0; list; list = list->next) {
29 len++;
30 }
31
32 return len;
33}
34
35int BLI_linklist_index(const LinkNode *list, const void *ptr)
36{
37 int index;
38
39 for (index = 0; list; list = list->next, index++) {
40 if (list->link == ptr) {
41 return index;
42 }
43 }
44
45 return -1;
46}
47
49{
50 int i;
51
52 for (i = 0; list; list = list->next, i++) {
53 if (i == index) {
54 return list;
55 }
56 }
57
58 return NULL;
59}
60
62{
63 if (list) {
64 while (list->next) {
65 list = list->next;
66 }
67 }
68 return list;
69}
70
72{
73 LinkNode *rhead = NULL, *cur = *listp;
74
75 while (cur) {
76 LinkNode *next = cur->next;
77
78 cur->next = rhead;
79 rhead = cur;
80
81 cur = next;
82 }
83
84 *listp = rhead;
85}
86
87void BLI_linklist_move_item(LinkNode **listp, int curr_index, int new_index)
88{
89 LinkNode *lnk, *lnk_psrc = NULL, *lnk_pdst = NULL;
90 int i;
91
92 if (new_index == curr_index) {
93 return;
94 }
95
96 if (new_index < curr_index) {
97 for (lnk = *listp, i = 0; lnk; lnk = lnk->next, i++) {
98 if (i == new_index - 1) {
99 lnk_pdst = lnk;
100 }
101 else if (i == curr_index - 1) {
102 lnk_psrc = lnk;
103 break;
104 }
105 }
106
107 if (!(lnk_psrc && lnk_psrc->next && (!lnk_pdst || lnk_pdst->next))) {
108 /* Invalid indices, abort. */
109 return;
110 }
111
112 lnk = lnk_psrc->next;
113 lnk_psrc->next = lnk->next;
114 if (lnk_pdst) {
115 lnk->next = lnk_pdst->next;
116 lnk_pdst->next = lnk;
117 }
118 else {
119 /* destination is first element of the list... */
120 lnk->next = *listp;
121 *listp = lnk;
122 }
123 }
124 else {
125 for (lnk = *listp, i = 0; lnk; lnk = lnk->next, i++) {
126 if (i == new_index) {
127 lnk_pdst = lnk;
128 break;
129 }
130 if (i == curr_index - 1) {
131 lnk_psrc = lnk;
132 }
133 }
134
135 if (!(lnk_pdst && (!lnk_psrc || lnk_psrc->next))) {
136 /* Invalid indices, abort. */
137 return;
138 }
139
140 if (lnk_psrc) {
141 lnk = lnk_psrc->next;
142 lnk_psrc->next = lnk->next;
143 }
144 else {
145 /* source is first element of the list... */
146 lnk = *listp;
147 *listp = lnk->next;
148 }
149 lnk->next = lnk_pdst->next;
150 lnk_pdst->next = lnk;
151 }
152}
153
155{
156 nlink->link = ptr;
157 nlink->next = *listp;
158 *listp = nlink;
159}
160
162{
163 LinkNode *nlink = MEM_mallocN(sizeof(*nlink), __func__);
164 BLI_linklist_prepend_nlink(listp, ptr, nlink);
165}
166
168{
169 LinkNode *nlink = BLI_memarena_alloc(ma, sizeof(*nlink));
170 BLI_linklist_prepend_nlink(listp, ptr, nlink);
171}
172
173void BLI_linklist_prepend_pool(LinkNode **listp, void *ptr, BLI_mempool *mempool)
174{
175 LinkNode *nlink = BLI_mempool_alloc(mempool);
176 BLI_linklist_prepend_nlink(listp, ptr, nlink);
177}
178
179void BLI_linklist_append_nlink(LinkNodePair *list_pair, void *ptr, LinkNode *nlink)
180{
181 nlink->link = ptr;
182 nlink->next = NULL;
183
184 if (list_pair->list) {
185 BLI_assert((list_pair->last_node != NULL) && (list_pair->last_node->next == NULL));
186 list_pair->last_node->next = nlink;
187 }
188 else {
189 BLI_assert(list_pair->last_node == NULL);
190 list_pair->list = nlink;
191 }
192
193 list_pair->last_node = nlink;
194}
195
196void BLI_linklist_append(LinkNodePair *list_pair, void *ptr)
197{
198 LinkNode *nlink = MEM_mallocN(sizeof(*nlink), __func__);
199 BLI_linklist_append_nlink(list_pair, ptr, nlink);
200}
201
203{
204 LinkNode *nlink = BLI_memarena_alloc(ma, sizeof(*nlink));
205 BLI_linklist_append_nlink(list_pair, ptr, nlink);
206}
207
208void BLI_linklist_append_pool(LinkNodePair *list_pair, void *ptr, BLI_mempool *mempool)
209{
210 LinkNode *nlink = BLI_mempool_alloc(mempool);
211 BLI_linklist_append_nlink(list_pair, ptr, nlink);
212}
213
215{
216 /* intentionally no NULL check */
217 void *link = (*listp)->link;
218 void *next = (*listp)->next;
219
220 MEM_freeN(*listp);
221
222 *listp = next;
223 return link;
224}
225
227{
228 /* intentionally no NULL check */
229 void *link = (*listp)->link;
230 void *next = (*listp)->next;
231
232 BLI_mempool_free(mempool, (*listp));
233
234 *listp = next;
235 return link;
236}
237
239{
240 LinkNode *nlink = MEM_mallocN(sizeof(*nlink), __func__);
241 LinkNode *node = *listp;
242
243 nlink->link = ptr;
244
245 if (node) {
246 nlink->next = node->next;
247 node->next = nlink;
248 }
249 else {
250 nlink->next = NULL;
251 *listp = nlink;
252 }
253}
254
256{
257 while (list) {
258 LinkNode *next = list->next;
259
260 if (freefunc) {
261 freefunc(list->link);
262 }
263 MEM_freeN(list);
264
265 list = next;
266 }
267}
268
270{
271 while (list) {
272 LinkNode *next = list->next;
273
274 if (freefunc) {
275 freefunc(list->link);
276 }
277 BLI_mempool_free(mempool, list);
278
279 list = next;
280 }
281}
282
284{
285 while (list) {
286 LinkNode *next = list->next;
287
288 MEM_freeN(list->link);
289 MEM_freeN(list);
290
291 list = next;
292 }
293}
294
295void BLI_linklist_apply(LinkNode *list, LinkNodeApplyFP applyfunc, void *userdata)
296{
297 for (; list; list = list->next) {
298 applyfunc(list->link, userdata);
299 }
300}
301
302/* -------------------------------------------------------------------- */
303/* Sort */
304#define SORT_IMPL_LINKTYPE LinkNode
305#define SORT_IMPL_LINKTYPE_DATA link
306
307/* regular call */
308#define SORT_IMPL_FUNC linklist_sort_fn
309#include "list_sort_impl.h"
310#undef SORT_IMPL_FUNC
311
312/* re-entrant call */
313#define SORT_IMPL_USE_THUNK
314#define SORT_IMPL_FUNC linklist_sort_fn_r
315#include "list_sort_impl.h"
316#undef SORT_IMPL_FUNC
317#undef SORT_IMPL_USE_THUNK
318
319#undef SORT_IMPL_LINKTYPE
320#undef SORT_IMPL_LINKTYPE_DATA
321
322LinkNode *BLI_linklist_sort(LinkNode *list, int (*cmp)(const void *, const void *))
323{
324 if (list && list->next) {
325 list = linklist_sort_fn(list, cmp);
326 }
327 return list;
328}
329
331 int (*cmp)(void *, const void *, const void *),
332 void *thunk)
333{
334 if (list && list->next) {
335 list = linklist_sort_fn_r(list, cmp, thunk);
336 }
337 return list;
338}
#define BLI_assert(a)
Definition BLI_assert.h:50
void * BLI_memarena_alloc(struct MemArena *ma, size_t size) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_ALLOC_SIZE(2)
void * BLI_mempool_alloc(BLI_mempool *pool) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(1)
void BLI_mempool_free(BLI_mempool *pool, void *addr) ATTR_NONNULL(1
Read Guarded memory(de)allocation.
#define NULL
int len
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
static ulong * next
LinkNode * last_node
LinkNode * list
void * link
struct LinkNode * next
PointerRNA * ptr
Definition wm_files.cc:4126