libcstl
Loading...
Searching...
No Matches
dlist.h
Go to the documentation of this file.
1/*!
2 * @file
3 */
4
5#ifndef CSTL_DLIST_H
6#define CSTL_DLIST_H
7
8/*!
9 * @defgroup lists Linked lists
10 * @ingroup lowlevel
11 * @brief Collection of linked lists
12 */
13
14/*!
15 * @defgroup dlist Doubly-linked list
16 * @ingroup lists
17 * @brief A linked list allowing traversal in both directions
18 */
19/*!
20 * @addtogroup dlist
21 * @{
22 */
23
24#include "cstl/common.h"
25
26/*!
27 * @brief Node to anchor an element within a list
28 *
29 * Users of the list object declare this object within another
30 * object as follows:
31 * @code{.c}
32 * struct object {
33 * ...
34 * struct cstl_dlist_node node;
35 * ...
36 * };
37 * @endcode
38 *
39 * When calling cstl_dlist_init(), the caller passes the offset of @p node
40 * within their object as the @p off parameter of that function, e.g.
41 * @code{.c}
42 * offsetof(struct object, node)
43 * @endcode
44 */
46{
47 /*! @privatesection */
48 struct cstl_dlist_node * p, * n;
49};
50
51/*!
52 * @brief List object
53 *
54 * Callers declare or allocate an object of this type to instantiate
55 * a list. Users are encouraged to declare (and initialize) this
56 * object with the DECLARE_CSTL_DLIST() macro. Any other declaration or
57 * allocation must be initialized via cstl_dlist_init().
58 */
60{
61 /*! @privatesection */
62 struct cstl_dlist_node h;
63 size_t size;
64
65 size_t off;
66};
67
68/*!
69 * @brief Constant initialization of a list object
70 *
71 * @param NAME The name of the variable being initialized
72 * @param TYPE The type of object that the list will hold
73 * @param MEMB The name of the @p cstl_dlist_node member within @p TYPE.
74 *
75 * @see cstl_dlist_node for a description of the relationship between
76 * @p TYPE and @p MEMB
77 */
78#define CSTL_DLIST_INITIALIZER(NAME, TYPE, MEMB) \
79 { \
80 .h = { \
81 .p = &NAME.h, \
82 .n = &NAME.h, \
83 }, \
84 .size = 0, \
85 .off = offsetof(TYPE, MEMB), \
86 }
87/*!
88 * @brief (Statically) declare and initialize a list
89 *
90 * @param NAME The name of the variable being declared
91 * @param TYPE The type of object that the list will hold
92 * @param MEMB The name of the @p cstl_dlist_node member within @p TYPE.
93 *
94 * @see cstl_dlist_node for a description of the relationship between
95 * @p TYPE and @p MEMB
96 */
97#define DECLARE_CSTL_DLIST(NAME, TYPE, MEMB) \
98 struct cstl_dlist NAME = \
99 CSTL_DLIST_INITIALIZER(NAME, TYPE, MEMB)
100
101/*!
102 * @brief Initialize a list object
103 *
104 * @param[in,out] l A pointer to the object to be initialized
105 * @param[in] off The offset of the @p cstl_dlist_node object within the
106 * object(s) that will be stored in the list
107 */
108static inline void cstl_dlist_init(
109 struct cstl_dlist * const l, const size_t off)
110{
111 l->h.p = &l->h;
112 l->h.n = &l->h;
113
114 l->size = 0;
115
116 l->off = off;
117}
118
119/*!
120 * @brief Get the number of objects in the list
121 *
122 * @param[in] l A pointer to the list
123 *
124 * @return The number of objects in the list
125 */
126static inline size_t cstl_dlist_size(const struct cstl_dlist * const l)
127{
128 return l->size;
129}
130
131/*!
132 * @brief Insert a new object into the list
133 *
134 * @param[in] l A pointer to the list into which to insert the object
135 * @param[in] before A pointer to an object already in the list
136 * @param[in] obj A pointer to an object to insert into the list
137 *
138 * The new object will be inserted after the object pointed to by @p before
139 */
140void cstl_dlist_insert(struct cstl_dlist * l, void * before, void * obj);
141
142/*!
143 * @brief Remove an object from the list
144 *
145 * @param[in] l The list in which the object currently resides
146 * @param[in] obj A pointer to the object to be removed
147 */
148void cstl_dlist_erase(struct cstl_dlist * l, void * obj);
149
150/*!
151 * @brief Get a pointer to the first object in the list
152 *
153 * @param[in] l A pointer to a list
154 *
155 * @return A pointer to the first object in the list
156 * @retval NULL The list is empty
157 */
158void * cstl_dlist_front(struct cstl_dlist * l);
159/*!
160 * @brief Get a pointer to the last object in the list
161 *
162 * @param[in] l A pointer to a list
163 *
164 * @return A pointer to the last object in the list
165 * @retval NULL The list is empty
166 */
167void * cstl_dlist_back(struct cstl_dlist * l);
168
169/*!
170 * @brief Insert a new object at the front of the list
171 *
172 * @param[in] l A pointer to a list
173 * @param[in] obj A pointer to the object to be inserted
174 */
175void cstl_dlist_push_front(struct cstl_dlist * l, void * obj);
176/*!
177 * @brief Insert a new object at the back of the list
178 *
179 * @param[in] l A pointer to a list
180 * @param[in] obj A pointer to the object to be inserted
181 */
182void cstl_dlist_push_back(struct cstl_dlist * l, void * obj);
183
184/*!
185 * @brief Remove the first item in the list and return it
186 *
187 * @param[in] l A pointer to a list
188 *
189 * @return A pointer to the removed object
190 * @retval NULL The list was empty and no object was removed
191 */
192void * cstl_dlist_pop_front(struct cstl_dlist * l);
193/*!
194 * @brief Remove the last item in the list and return it
195 *
196 * @param[in] l A pointer to a list
197 *
198 * @return A pointer to the removed object
199 * @retval NULL The list was empty and no object was removed
200 */
201void * cstl_dlist_pop_back(struct cstl_dlist * l);
202
203/*!
204 * @brief Reverse the order of items in the list
205 *
206 * @param[in] l A pointer to the list
207 */
208void cstl_dlist_reverse(struct cstl_dlist * l);
209/*!
210 * @brief Sort the items in a list
211 *
212 * @param[in] l A pointer to the list
213 * @param[in] cmp A pointer to a function to compare objects
214 * @param[in] priv A pointer to be passed to each invocation
215 * of the comparison function
216 *
217 * The items are sorted from least to greatest, according to the provided
218 * comparison function.
219 */
220void cstl_dlist_sort(struct cstl_dlist * l,
221 cstl_compare_func_t * cmp, void * priv);
222
223/*!
224 * @brief Append one list to the end of another
225 *
226 * @param[in] list The list to which to append more objects
227 * @param[in] more The list of objects to append
228 *
229 * Upon return @p list will have all of the objects from @p more
230 * appended to its end.
231 */
232void cstl_dlist_concat(struct cstl_dlist * list, struct cstl_dlist * more);
233
234/*!
235 * @brief The direction in which to traverse the list
236 * during cstl_dlist_foreach()
237 */
238typedef enum
239{
240 /*! @brief Traverse the list from front to back */
242 /*! @brief Traverse the list from back to front */
245
246/*!
247 * @brief Call a user-supplied function for each object in a list
248 *
249 * @param[in] l The list containing the objects to visit
250 * @param[in] visit A pointer to the function to call for each object
251 * @param[in] priv A pointer to be passed to each invocation of the function
252 * @param[in] dir The direction in which to traverse the list
253 *
254 * The user-supplied function must return 0 in order to continue visiting
255 * objects in the list. The visiting of objects will stop at the first
256 * occurrence of a non-zero return from the visit function.
257 *
258 * @return The value returned from the user-supplied function from the
259 * last object visited or 0
260 */
261int cstl_dlist_foreach(struct cstl_dlist * l,
262 cstl_visit_func_t * visit, void * priv,
264
265/*!
266 * @brief Perform a linear search for an object
267 *
268 * @param[in] l The list to be searched
269 * @param[in] obj A pointer to an object to search for in the list
270 * @param[in] cmp A function to compare objects in the list
271 * @param[in] priv A pointer to be passed to each invocation
272 * of the compare function
273 * @param[in] dir The direction in which to traverse/search the list
274 *
275 * The function will traverse the list in the specified direction, comparing
276 * the user-supplied object with objects in the list. When the comparison
277 * function returns 0, the associated object is returned.
278 *
279 * @return A pointer to the sought object
280 * @retval NULL The sought object was not found
281 */
282void * cstl_dlist_find(const struct cstl_dlist * l,
283 const void * obj, cstl_compare_func_t * cmp, void * priv,
285
286/*!
287 * @brief Remove objects from and reinitialize a list
288 *
289 * @param[in] l The list to be cleared
290 * @param[in] clr The function to be called for each object in the list
291 *
292 * All objects are removed from the list and the @p clr function is
293 * called for each object that was in the list. The order in which
294 * the objects are removed and @p clr is called is not specified, but
295 * the callee may take ownership of an object at the time that @p clr
296 * is called for that object and not before.
297 *
298 * Upon return from this function, the list contains no objects, and it
299 * is as it was immediately after being initialized. No further operations
300 * on the list are necessary to make it ready to go out of scope or be
301 * destroyed.
302 */
303void cstl_dlist_clear(struct cstl_dlist * l, cstl_xtor_func_t * clr);
304
305/*!
306 * @brief Swap the list objects at the two given locations
307 *
308 * @param[in,out] a A pointer to a list
309 * @param[in,out] b A pointer to a(nother) list
310 *
311 * The lists at the given locations will be swapped such that upon return,
312 * @p a will contain the list previously pointed to by @p b and vice versa.
313 */
314void cstl_dlist_swap(struct cstl_dlist * a, struct cstl_dlist * b);
315
316/*!
317 * @}
318 */
319
320#endif
void cstl_xtor_func_t(void *obj, void *priv)
Type for functions called to construct, clear, or destroy an object.
Definition common.h:97
int cstl_visit_func_t(void *obj, void *priv)
Type for visit callbacks from objects supporting foreach.
Definition common.h:65
int cstl_compare_func_t(const void *obj1, const void *obj2, void *priv)
Function type for comparing (in)equality of two objects.
Definition common.h:49
static void cstl_dlist_init(struct cstl_dlist *const l, const size_t off)
Initialize a list object.
Definition dlist.h:108
void * cstl_dlist_front(struct cstl_dlist *l)
Get a pointer to the first object in the list.
Definition dlist.c:75
void cstl_dlist_reverse(struct cstl_dlist *l)
Reverse the order of items in the list.
Definition dlist.c:219
void cstl_dlist_clear(struct cstl_dlist *l, cstl_xtor_func_t *clr)
Remove objects from and reinitialize a list.
Definition dlist.c:207
void * cstl_dlist_pop_front(struct cstl_dlist *l)
Remove the first item in the list and return it.
Definition dlist.c:101
void cstl_dlist_erase(struct cstl_dlist *l, void *obj)
Remove an object from the list.
Definition dlist.c:70
static size_t cstl_dlist_size(const struct cstl_dlist *const l)
Get the number of objects in the list.
Definition dlist.h:126
void cstl_dlist_swap(struct cstl_dlist *a, struct cstl_dlist *b)
Swap the list objects at the two given locations.
Definition dlist.c:184
void cstl_dlist_concat(struct cstl_dlist *list, struct cstl_dlist *more)
Append one list to the end of another.
Definition dlist.c:272
void * cstl_dlist_find(const struct cstl_dlist *l, const void *obj, cstl_compare_func_t *cmp, void *priv, cstl_dlist_foreach_dir_t dir)
Perform a linear search for an object.
Definition dlist.c:165
void * cstl_dlist_pop_back(struct cstl_dlist *l)
Remove the last item in the list and return it.
Definition dlist.c:109
void cstl_dlist_push_front(struct cstl_dlist *l, void *obj)
Insert a new object at the front of the list.
Definition dlist.c:91
cstl_dlist_foreach_dir_t
The direction in which to traverse the list during cstl_dlist_foreach()
Definition dlist.h:239
void cstl_dlist_push_back(struct cstl_dlist *l, void *obj)
Insert a new object at the back of the list.
Definition dlist.c:96
int cstl_dlist_foreach(struct cstl_dlist *l, cstl_visit_func_t *visit, void *priv, cstl_dlist_foreach_dir_t dir)
Call a user-supplied function for each object in a list.
Definition dlist.c:117
void * cstl_dlist_back(struct cstl_dlist *l)
Get a pointer to the last object in the list.
Definition dlist.c:83
void cstl_dlist_sort(struct cstl_dlist *l, cstl_compare_func_t *cmp, void *priv)
Sort the items in a list.
Definition dlist.c:292
void cstl_dlist_insert(struct cstl_dlist *l, void *before, void *obj)
Insert a new object into the list.
Definition dlist.c:52
@ CSTL_DLIST_FOREACH_DIR_FWD
Traverse the list from front to back.
Definition dlist.h:241
@ CSTL_DLIST_FOREACH_DIR_REV
Traverse the list from back to front.
Definition dlist.h:243
Node to anchor an element within a list.
Definition dlist.h:46
List object.
Definition dlist.h:60