19#define restrict __restrict__
36#define PASTE(a, b) a##b
44#define XPASTE(a, b) PASTE(a, b)
52#define JOIN(a, b) XPASTE(a, XPASTE(_, b))
63#error "Must define NAME."
64#define FUNCTION_DEFINITIONS
65#define TYPE_DEFINITIONS
74#ifndef FUNCTION_LINKAGE
75#define FUNCTION_LINKAGE
79#define LIST_NODE_TYPE struct JOIN(LIST_NAME, node)
80#define LIST_NODE_ADD_BETWEEN JOIN(JOIN(internal, LIST_NAME), node_add_between)
81#define LIST_NODE_ATTACH JOIN(JOIN(internal, LIST_NAME), node_attach)
82#define LIST_NODE_INIT JOIN(LIST_NAME, node_init)
83#define LIST_NODE_IS_SINGULAR JOIN(LIST_NAME, node_is_singular)
94#define LIST_FOR_EACH(node_ptr, head_ptr) \
95 for ((node_ptr) = (head_ptr)->next_ptr; (node_ptr) != (head_ptr); (node_ptr) = (node_ptr)->next_ptr)
105#ifndef LIST_FOR_EACH_REVERSE
106#define LIST_FOR_EACH_REVERSE(node_ptr, head_ptr) \
107 for ((node_ptr) = (head_ptr)->prev_ptr; (node_ptr) != (head_ptr); (node_ptr) = (node_ptr)->prev_ptr)
118#ifndef LIST_FOR_EACH_SAFE
119#define LIST_FOR_EACH_SAFE(node_ptr, next_ptr, head_ptr) \
120 for ((node_ptr) = (head_ptr)->next_ptr, (next_ptr) = (node_ptr)->next_ptr; (node_ptr) != (head_ptr); \
121 (node_ptr) = (next_ptr), (next_ptr) = (node_ptr)->next_ptr)
132#ifndef LIST_FOR_EACH_REVERSE_SAFE
133#define LIST_FOR_EACH_REVERSE_SAFE(node_ptr, prev_ptr, head_ptr) \
134 for ((node_ptr) = (head_ptr)->prev_ptr, (prev_ptr) = (node_ptr)->prev_ptr; (node_ptr) != (head_ptr); \
135 (node_ptr) = (prev_ptr), (prev_ptr) = (node_ptr)->prev_ptr)
142struct JOIN(LIST_NAME, node);
148#ifdef TYPE_DEFINITIONS
181FUNCTION_LINKAGE bool JOIN(LIST_NAME, node_is_first)(
const LIST_NODE_TYPE *head_ptr,
const LIST_NODE_TYPE *node_ptr);
194FUNCTION_LINKAGE bool JOIN(LIST_NAME, node_is_last)(
const LIST_NODE_TYPE *head_ptr,
const LIST_NODE_TYPE *node_ptr);
213FUNCTION_LINKAGE void JOIN(LIST_NAME, node_add_after)(LIST_NODE_TYPE *prev_ptr, LIST_NODE_TYPE *node_ptr);
223FUNCTION_LINKAGE void JOIN(LIST_NAME, node_add_before)(LIST_NODE_TYPE *next_ptr, LIST_NODE_TYPE *node_ptr);
244FUNCTION_LINKAGE void JOIN(LIST_NAME, node_replace)(LIST_NODE_TYPE *restrict old_ptr, LIST_NODE_TYPE *restrict new_ptr);
254#ifdef FUNCTION_DEFINITIONS
261static inline void JOIN(
JOIN(internal, LIST_NAME), node_add_between)(LIST_NODE_TYPE *node_ptr,
262 LIST_NODE_TYPE *before_ptr,
263 LIST_NODE_TYPE *after_ptr)
265 before_ptr->next_ptr = node_ptr;
266 node_ptr->prev_ptr = before_ptr;
268 after_ptr->prev_ptr = node_ptr;
269 node_ptr->next_ptr = after_ptr;
273static inline void JOIN(
JOIN(internal, LIST_NAME), node_attach)(LIST_NODE_TYPE *prev_ptr, LIST_NODE_TYPE *next_ptr)
275 prev_ptr->next_ptr = next_ptr;
276 next_ptr->prev_ptr = prev_ptr;
283 assert(node_ptr != NULL);
285 node_ptr->prev_ptr = node_ptr->next_ptr = node_ptr;
288FUNCTION_LINKAGE bool JOIN(LIST_NAME, node_is_first)(
const LIST_NODE_TYPE *head_ptr,
const LIST_NODE_TYPE *node_ptr)
290 assert(head_ptr != NULL);
291 assert(node_ptr != NULL);
293 return node_ptr->prev_ptr == head_ptr;
296FUNCTION_LINKAGE bool JOIN(LIST_NAME, node_is_last)(
const LIST_NODE_TYPE *head_ptr,
const LIST_NODE_TYPE *node_ptr)
298 assert(head_ptr != NULL);
299 assert(node_ptr != NULL);
301 return node_ptr->next_ptr == head_ptr;
306 assert(node_ptr != NULL);
308 return node_ptr->prev_ptr == node_ptr && node_ptr->next_ptr == node_ptr;
313 assert(prev_ptr != NULL);
314 assert(node_ptr != NULL);
315 assert(LIST_NODE_IS_SINGULAR(node_ptr));
317 LIST_NODE_ADD_BETWEEN(node_ptr, prev_ptr, prev_ptr->next_ptr);
322 assert(next_ptr != NULL);
323 assert(node_ptr != NULL);
324 assert(LIST_NODE_IS_SINGULAR(node_ptr));
326 LIST_NODE_ADD_BETWEEN(node_ptr, next_ptr->prev_ptr, next_ptr);
331 assert(node_ptr != NULL);
332 assert(!LIST_NODE_IS_SINGULAR(node_ptr));
334 LIST_NODE_ATTACH(node_ptr->prev_ptr, node_ptr->next_ptr);
335 LIST_NODE_INIT(node_ptr);
340FUNCTION_LINKAGE void JOIN(LIST_NAME, node_replace)(LIST_NODE_TYPE *restrict old_ptr, LIST_NODE_TYPE *restrict new_ptr)
342 assert(old_ptr != NULL);
343 assert(new_ptr != NULL);
344 assert(!LIST_NODE_IS_SINGULAR(old_ptr));
345 assert(LIST_NODE_IS_SINGULAR(new_ptr));
347 LIST_NODE_ADD_BETWEEN(new_ptr, old_ptr->prev_ptr, old_ptr->next_ptr);
348 LIST_NODE_INIT(old_ptr);
357#undef FUNCTION_LINKAGE
358#undef FUNCTION_DEFINITIONS
359#undef TYPE_DEFINITIONS
363#undef LIST_NODE_ADD_BETWEEN
364#undef LIST_NODE_ATTACH
366#undef LIST_NODE_IS_SINGULAR
#define FUNCTION_LINKAGE
Specify function linkage e.g. static inline.
Definition fstack_template.h:145
#define JOIN(a, b)
First expand tokens, then paste them together with a _ in between.
Definition fstack_template.h:50
#define JOIN(a, b)
First expand tokens, then paste them together with a _ in between.
Definition list_template.h:52
list_node_type * next_ptr
next node pointer.
Definition list_template.h:155
list_node_type * prev_ptr
prev node pointer.
Definition list_template.h:154