18#ifndef __R_LIST_INTERNAL_H__
19#define __R_LIST_INTERNAL_H__
32#define R__LIST_DECL(RTYPE, RTYPE_LOW, RDATA, FUNCSPECS) \
33typedef struct _##RTYPE RTYPE; \
34FUNCSPECS RTYPE * RTYPE_LOW##_first (RTYPE * lst); \
35FUNCSPECS RTYPE * RTYPE_LOW##_last (RTYPE * lst); \
36FUNCSPECS RTYPE * RTYPE_LOW##_nth (RTYPE * lst, rsize n); \
37FUNCSPECS rsize RTYPE_LOW##_len (RTYPE * lst); \
38FUNCSPECS rboolean RTYPE_LOW##_contains_full (RTYPE * lst, RDATA data); \
39FUNCSPECS void RTYPE_LOW##_foreach (RTYPE * lst, RFunc func, rpointer user); \
40FUNCSPECS RTYPE * RTYPE_LOW##_alloc0 (void) R_ATTR_MALLOC; \
41FUNCSPECS RTYPE * RTYPE_LOW##_alloc_copy (RDATA data) R_ATTR_MALLOC; \
42FUNCSPECS RTYPE * RTYPE_LOW##_prepend_link (RTYPE * lst, RTYPE * entry) R_ATTR_WARN_UNUSED_RESULT; \
43FUNCSPECS RTYPE * RTYPE_LOW##_append_link (RTYPE * lst, RTYPE * entry) R_ATTR_WARN_UNUSED_RESULT; \
44FUNCSPECS RTYPE * RTYPE_LOW##_prepend_copy (RTYPE * lst, RDATA data) R_ATTR_WARN_UNUSED_RESULT; \
45FUNCSPECS RTYPE * RTYPE_LOW##_append_copy (RTYPE * lst, RDATA data) R_ATTR_WARN_UNUSED_RESULT; \
46FUNCSPECS RTYPE * RTYPE_LOW##_insert_after (RTYPE * head, RTYPE * entry, RDATA data) R_ATTR_WARN_UNUSED_RESULT; \
47FUNCSPECS RTYPE * RTYPE_LOW##_insert_before (RTYPE * head, RTYPE * entry, RDATA data) R_ATTR_WARN_UNUSED_RESULT;\
48FUNCSPECS void RTYPE_LOW##_free1 (RTYPE * lst); \
49FUNCSPECS void RTYPE_LOW##_free1_full (RTYPE * lst, RDestroyNotify notify); \
50FUNCSPECS RTYPE * RTYPE_LOW##_remove (RTYPE * head, RDATA data) R_ATTR_WARN_UNUSED_RESULT; \
51FUNCSPECS RTYPE * RTYPE_LOW##_remove_link (RTYPE * head, RTYPE * entry) R_ATTR_WARN_UNUSED_RESULT; \
52FUNCSPECS RTYPE * RTYPE_LOW##_destroy_link (RTYPE * head, RTYPE * entry) R_ATTR_WARN_UNUSED_RESULT; \
53FUNCSPECS void RTYPE_LOW##_destroy (RTYPE * head); \
54FUNCSPECS void RTYPE_LOW##_destroy_full (RTYPE * head, RDestroyNotify notify);\
61#define R__LIST_IMPL(RTYPE, RTYPE_LOW, RDATA, RREF, FUNCSPECS) \
62FUNCSPECS RTYPE * RTYPE_LOW##_first (RTYPE * lst) \
64 if (lst != NULL) while (lst->prev != NULL) lst = lst->prev; \
67FUNCSPECS RTYPE * RTYPE_LOW##_last (RTYPE * lst) \
69 if (lst != NULL) while (lst->next != NULL) lst = lst->next; \
72FUNCSPECS RTYPE * RTYPE_LOW##_nth (RTYPE * lst, rsize n) \
74 while (n-- > 0 && lst != NULL) lst = lst->next; \
77FUNCSPECS rsize RTYPE_LOW##_len (RTYPE * lst) \
82 for (it = lst->next; it != NULL; it = it->next) ret++; \
83 for (it = lst->prev; it != NULL; it = it->prev) ret++; \
88FUNCSPECS rboolean RTYPE_LOW##_contains_full (RTYPE * lst, RDATA data) \
92 for (it = lst; it != NULL; it = it->next) { \
93 if (RTYPE_LOW##_data_equal (&it->data, &data)) \
96 for (it = lst->prev; it != NULL; it = it->prev) { \
97 if (RTYPE_LOW##_data_equal (&it->data, &data)) \
103FUNCSPECS void RTYPE_LOW##_foreach (RTYPE * lst, RFunc func, rpointer user) \
105 for (; lst != NULL; lst = lst->next) \
106 func (RREF lst->data, user); \
108FUNCSPECS RTYPE * RTYPE_LOW##_alloc0 (void) \
110 return r_mem_new0 (RTYPE); \
112FUNCSPECS RTYPE * RTYPE_LOW##_alloc_copy (RDATA data) \
115 if ((ret = r_mem_new (RTYPE)) != NULL) { \
117 ret->next = ret->prev = NULL; \
121FUNCSPECS RTYPE * RTYPE_LOW##_prepend_link (RTYPE * lst, RTYPE * entry) \
123 if ((entry->next = RTYPE_LOW##_first (lst)) != NULL) \
124 entry->next->prev = entry; \
127FUNCSPECS RTYPE * RTYPE_LOW##_append_link (RTYPE * lst, RTYPE * entry) \
130 RTYPE * last = RTYPE_LOW##_last (lst); \
131 last->next = entry; \
132 entry->prev = last; \
137FUNCSPECS RTYPE * RTYPE_LOW##_prepend_copy (RTYPE * lst, RDATA data) \
139 return RTYPE_LOW##_prepend_link (lst, RTYPE_LOW##_alloc_copy (data)); \
141FUNCSPECS RTYPE * RTYPE_LOW##_append_copy (RTYPE * lst, RDATA data) \
143 return RTYPE_LOW##_append_link (lst, RTYPE_LOW##_alloc_copy (data)); \
145FUNCSPECS RTYPE * RTYPE_LOW##_insert_after (RTYPE * head, RTYPE * entry, RDATA data) \
147 RTYPE * lst = RTYPE_LOW##_alloc_copy (data); \
148 if (R_UNLIKELY (head == NULL)) return lst; \
149 if (entry == NULL) entry = head; \
150 lst->next = entry->next; \
152 if (entry->next != NULL) entry->next->prev = lst; \
156FUNCSPECS RTYPE * RTYPE_LOW##_insert_before (RTYPE * head, RTYPE * entry, RDATA data) \
158 RTYPE * lst = RTYPE_LOW##_alloc_copy (data); \
159 if (head != NULL && entry != NULL && entry != head) { \
160 lst->prev = entry->prev; \
162 entry->prev->next = lst; \
165 head = RTYPE_LOW##_prepend_link (head, lst); \
169FUNCSPECS void RTYPE_LOW##_free1 (RTYPE * lst) \
171 RTYPE_LOW##_clear (lst); \
174FUNCSPECS void RTYPE_LOW##_free1_full (RTYPE * lst, RDestroyNotify notify) \
177 if (notify != NULL) notify (RREF lst->data); \
178 RTYPE_LOW##_free1 (lst); \
181FUNCSPECS RTYPE * RTYPE_LOW##_remove (RTYPE * head, RDATA data) \
184 for (it = head; it != NULL; it = it->next) { \
185 if (RTYPE_LOW##_data_equal (&it->data, &data)) \
186 return RTYPE_LOW##_destroy_link (head, it); \
190FUNCSPECS RTYPE * RTYPE_LOW##_remove_link (RTYPE * head, RTYPE * entry) \
192 if (entry != NULL) { \
193 RTYPE * next = entry->next; \
194 RTYPE * prev = entry->prev; \
195 if (head == entry) head = head->next; \
196 if (prev != NULL) prev->next = entry->next; \
197 if (next != NULL) next->prev = entry->prev; \
201FUNCSPECS RTYPE * RTYPE_LOW##_destroy_link (RTYPE * head, RTYPE * entry) \
203 head = RTYPE_LOW##_remove_link (head, entry); \
204 RTYPE_LOW##_free1 (entry); \
207FUNCSPECS void RTYPE_LOW##_destroy (RTYPE * head) \
209 if (head != NULL) { \
210 RTYPE * it, * next; \
211 for (it = head->next; it != NULL; it = next) { \
213 RTYPE_LOW##_free1 (it); \
215 for (it = head->prev; it != NULL; it = next) { \
217 RTYPE_LOW##_free1 (it); \
219 RTYPE_LOW##_free1 (head); \
222FUNCSPECS void RTYPE_LOW##_destroy_full (RTYPE * head, RDestroyNotify notify) \
224 if (head != NULL) { \
225 RTYPE * it, * next; \
226 for (it = head->next; it != NULL; it = next) { \
228 RTYPE_LOW##_free1_full (it, notify); \
230 for (it = head->prev; it != NULL; it = next) { \
232 RTYPE_LOW##_free1_full (it, notify); \
234 RTYPE_LOW##_free1_full (head, notify); \
241#define R__SLIST_DECL(RTYPE, RTYPE_LOW, RDATA, FUNCSPECS) \
242typedef struct _##RTYPE RTYPE; \
243FUNCSPECS RTYPE * RTYPE_LOW##_last (RTYPE * lst); \
244FUNCSPECS RTYPE * RTYPE_LOW##_nth (RTYPE * lst, rsize n); \
245FUNCSPECS RTYPE * RTYPE_LOW##_copy (RTYPE * lst); \
246FUNCSPECS RTYPE * RTYPE_LOW##_merge (RTYPE * a, RTYPE * b); \
247FUNCSPECS rsize RTYPE_LOW##_len (RTYPE * lst); \
248FUNCSPECS rboolean RTYPE_LOW##_contains_full (RTYPE * lst, RDATA data); \
249FUNCSPECS void RTYPE_LOW##_foreach (RTYPE * lst, RFunc func, rpointer user); \
250FUNCSPECS rsize RTYPE_LOW##_foreach_remove (RTYPE ** head, \
251 RFuncReturn func, rpointer user); \
252FUNCSPECS RTYPE * RTYPE_LOW##_alloc0 (void) R_ATTR_MALLOC; \
253FUNCSPECS RTYPE * RTYPE_LOW##_alloc_copy (RDATA data) R_ATTR_MALLOC; \
254FUNCSPECS RTYPE * RTYPE_LOW##_prepend_link (RTYPE * lst, RTYPE * entry) R_ATTR_WARN_UNUSED_RESULT; \
255FUNCSPECS RTYPE * RTYPE_LOW##_append_link (RTYPE * lst, RTYPE * entry) R_ATTR_WARN_UNUSED_RESULT; \
256FUNCSPECS RTYPE * RTYPE_LOW##_prepend_copy (RTYPE * lst, RDATA data) R_ATTR_WARN_UNUSED_RESULT; \
257FUNCSPECS RTYPE * RTYPE_LOW##_append_copy (RTYPE * lst, RDATA data) R_ATTR_WARN_UNUSED_RESULT; \
258FUNCSPECS RTYPE * RTYPE_LOW##_insert_after (RTYPE * head, RTYPE * entry, RDATA data) R_ATTR_WARN_UNUSED_RESULT; \
259FUNCSPECS void RTYPE_LOW##_free1 (RTYPE * lst); \
260FUNCSPECS void RTYPE_LOW##_free1_full (RTYPE * lst, RDestroyNotify notify); \
261FUNCSPECS RTYPE * RTYPE_LOW##_remove (RTYPE * head, RDATA data) R_ATTR_WARN_UNUSED_RESULT; \
262FUNCSPECS RTYPE * RTYPE_LOW##_remove_link (RTYPE * head, RTYPE * entry) R_ATTR_WARN_UNUSED_RESULT; \
263FUNCSPECS RTYPE * RTYPE_LOW##_destroy_link (RTYPE * head, RTYPE * entry) R_ATTR_WARN_UNUSED_RESULT; \
264FUNCSPECS void RTYPE_LOW##_destroy (RTYPE * head); \
265FUNCSPECS void RTYPE_LOW##_destroy_full (RTYPE * head, RDestroyNotify notify);\
271#define R__SLIST_IMPL(RTYPE, RTYPE_LOW, RDATA, RREF, FUNCSPECS) \
272FUNCSPECS RTYPE * RTYPE_LOW##_last (RTYPE * lst) \
274 if (lst != NULL) while (lst->next != NULL) lst = lst->next; \
277FUNCSPECS RTYPE * RTYPE_LOW##_nth (RTYPE * lst, rsize n) \
279 while (n-- > 0 && lst != NULL) lst = lst->next; \
282FUNCSPECS RTYPE * RTYPE_LOW##_copy (RTYPE * lst) \
284 RTYPE * ret, * last; \
285 if (R_UNLIKELY (lst == NULL)) return NULL; \
286 ret = last = RTYPE_LOW##_alloc_copy (lst->data); \
287 for (lst = lst->next; lst != NULL; lst = lst->next, last = last->next) \
288 last->next = RTYPE_LOW##_alloc_copy (lst->data); \
291FUNCSPECS RTYPE * RTYPE_LOW##_merge (RTYPE * a, RTYPE * b) \
294 RTYPE_LOW##_last (a)->next = b; \
299FUNCSPECS rsize RTYPE_LOW##_len (RTYPE * lst) \
302 for (; lst != NULL; lst = lst->next) ret++; \
305FUNCSPECS rboolean RTYPE_LOW##_contains_full (RTYPE * lst, RDATA data) \
307 for (; lst != NULL; lst = lst->next) { \
308 if (RTYPE_LOW##_data_equal (&lst->data, &data)) \
313FUNCSPECS void RTYPE_LOW##_foreach (RTYPE * lst, RFunc func, rpointer user) \
315 for (; lst != NULL; lst = lst->next) \
316 func (RREF lst->data, user); \
318FUNCSPECS RTYPE * RTYPE_LOW##_alloc0 (void) \
320 return r_mem_new0 (RTYPE); \
322FUNCSPECS RTYPE * RTYPE_LOW##_alloc_copy (RDATA data) \
325 if ((ret = r_mem_new (RTYPE)) != NULL) { \
331FUNCSPECS RTYPE * RTYPE_LOW##_prepend_link (RTYPE * lst, RTYPE * entry) \
336FUNCSPECS RTYPE * RTYPE_LOW##_append_link (RTYPE * lst, RTYPE * entry) \
339 RTYPE * last = RTYPE_LOW##_last (lst); \
340 last->next = entry; \
345FUNCSPECS RTYPE * RTYPE_LOW##_prepend_copy (RTYPE * lst, RDATA data) \
347 return RTYPE_LOW##_prepend_link (lst, RTYPE_LOW##_alloc_copy (data)); \
349FUNCSPECS RTYPE * RTYPE_LOW##_append_copy (RTYPE * lst, RDATA data) \
351 return RTYPE_LOW##_append_link (lst, RTYPE_LOW##_alloc_copy (data)); \
353FUNCSPECS RTYPE * RTYPE_LOW##_insert_after (RTYPE * head, RTYPE * entry, RDATA data) \
355 RTYPE * lst = RTYPE_LOW##_alloc_copy (data); \
356 if (R_UNLIKELY (head == NULL)) return lst; \
357 if (entry == NULL) entry = head; \
358 lst->next = entry->next; \
362FUNCSPECS void RTYPE_LOW##_free1 (RTYPE * lst) \
364 RTYPE_LOW##_clear (lst); \
367FUNCSPECS void RTYPE_LOW##_free1_full (RTYPE * lst, RDestroyNotify notify) \
370 if (notify != NULL) notify (RREF lst->data); \
371 RTYPE_LOW##_free1 (lst); \
374FUNCSPECS RTYPE * RTYPE_LOW##_remove (RTYPE * head, RDATA data) \
376 RTYPE * ret = head, * prev; \
377 for (prev = NULL; head != NULL; head = head->next) { \
378 if (RTYPE_LOW##_data_equal (&head->data, &data)) { \
379 if (ret == head) ret = ret->next; \
380 if (prev != NULL) prev->next = head->next; \
381 RTYPE_LOW##_free1 (head); \
388FUNCSPECS RTYPE * RTYPE_LOW##_remove_link (RTYPE * head, RTYPE * entry) \
391 if (R_UNLIKELY (head == NULL || entry == NULL)) return head; \
392 if (head == entry) return head->next; \
393 for (it = head; it->next != NULL; it = it->next) { \
394 if (it->next == entry) { \
395 it->next = entry->next; \
401FUNCSPECS rsize RTYPE_LOW##_foreach_remove (RTYPE ** head, \
402 RFuncReturn func, rpointer user) \
405 RTYPE * it, * prev; \
406 for (it = *head, prev = NULL; it != NULL; prev = it, it = it->next) { \
407 if (func (RREF it->data, user)) { \
409 prev->next = it->next; \
412 RTYPE_LOW##_free1 (it); \
418FUNCSPECS RTYPE * RTYPE_LOW##_destroy_link (RTYPE * head, RTYPE * entry) \
420 head = RTYPE_LOW##_remove_link (head, entry); \
421 RTYPE_LOW##_free1 (entry); \
424FUNCSPECS void RTYPE_LOW##_destroy (RTYPE * head) \
427 for (; head != NULL; head = next) { \
429 RTYPE_LOW##_free1 (head); \
432FUNCSPECS void RTYPE_LOW##_destroy_full (RTYPE * head, RDestroyNotify notify) \
435 for (; head != NULL; head = next) { \
437 RTYPE_LOW##_free1_full (head, notify); \
#define R_BEGIN_DECLS
Open an extern "C" block under C++ (no-op in C).
Definition rmacros.h:196
Memory allocation, byte-buffer operations, and pattern scanning.
Foundational type aliases used by every rlib header.