3 @brief singly linked list implementation
13 @addtogroup A_SLIST singly linked list
18 #define A_SLIST_NODE {A_NULL}
19 #define A_SLIST_INIT(list) {{A_NULL}, &(list).head}
23 @brief instance structure for singly linked list node
25 typedef struct a_slist_node
27 struct a_slist_node
*next
;
31 @brief cast a list pointer from another type pointer
32 @param[in] _ additional attributes of specified type
33 @param[in] x points to singly linked list node
34 @return a pointer to singly linked list node
36 #define a_slist_(_, x) a_cast_s(a_slist_node _, a_cast_s(void _, x))
39 @brief instance structure for singly linked list head
41 typedef struct a_slist
48 @brief access the struct for this entry
49 @param ptr the &a_slist_node pointer
50 @param type the type of the struct this is embedded in
51 @param member the name of the a_slist_node within the struct
53 #define a_slist_entry(ptr, type, member) a_container_of(ptr, type, member)
54 #define a_slist_entry_next(ptr, type, member) a_slist_entry((ptr)->next, type, member)
57 @brief iterate over a list
58 @param it the &a_slist_node to use as a loop counter
59 @param ctx points to singly linked list head
61 #define a_slist_foreach(it, ctx) \
62 for (a_slist_node *it = (ctx)->head.next; it; it = it->next)
65 @brief iterate over a list safe against removal of list entry
66 @param it the &a_slist_node to use as a loop counter
67 @param at another &a_slist_node to use as temporary storage
68 @param ctx points to singly linked list head
70 #define a_slist_forsafe(it, at, ctx) \
71 for (a_slist_node *at = &(ctx)->head, *it = at->next; \
72 it; at = it ? it : at, it = at->next)
75 @brief constructor for singly linked list head
76 @param[in,out] ctx points to singly linked list head
78 A_INTERN
void a_slist_ctor(a_slist
*ctx
)
80 ctx
->head
.next
= A_NULL
;
81 ctx
->tail
= &ctx
->head
;
85 @brief initialize for singly linked list head
86 @param[in,out] ctx points to singly linked list head
88 A_INTERN
void a_slist_init(a_slist
*ctx
)
90 ctx
->head
.next
= A_NULL
;
91 ctx
->tail
= &ctx
->head
;
95 @brief destructor for singly linked list head
96 @param[in,out] ctx points to singly linked list head
98 A_INTERN
void a_slist_dtor(a_slist
*ctx
)
100 ctx
->head
.next
= A_NULL
;
101 ctx
->tail
= &ctx
->head
;
105 @brief link head node and tail node
106 @param[in,out] head the head node of a list
107 @param[in,out] tail the tail node of a list
109 A_INTERN
void a_slist_link(a_slist_node
*head
, a_slist_node
*tail
) { head
->next
= tail
; }
112 @brief insert a node to a list
113 @param[in,out] ctx points to singly linked list head
114 @param[in] prev previous singly linked list node
115 @param[in] node a singly linked list node
117 A_INTERN
void a_slist_add(a_slist
*ctx
, a_slist_node
*prev
, a_slist_node
*node
)
119 if (!prev
->next
) { ctx
->tail
= node
; }
120 a_slist_link(node
, prev
->next
);
121 a_slist_link(prev
, node
);
125 @brief insert a node to a list head
126 @param[in,out] ctx points to singly linked list head
127 @param[in] node a singly linked list node
129 A_INTERN
void a_slist_add_head(a_slist
*ctx
, a_slist_node
*node
)
131 a_slist_add(ctx
, &ctx
->head
, node
);
135 @brief insert a node to a list tail
136 @param[in,out] ctx points to singly linked list head
137 @param[in] node a singly linked list node
139 A_INTERN
void a_slist_add_tail(a_slist
*ctx
, a_slist_node
*node
)
141 a_slist_link(ctx
->tail
, node
);
147 @brief delete a node from a list
148 @param[in,out] ctx points to singly linked list head
149 @param[in] prev previous singly linked list node
151 A_INTERN
void a_slist_del(a_slist
*ctx
, a_slist_node
*prev
)
153 a_slist_node
*const node
= prev
->next
;
156 a_slist_link(prev
, node
->next
);
157 if (!node
->next
) { ctx
->tail
= prev
; }
162 @brief delete a node from a list head
163 @param[in,out] ctx points to singly linked list head
165 A_INTERN
void a_slist_del_head(a_slist
*ctx
)
167 a_slist_node
*const node
= ctx
->head
.next
;
170 a_slist_link(&ctx
->head
, node
->next
);
171 if (!node
->next
) { ctx
->tail
= &ctx
->head
; }
176 @brief moving a list to another list
177 @param[in] ctx points to singly linked list head
178 @param[in,out] to another linked list to be inserted
179 @param[in] at the previous &a_slist_node of the inserted node
181 A_INTERN
void a_slist_mov(a_slist
*ctx
, a_slist
*to
, a_slist_node
*at
)
183 a_slist_node
*const node
= ctx
->head
.next
;
186 if (!at
->next
) { to
->tail
= ctx
->tail
; }
187 a_slist_link(ctx
->tail
, at
->next
);
188 a_slist_link(at
, node
);
193 @brief rotate a node in the list
194 @param[in,out] ctx points to singly linked list head
196 A_INTERN
void a_slist_rot(a_slist
*ctx
)
198 a_slist_node
*const node
= ctx
->head
.next
;
201 a_slist_link(&ctx
->head
, node
->next
);
202 a_slist_link(ctx
->tail
, node
);
210 #endif /* a/slist.h */