Freeciv-3.1: /fast/freeciv/nightly/S3_1/utility/speclist.h Source File

Freeciv-3.1

Loading...
Searching...
No Matches
speclist.h
Go to the documentation of this file.
1/**********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14/* speclists: "specific genlists", by dwp.
15 * (A generalisation of previous city_list and unit_list stuff.)
16 *
17 * This file is used to implement a "specific" genlist.
18 * That is, a (sometimes) type-checked genlist. (Or at least a
19 * genlist with related functions with distinctly typed parameters.)
20 * (Or, maybe, what you end up doing when you don't use C++ ?)
21 *
22 * Before including this file, you must define the following:
23 * SPECLIST_TAG - this tag will be used to form names for functions etc.
24 * You may also define:
25 * SPECLIST_TYPE - the typed genlist will contain pointers to this type;
26 * If SPECLIST_TYPE is not defined, then 'struct SPECLIST_TAG' is used.
27 * At the end of this file, these (and other defines) are undef-ed.
28 *
29 * Assuming SPECLIST_TAG were 'foo', and SPECLIST_TYPE were 'foo_t',
30 * including this file would provide a struct definition for:
31 * struct foo_list;
32 * struct foo_list_link;
33 *
34 * function typedefs:
35 * typedef void (*foo_list_free_fn_t) (foo_t *);
36 * typedef foo_t * (*foo_list_copy_fn_t) (const foo_t *);
37 * typedef bool (*foo_list_comp_fn_t) (const foo_t *, const foo_t *);
38 * typedef bool (*foo_list_cond_fn_t) (const foo_t *);
39 *
40 * and prototypes for the following functions:
41 * struct foo_list *foo_list_new(void);
42 * struct foo_list *foo_list_new_full(foo_list_free_fn_t free_data_func);
43 * void foo_list_destroy(struct foo_list *plist);
44 * struct foo_list *foo_list_copy(const struct foolist *plist);
45 * struct foo_list *foo_list_copy_full(const struct foolist *plist,
46 * foo_list_copy_fn_t copy_data_func,
47 * foo_list_free_fn_t free_data_func);
48 * void foo_list_clear(struct foo_list *plist);
49 * void foo_list_unique(struct foo_list *plist);
50 * void foo_list_unique_full(struct foo_list *plist,
51 * foo_list_comp_fn_t comp_data_func);
52 * void foo_list_append(struct foo_list *plist, foo_t *pfoo);
53 * void foo_list_prepend(struct foo_list *plist, foo_t *pfoo);
54 * void foo_list_insert(struct foo_list *plist, foo_t *pfoo, int idx);
55 * void foo_list_insert_after(struct foo_list *plist, foo_t *pfoo,
56 * struct foo_list_link *plink);
57 * void foo_list_insert_before(struct foo_list *plist, foo_t *pfoo,
58 * struct foo_list_link *plink);
59 * bool foo_list_remove(struct foo_list *plist, const foo_t *pfoo);
60 * bool foo_list_remove_if(struct foo_list *plist,
61 * foo_list_cond_fn_t cond_data_func);
62 * int foo_list_remove_all(struct foo_list *plist, const foo_t *pfoo);
63 * int foo_list_remove_all_if(struct foo_list *plist,
64 * foo_list_cond_fn_t cond_data_func);
65 * void foo_list_erase(struct foo_list *plist,
66 * struct foo_list_link *plink);
67 * void foo_list_pop_front(struct foo_list *plist);
68 * void foo_list_pop_back(struct foo_list *plist);
69 * int foo_list_size(const struct foo_list *plist);
70 * foo_t *foo_list_get(const struct foo_list *plist, int idx);
71 * foo_t *foo_list_front(const struct foo_list *plist);
72 * foo_t *foo_list_back(const struct foo_list *plist);
73 * struct foo_list_link *foo_list_link_get(const struct foo_list *plist,
74 * int idx);
75 * struct foo_list_link *foo_list_head(const struct foo_list *plist);
76 * struct foo_list_link *foo_list_tail(const struct foo_list *plist);
77 * struct foo_list_link *foo_list_search(const struct foo_list *plist,
78 * const void *data);
79 * struct foo_list_link *foo_list_search_if(const struct foo_list *plist,
80 * foo_list_cond_fn_t
81 * cond_data_func);
82 * void foo_list_sort(struct foo_list *plist,
83 * int (*compar) (const foo_t *const *, const foo_t *const *));
84 * void foo_list_shuffle(struct foo_list *plist);
85 * void foo_list_reverse(struct foo_list *plist);
86 * void foo_list_allocate_mutex(struct foo_list *plist);
87 * void foo_list_release_mutex(struct foo_list *plist);
88 * foo_t *foo_list_link_data(const struct foo_list_link *plink);
89 * struct foo_list_link *
90 * foo_list_link_prev(const struct foo_list_link *plink);
91 * struct foo_list_link *
92 * foo_list_link_next(const struct foo_list_link *plink);
93 *
94 * You should also define yourself (this file cannot do this for you):
95 * #define foo_list_iterate(foolist, pfoo) \
96 * TYPED_LIST_ITERATE(foo_t, foolist, pfoo)
97 * #define foo_list_iterate_end LIST_ITERATE_END
98 *
99 * #define foo_list_iterate_rev(foolist, pfoo) \
100 * TYPED_LIST_ITERATE_REV(foo_t, foolist, pfoo)
101 * #define foo_list_iterate_rev_end LIST_ITERATE_REV_END
102 *
103 * #define foo_list_link_iterate(foolist, plink) \
104 * TYPED_LIST_LINK_ITERATE(struct foo_list_link, foolist, plink)
105 * #define foo_list_link_iterate_end LIST_LINK_ITERATE_END
106 *
107 * #define foo_list_link_iterate_rev(foolist, plink) \
108 * TYPED_LIST_LINK_ITERATE_REV(struct foo_list_link, foolist, plink)
109 * #define foo_list_link_iterate_rev_end LIST_LINK_ITERATE_REV_END
110 *
111 * #define foo_list_both_iterate(foolist, plink, pfoo) \
112 * TYPED_LIST_BOTH_ITERATE(struct foo_list_link, foo_t, \
113 foolist, plink, pfoo)
114 * #define foo_list_both_iterate_end LIST_BOTH_ITERATE_END
115 *
116 * #define foo_list_both_iterate_rev(foolist, pfoo) \
117 * TYPED_LIST_BOTH_ITERATE_REV(struct foo_list_link, foo_t, \
118 foolist, plink, pfoo)
119 * #define foo_list_both_iterate_rev_end LIST_BOTH_ITERATE_REV_END
120 *
121 * Note this is not protected against multiple inclusions; this is so that
122 * you can have multiple different speclists. For each speclist, this file
123 * should be included _once_, inside a .h file which _is_ itself protected
124 * against multiple inclusions. */
125
126#ifdef __cplusplus
127extern "C" {
128#endif /* __cplusplus */
129
130#include "genlist.h"
131
132#ifndef SPECLIST_TAG
133#error Must define a SPECLIST_TAG to use this header
134#endif
135
136#ifndef SPECLIST_TYPE
137#define SPECLIST_TYPE struct SPECLIST_TAG
138#endif
139
140#define SPECLIST_PASTE_(x, y) x ## y
141#define SPECLIST_PASTE(x, y) SPECLIST_PASTE_(x,y)
142
143#define SPECLIST_LIST struct SPECLIST_PASTE(SPECLIST_TAG, _list)
144#define SPECLIST_LINK struct SPECLIST_PASTE(SPECLIST_TAG, _list_link)
145#define SPECLIST_FOO(suffix) SPECLIST_PASTE(SPECLIST_TAG, suffix)
146
147/* Dummy type. Actually a genlist, and not defined anywhere. */
148 SPECLIST_LIST;
149
150/* Dummy type. Actually a genlist_link, and not defined anywhere. */
151 SPECLIST_LINK;
152
153/* Function related typedefs. */
154 typedef void (*SPECLIST_FOO(_list_free_fn_t)) (SPECLIST_TYPE *);
155typedef SPECLIST_TYPE *
156(*SPECLIST_FOO(_list_copy_fn_t)) (const SPECLIST_TYPE *);
157typedef bool (*SPECLIST_FOO(_list_comp_fn_t)) (const SPECLIST_TYPE *,
158 const SPECLIST_TYPE *);
159typedef bool (*SPECLIST_FOO(_list_cond_fn_t)) (const SPECLIST_TYPE *);
160
161
162/****************************************************************************
163 Create a new speclist.
164****************************************************************************/
165static inline SPECLIST_LIST *SPECLIST_FOO(_list_new) (void)
166 fc__warn_unused_result;
167
168 static inline SPECLIST_LIST *SPECLIST_FOO(_list_new) (void)
169{
170 return (SPECLIST_LIST *) genlist_new();
171}
172
173/****************************************************************************
174 Create a new speclist with a free callback.
175****************************************************************************/
176static inline SPECLIST_LIST *
177 SPECLIST_FOO(_list_new_full) (SPECLIST_FOO(_list_free_fn_t) free_data_func)
178 fc__warn_unused_result;
179
180static inline SPECLIST_LIST *
181 SPECLIST_FOO(_list_new_full) (SPECLIST_FOO(_list_free_fn_t) free_data_func)
182{
183 return ((SPECLIST_LIST *)
184 genlist_new_full((genlist_free_fn_t) free_data_func));
185}
186
187/****************************************************************************
188 Free a speclist.
189****************************************************************************/
190 static inline void SPECLIST_FOO(_list_destroy) (SPECLIST_LIST *tthis)
191{
192 genlist_destroy((struct genlist *) tthis);
193}
194
195/****************************************************************************
196 Duplicate a speclist.
197****************************************************************************/
198static inline SPECLIST_LIST *
199 SPECLIST_FOO(_list_copy) (const SPECLIST_LIST *tthis)
200 fc__warn_unused_result;
201
202static inline SPECLIST_LIST *
203 SPECLIST_FOO(_list_copy) (const SPECLIST_LIST *tthis)
204{
205 return (SPECLIST_LIST *) genlist_copy((const struct genlist *) tthis);
206}
207
208/****************************************************************************
209 Duplicate a speclist with a free callback and a function to copy each
210 element.
211****************************************************************************/
212static inline SPECLIST_LIST *
213 SPECLIST_FOO(_list_copy_full) (const SPECLIST_LIST *tthis,
214 SPECLIST_FOO(_list_copy_fn_t) copy_data_func,
215 SPECLIST_FOO(_list_free_fn_t) free_data_func)
216 fc__warn_unused_result;
217
218static inline SPECLIST_LIST *
219 SPECLIST_FOO(_list_copy_full) (const SPECLIST_LIST *tthis,
220 SPECLIST_FOO(_list_copy_fn_t) copy_data_func,
221 SPECLIST_FOO(_list_free_fn_t) free_data_func)
222{
223 return ((SPECLIST_LIST *)
224 genlist_copy_full((const struct genlist *) tthis,
225 (genlist_copy_fn_t) copy_data_func,
226 (genlist_free_fn_t) free_data_func));
227}
228
229/****************************************************************************
230 Remove all elements from the speclist.
231****************************************************************************/
232 static inline void SPECLIST_FOO(_list_clear) (SPECLIST_LIST *tthis)
233{
234 genlist_clear((struct genlist *) tthis);
235}
236
237/****************************************************************************
238 Remove all element duplicates (the speclist must be sorted before).
239****************************************************************************/
240 static inline void SPECLIST_FOO(_list_unique) (SPECLIST_LIST *tthis)
241{
242 genlist_unique((struct genlist *) tthis);
243}
244
245/****************************************************************************
246 Remove all element duplicates (the speclist must be sorted before), using
247 'comp_data_func' to determine if the elements are equivalents.
248****************************************************************************/
249static inline void
250 SPECLIST_FOO(_list_unique_full) (SPECLIST_LIST *tthis,
251 SPECLIST_FOO(_list_comp_fn_t) comp_data_func)
252{
253 genlist_unique_full((struct genlist *) tthis,
254 (genlist_comp_fn_t) comp_data_func);
255}
256
257/****************************************************************************
258 Push back an element into the speclist.
259****************************************************************************/
260 static inline void SPECLIST_FOO(_list_append) (SPECLIST_LIST *tthis,
261 SPECLIST_TYPE *pfoo)
262{
263 genlist_append((struct genlist *) tthis, pfoo);
264}
265
266/****************************************************************************
267 Push front an element into the speclist.
268****************************************************************************/
269 static inline void SPECLIST_FOO(_list_prepend) (SPECLIST_LIST *tthis,
270 SPECLIST_TYPE *pfoo)
271{
272 genlist_prepend((struct genlist *) tthis, pfoo);
273}
274
275/****************************************************************************
276 Insert an element into the speclist at the given position.
277****************************************************************************/
278 static inline void SPECLIST_FOO(_list_insert) (SPECLIST_LIST *tthis,
279 SPECLIST_TYPE *pfoo, int idx)
280{
281 genlist_insert((struct genlist *) tthis, pfoo, idx);
282}
283
284/****************************************************************************
285 Insert an element after the specified link.
286****************************************************************************/
287 static inline void SPECLIST_FOO(_list_insert_after) (SPECLIST_LIST *tthis,
288 SPECLIST_TYPE *pfoo,
289 SPECLIST_LINK *plink)
290{
291 genlist_insert_after((struct genlist *) tthis, pfoo,
292 (struct genlist_link *) plink);
293}
294
295/****************************************************************************
296 Insert an element before the specified link.
297****************************************************************************/
298 static inline void SPECLIST_FOO(_list_insert_before) (SPECLIST_LIST *tthis,
299 SPECLIST_TYPE *pfoo,
300 SPECLIST_LINK *plink)
301{
302 genlist_insert_before((struct genlist *) tthis, pfoo,
303 (struct genlist_link *) plink);
304}
305
306/****************************************************************************
307 Search 'pfoo' in the speclist, and remove it. Returns TRUE on success.
308****************************************************************************/
309 static inline bool SPECLIST_FOO(_list_remove) (SPECLIST_LIST *tthis,
310 const SPECLIST_TYPE *pfoo)
311{
312 return genlist_remove((struct genlist *) tthis, pfoo);
313}
314
315/****************************************************************************
316 Remove the first element which fit the conditional function. Returns
317 TRUE on success.
318****************************************************************************/
319static inline bool
320 SPECLIST_FOO(_list_remove_if) (SPECLIST_LIST *tthis,
321 SPECLIST_FOO(_list_cond_fn_t) cond_data_func)
322{
323 return genlist_remove_if((struct genlist *) tthis,
324 (genlist_cond_fn_t) cond_data_func);
325}
326
327/****************************************************************************
328 Remove 'pfoo' of the whole list. Returns the number of removed elements.
329****************************************************************************/
330 static inline int SPECLIST_FOO(_list_remove_all) (SPECLIST_LIST *tthis,
331 const SPECLIST_TYPE *pfoo)
332{
333 return genlist_remove_all((struct genlist *) tthis, pfoo);
334}
335
336/****************************************************************************
337 Remove all elements which fit the conditional function. Returns the
338 number of removed elements.
339****************************************************************************/
340static inline bool
341 SPECLIST_FOO(_list_remove_all_if) (SPECLIST_LIST *tthis,
342 SPECLIST_FOO(_list_cond_fn_t)
343 cond_data_func)
344{
345 return genlist_remove_all_if((struct genlist *) tthis,
346 (genlist_cond_fn_t) cond_data_func);
347}
348
349/****************************************************************************
350 Remove the elements pointed by 'plink'. Returns the next element of the
351 speclist.
352
353 NB: After calling this function 'plink' is no more usable. You should
354 have saved the next or previous link before.
355****************************************************************************/
356 static inline void SPECLIST_FOO(_list_erase) (SPECLIST_LIST *tthis,
357 SPECLIST_LINK *plink)
358{
359 genlist_erase((struct genlist *) tthis, (struct genlist_link *) plink);
360}
361
362/****************************************************************************
363 Remove the first element of the speclist.
364****************************************************************************/
365 static inline void SPECLIST_FOO(_list_pop_front) (SPECLIST_LIST *tthis)
366{
367 genlist_pop_front((struct genlist *) tthis);
368}
369
370/****************************************************************************
371 Remove the last element of the speclist.
372****************************************************************************/
373 static inline void SPECLIST_FOO(_list_pop_back) (SPECLIST_LIST *tthis)
374{
375 genlist_pop_back((struct genlist *) tthis);
376}
377
378/****************************************************************************
379 Return the number of elements inside the speclist.
380****************************************************************************/
381 static inline int SPECLIST_FOO(_list_size) (const SPECLIST_LIST *tthis)
382{
383 return genlist_size((const struct genlist *) tthis);
384}
385
386/****************************************************************************
387 Return the element at position in the speclist.
388****************************************************************************/
389static inline SPECLIST_TYPE *
390 SPECLIST_FOO(_list_get) (const SPECLIST_LIST *tthis, int slindex)
391{
392 return ((SPECLIST_TYPE *)
393 genlist_get((const struct genlist *) tthis, slindex));
394}
395
396/****************************************************************************
397 Return the first element of the speclist.
398****************************************************************************/
399static inline SPECLIST_TYPE *
400 SPECLIST_FOO(_list_front) (const SPECLIST_LIST *tthis)
401{
402 return (SPECLIST_TYPE *) genlist_front((const struct genlist *) tthis);
403}
404
405/****************************************************************************
406 Return the last element of the speclist.
407****************************************************************************/
408static inline SPECLIST_TYPE *
409 SPECLIST_FOO(_list_back) (const SPECLIST_LIST *tthis)
410{
411 return (SPECLIST_TYPE *) genlist_back((const struct genlist *) tthis);
412}
413
414/****************************************************************************
415 Return the element at position in the speclist.
416****************************************************************************/
417static inline SPECLIST_LINK *
418 SPECLIST_FOO(_list_link_get) (const SPECLIST_LIST *tthis, int slindex)
419{
420 return ((SPECLIST_LINK *)
421 genlist_link_get((const struct genlist *) tthis, slindex));
422}
423
424/****************************************************************************
425 Return the head link of the speclist.
426****************************************************************************/
427static inline SPECLIST_LINK *
428 SPECLIST_FOO(_list_head) (const SPECLIST_LIST *tthis)
429{
430 return (SPECLIST_LINK *) genlist_head((const struct genlist *) tthis);
431}
432
433/****************************************************************************
434 Return the tail link of the speclist.
435****************************************************************************/
436static inline SPECLIST_LINK *
437 SPECLIST_FOO(_list_tail) (const SPECLIST_LIST *tthis)
438{
439 return (SPECLIST_LINK *) genlist_tail((const struct genlist *) tthis);
440}
441
442/****************************************************************************
443 Return the link of the first element which match the data 'pfoo'.
444****************************************************************************/
445static inline SPECLIST_LINK *
446 SPECLIST_FOO(_list_search) (const SPECLIST_LIST *tthis,
447 const SPECLIST_TYPE *pfoo)
448{
449 return ((SPECLIST_LINK *)
450 genlist_search((const struct genlist *) tthis, pfoo));
451}
452
453/****************************************************************************
454 Return the link of the first element which match the conditional function.
455****************************************************************************/
456static inline SPECLIST_LINK *
457 SPECLIST_FOO(_list_search_if) (const SPECLIST_LIST *tthis,
458 SPECLIST_FOO(_list_cond_fn_t) cond_data_func)
459{
460 return ((SPECLIST_LINK *)
461 genlist_search_if((const struct genlist *) tthis,
462 (genlist_cond_fn_t) cond_data_func));
463}
464
465/****************************************************************************
466 Sort the speclist.
467****************************************************************************/
468static inline void
469 SPECLIST_FOO(_list_sort) (SPECLIST_LIST * tthis,
470 int (*compar) (const SPECLIST_TYPE *const *,
471 const SPECLIST_TYPE *const *))
472{
473 genlist_sort((struct genlist *) tthis,
474 (int (*)(const void *, const void *)) compar);
475}
476
477/****************************************************************************
478 Shuffle the speclist.
479****************************************************************************/
480 static inline void SPECLIST_FOO(_list_shuffle) (SPECLIST_LIST *tthis)
481{
482 genlist_shuffle((struct genlist *) tthis);
483}
484
485/****************************************************************************
486 Reverse the order of the elements of the speclist.
487****************************************************************************/
488 static inline void SPECLIST_FOO(_list_reverse) (SPECLIST_LIST *tthis)
489{
490 genlist_reverse((struct genlist *) tthis);
491}
492
493/****************************************************************************
494 Allocate speclist mutex
495****************************************************************************/
496 static inline void SPECLIST_FOO(_list_allocate_mutex) (SPECLIST_LIST *tthis)
497{
498 genlist_allocate_mutex((struct genlist *) tthis);
499}
500
501/****************************************************************************
502 Release speclist mutex
503****************************************************************************/
504 static inline void SPECLIST_FOO(_list_release_mutex) (SPECLIST_LIST *tthis)
505{
506 genlist_release_mutex((struct genlist *) tthis);
507}
508
509/****************************************************************************
510 Return the data of the link.
511****************************************************************************/
512static inline SPECLIST_TYPE *
513 SPECLIST_FOO(_list_link_data) (const SPECLIST_LINK *plink)
514{
515 return ((SPECLIST_TYPE *)
516 genlist_link_data((const struct genlist_link *) plink));
517}
518
519/****************************************************************************
520 Return the previous link.
521****************************************************************************/
522static inline SPECLIST_LINK *
523 SPECLIST_FOO(_list_link_prev) (const SPECLIST_LINK *plink)
524 fc__warn_unused_result;
525
526static inline SPECLIST_LINK *
527 SPECLIST_FOO(_list_link_prev) (const SPECLIST_LINK *plink)
528{
529 return ((SPECLIST_LINK *)
530 genlist_link_prev((const struct genlist_link *) plink));
531}
532
533/****************************************************************************
534 Return the next link.
535****************************************************************************/
536static inline SPECLIST_LINK *
537 SPECLIST_FOO(_list_link_next) (const SPECLIST_LINK *plink)
538 fc__warn_unused_result;
539
540static inline SPECLIST_LINK *
541 SPECLIST_FOO(_list_link_next) (const SPECLIST_LINK *plink)
542{
543 return ((SPECLIST_LINK *)
544 genlist_link_next((const struct genlist_link *) plink));
545}
546
547#undef SPECLIST_TAG
548#undef SPECLIST_TYPE
549#undef SPECLIST_PASTE_
550#undef SPECLIST_PASTE
551#undef SPECLIST_LIST
552#undef SPECLIST_FOO
553
554/* Base macros that the users can specialize. */
555#ifndef FC__SPECLIST_H /* Defines this only once, no multiple inclusions. */
556#define FC__SPECLIST_H
557
558#ifdef FREECIV_DEBUG
559# define TYPED_LIST_CHECK(ARG_list) \
560 fc_assert_action(NULL != ARG_list, break)
561#else
562# define TYPED_LIST_CHECK(ARG_list) /* Nothing. */
563#endif /* FREECIV_DEBUG */
564
565/* Speclist data iterator.
566 *
567 * Using *_list_remove(NAME_data) is safe in this loop (but it may be
568 * inefficient due to the linear research of the data, see also
569 * *_list_erase()).
570 * Using *_list_clear() will result to use freed data. It must be avoided!
571 *
572 * TYPE_data - The real type of the data in the genlist/speclist.
573 * ARG_list - The speclist to iterate.
574 * NAME_data - The name of the data iterator (defined inside the macro). */
575#define TYPED_LIST_ITERATE(TYPE_data, ARG_list, NAME_data) \
576do { \
577 const struct genlist_link *NAME_data##_iter; \
578 TYPE_data *NAME_data; \
579 TYPED_LIST_CHECK(ARG_list); \
580 NAME_data##_iter = genlist_head((const struct genlist *) ARG_list); \
581 while (NULL != NAME_data##_iter) { \
582 NAME_data = (TYPE_data *) genlist_link_data(NAME_data##_iter); \
583 NAME_data##_iter = genlist_link_next(NAME_data##_iter);
584
585/* Balance for above: */
586#define LIST_ITERATE_END \
587 } \
588} while (FALSE);
589
590/* Mutex protected speclist data iterator.
591 *
592 * Using *_list_remove(NAME_data) is safe in this loop (but it may be
593 * inefficient due to the linear research of the data, see also
594 * *_list_erase()).
595 * Using *_list_clear() will result to use freed data. It must be avoided!
596 *
597 * TYPE_data - The real type of the data in the genlist/speclist.
598 * LIST_tag - Tag of the speclist
599 * ARG_list - The speclist to iterate.
600 * NAME_data - The name of the data iterator (defined inside the macro). */
601#define MUTEXED_LIST_ITERATE(TYPE_data, LIST_tag, ARG_list, NAME_data) \
602do { \
603 const struct genlist_link *NAME_data##_iter; \
604 TYPE_data *NAME_data; \
605 LIST_tag##_list_allocate_mutex(ARG_list); \
606 TYPED_LIST_CHECK(ARG_list); \
607 NAME_data##_iter = genlist_head((const struct genlist *) ARG_list); \
608 while (NULL != NAME_data##_iter) { \
609 NAME_data = (TYPE_data *) genlist_link_data(NAME_data##_iter); \
610 NAME_data##_iter = genlist_link_next(NAME_data##_iter);
611
612/* Balance for above: */
613#define MUTEXED_ITERATE_END(LIST_tag, ARG_list) \
614 } \
615 LIST_tag##_list_release_mutex(ARG_list); \
616} while (FALSE);
617
618#define MUTEXED_ITERATE_BREAK(LIST_tag, ARG_list) \
619do { \
620 LIST_tag##_list_release_mutex(ARG_list); \
621} while (FALSE);
622
623/* Same, but iterate backwards:
624 *
625 * TYPE_data - The real type of the data in the genlist/speclist.
626 * ARG_list - The speclist to iterate.
627 * NAME_data - The name of the data iterator (defined inside the macro). */
628#define TYPED_LIST_ITERATE_REV(TYPE_data, ARG_list, NAME_data) \
629do { \
630 const struct genlist_link *NAME_data##_iter; \
631 TYPE_data *NAME_data; \
632 TYPED_LIST_CHECK(ARG_list); \
633 NAME_data##_iter = genlist_tail((const struct genlist *) ARG_list); \
634 while (NULL != NAME_data##_iter) { \
635 NAME_data = (TYPE_data *) genlist_link_data(NAME_data##_iter); \
636 NAME_data##_iter = genlist_link_prev(NAME_data##_iter);
637
638/* Balance for above: */
639#define LIST_ITERATE_REV_END \
640 } \
641} while (FALSE);
642
643/* Speclist link iterator.
644 *
645 * Using *_list_erase(NAME_link) is safe in this loop.
646 * Using *_list_clear() will result to use freed data. It must be avoided!
647 *
648 * TYPE_link - The real type of the link.
649 * ARG_list - The speclist to iterate.
650 * NAME_link - The name of the link iterator (defined inside the macro). */
651#define TYPED_LIST_LINK_ITERATE(TYPE_link, ARG_list, NAME_link) \
652do { \
653 TYPE_link *NAME_link = ((TYPE_link *) \
654 genlist_head((const struct genlist *) ARG_list)); \
655 TYPE_link *NAME_link##_next; \
656 TYPED_LIST_CHECK(ARG_list); \
657 for (; NULL != NAME_link; NAME_link = NAME_link##_next) { \
658 NAME_link##_next = ((TYPE_link *) \
659 genlist_link_next((struct genlist_link *) \
660 NAME_link));
661
662/* Balance for above: */
663#define LIST_LINK_ITERATE_END \
664 } \
665} while (FALSE);
666
667/* Same, but iterate backwards:
668 *
669 * TYPE_link - The real type of the link.
670 * ARG_list - The speclist to iterate.
671 * NAME_link - The name of the link iterator (defined inside the macro). */
672#define TYPED_LIST_LINK_ITERATE_REV(TYPE_link, ARG_list, NAME_link) \
673do { \
674 TYPE_link *NAME_link = ((TYPE_link *) \
675 genlist_tail((const struct genlist *) ARG_list)); \
676 TYPE_link *NAME_link##_prev; \
677 TYPED_LIST_CHECK(ARG_list); \
678 for (; NULL != NAME_link; NAME_link = NAME_link##_prev) { \
679 NAME_link##_prev = ((TYPE_link *) \
680 genlist_link_prev((struct genlist_link *) \
681 NAME_link));
682
683/* Balance for above: */
684#define LIST_LINK_ITERATE_REV_END \
685 } \
686} while (FALSE);
687
688/* Speclist link and data iterator.
689 *
690 * Using *_list_erase(NAME_link) is safe in this loop.
691 * Using *_list_clear() will result to use freed data. It must be avoided!
692 *
693 * TYPE_link - The real type of the link.
694 * TYPE_data - The real type of the data in the genlist/speclist.
695 * ARG_list - The speclist to iterate.
696 * NAME_link - The name of the link iterator (defined inside the macro).
697 * NAME_data - The name of the data iterator (defined inside the macro). */
698#define TYPED_LIST_BOTH_ITERATE(TYPE_link, TYPE_data, \
699 ARG_list, NAME_link, NAME_data) \
700do { \
701 TYPE_link *NAME_link = ((TYPE_link *) \
702 genlist_head((const struct genlist *) ARG_list)); \
703 TYPE_link *NAME_link##_next; \
704 TYPE_data *NAME_data; \
705 TYPED_LIST_CHECK(ARG_list); \
706 for (; NULL != NAME_link; NAME_link = NAME_link##_next) { \
707 NAME_link##_next = ((TYPE_link *) \
708 genlist_link_next((struct genlist_link *) \
709 NAME_link)); \
710 NAME_data = ((TYPE_data *) \
711 genlist_link_data((struct genlist_link *) NAME_link));
712
713/* Balance for above: */
714#define LIST_BOTH_ITERATE_END \
715 } \
716} while (FALSE);
717
718/* Same, but iterate backwards:
719 *
720 * TYPE_link - The real type of the link.
721 * TYPE_data - The real type of the data in the genlist/speclist.
722 * ARG_list - The speclist to iterate.
723 * NAME_link - The name of the link iterator (defined inside the macro).
724 * NAME_data - The name of the data iterator (defined inside the macro). */
725#define TYPED_LIST_BOTH_ITERATE_REV(TYPE_link, TYPE_data, \
726 ARG_list, NAME_link, NAME_data) \
727do { \
728 TYPE_link *NAME_link = ((TYPE_link *) \
729 genlist_tail((const struct genlist *) ARG_list)); \
730 TYPE_link *NAME_link##_prev; \
731 TYPE_data *NAME_data; \
732 TYPED_LIST_CHECK(ARG_list); \
733 for (; NULL != NAME_link; NAME_link = NAME_link##_prev) { \
734 NAME_link##_prev = ((TYPE_link *) \
735 genlist_link_prev((struct genlist_link *) \
736 NAME_link)); \
737 NAME_data = ((TYPE_data *) \
738 genlist_link_data((struct genlist_link *) NAME_link));
739
740/* Balance for above: */
741#define LIST_BOTH_ITERATE_REV_END \
742 } \
743} while (FALSE);
744
745#endif /* FC__SPECLIST_H */
746
747/* This is after #endif FC__SPECLIST_H on purpose.
748 extern "C" portion begins well before latter part of the header
749 is guarded against multiple inclusions. */
750#ifdef __cplusplus
751}
752#endif /* __cplusplus */
SPECLIST_TYPE
#define SPECLIST_TYPE
Definition fc_cmdline.c:32
genlist_remove
bool genlist_remove(struct genlist *pgenlist, const void *punlink)
Definition genlist.c:329
genlist_allocate_mutex
void genlist_allocate_mutex(struct genlist *pgenlist)
Definition genlist.c:682
genlist_insert
void genlist_insert(struct genlist *pgenlist, void *data, int pos)
Definition genlist.c:477
genlist_copy_full
struct genlist * genlist_copy_full(const struct genlist *pgenlist, genlist_copy_fn_t copy_data_func, genlist_free_fn_t free_data_func)
Definition genlist.c:165
genlist_release_mutex
void genlist_release_mutex(struct genlist *pgenlist)
Definition genlist.c:690
genlist_new
struct genlist * genlist_new(void)
Definition genlist.c:31
genlist_get
void * genlist_get(const struct genlist *pgenlist, int idx)
Definition genlist.c:224
genlist_remove_all
int genlist_remove_all(struct genlist *pgenlist, const void *punlink)
Definition genlist.c:351
genlist_erase
void genlist_erase(struct genlist *pgenlist, struct genlist_link *plink)
Definition genlist.c:436
genlist_search_if
struct genlist_link * genlist_search_if(const struct genlist *pgenlist, genlist_cond_fn_t cond_data_func)
Definition genlist.c:568
genlist_clear
void genlist_clear(struct genlist *pgenlist)
Definition genlist.c:250
genlist_prepend
void genlist_prepend(struct genlist *pgenlist, void *data)
Definition genlist.c:526
genlist_remove_if
bool genlist_remove_if(struct genlist *pgenlist, genlist_cond_fn_t cond_data_func)
Definition genlist.c:379
genlist_append
void genlist_append(struct genlist *pgenlist, void *data)
Definition genlist.c:536
genlist_unique_full
void genlist_unique_full(struct genlist *pgenlist, genlist_comp_fn_t comp_data_func)
Definition genlist.c:292
genlist_copy
struct genlist * genlist_copy(const struct genlist *pgenlist)
Definition genlist.c:157
genlist_destroy
void genlist_destroy(struct genlist *pgenlist)
Definition genlist.c:57
genlist_pop_front
void genlist_pop_front(struct genlist *pgenlist)
Definition genlist.c:448
genlist_insert_before
void genlist_insert_before(struct genlist *pgenlist, void *data, struct genlist_link *plink)
Definition genlist.c:514
genlist_back
void * genlist_back(const struct genlist *pgenlist)
Definition genlist.c:240
genlist_remove_all_if
int genlist_remove_all_if(struct genlist *pgenlist, genlist_cond_fn_t cond_data_func)
Definition genlist.c:404
genlist_unique
void genlist_unique(struct genlist *pgenlist)
Definition genlist.c:282
genlist_insert_after
void genlist_insert_after(struct genlist *pgenlist, void *data, struct genlist_link *plink)
Definition genlist.c:502
genlist_sort
void genlist_sort(struct genlist *pgenlist, int(*compar)(const void *, const void *))
Definition genlist.c:597
genlist_reverse
void genlist_reverse(struct genlist *pgenlist)
Definition genlist.c:659
genlist_tail
struct genlist_link * genlist_tail(const struct genlist *pgenlist)
Definition genlist.c:213
genlist_front
void * genlist_front(const struct genlist *pgenlist)
Definition genlist.c:232
genlist_new_full
struct genlist * genlist_new_full(genlist_free_fn_t free_data_func)
Definition genlist.c:39
genlist_link_get
struct genlist_link * genlist_link_get(const struct genlist *pgenlist, int idx)
Definition genlist.c:203
genlist_pop_back
void genlist_pop_back(struct genlist *pgenlist)
Definition genlist.c:460
genlist_search
struct genlist_link * genlist_search(const struct genlist *pgenlist, const void *data)
Definition genlist.c:548
genlist_size
int genlist_size(const struct genlist *pgenlist)
Definition genlist.c:192
genlist_shuffle
void genlist_shuffle(struct genlist *pgenlist)
Definition genlist.c:629
genlist.h
genlist_cond_fn_t
bool(* genlist_cond_fn_t)(const void *)
Definition genlist.h:53
genlist_comp_fn_t
bool(* genlist_comp_fn_t)(const void *, const void *)
Definition genlist.h:54
genlist_head
static struct genlist_link * genlist_head(const struct genlist *pgenlist)
Definition genlist.h:108
genlist_link_data
static void * genlist_link_data(const struct genlist_link *plink)
Definition genlist.h:140
genlist_copy_fn_t
void *(* genlist_copy_fn_t)(const void *)
Definition genlist.h:52
genlist_free_fn_t
void(* genlist_free_fn_t)(void *)
Definition genlist.h:51
genlist_link_prev
static fc__warn_unused_result struct genlist_link * genlist_link_prev(const struct genlist_link *plink)
Definition genlist.h:151
genlist_link_next
static fc__warn_unused_result struct genlist_link * genlist_link_next(const struct genlist_link *plink)
Definition genlist.h:162
_list_copy
static SPECLIST_LIST *SPECLIST_FOO() _list_copy(const SPECLIST_LIST *tthis) fc__warn_unused_result
Definition speclist.h:203
_list_sort
static void SPECLIST_FOO() _list_sort(SPECLIST_LIST *tthis, int(*compar)(const SPECLIST_TYPE *const *, const SPECLIST_TYPE *const *))
Definition speclist.h:469
_list_append
static void SPECLIST_FOO() _list_append(SPECLIST_LIST *tthis, SPECLIST_TYPE *pfoo)
Definition speclist.h:260
_list_tail
static SPECLIST_LINK *SPECLIST_FOO() _list_tail(const SPECLIST_LIST *tthis)
Definition speclist.h:437
_list_search_if
static SPECLIST_LINK *SPECLIST_FOO() _list_search_if(const SPECLIST_LIST *tthis, SPECLIST_FOO(_list_cond_fn_t) cond_data_func)
Definition speclist.h:457
_list_size
static int SPECLIST_FOO() _list_size(const SPECLIST_LIST *tthis)
Definition speclist.h:381
_list_link_data
static SPECLIST_TYPE *SPECLIST_FOO() _list_link_data(const SPECLIST_LINK *plink)
Definition speclist.h:513
_list_front
static SPECLIST_TYPE *SPECLIST_FOO() _list_front(const SPECLIST_LIST *tthis)
Definition speclist.h:400
_list_search
static SPECLIST_LINK *SPECLIST_FOO() _list_search(const SPECLIST_LIST *tthis, const SPECLIST_TYPE *pfoo)
Definition speclist.h:446
_list_head
static SPECLIST_LINK *SPECLIST_FOO() _list_head(const SPECLIST_LIST *tthis)
Definition speclist.h:428
_list_erase
static void SPECLIST_FOO() _list_erase(SPECLIST_LIST *tthis, SPECLIST_LINK *plink)
Definition speclist.h:356
_list_back
static SPECLIST_TYPE *SPECLIST_FOO() _list_back(const SPECLIST_LIST *tthis)
Definition speclist.h:409
_list_copy_full
static SPECLIST_LIST *SPECLIST_FOO() _list_copy_full(const SPECLIST_LIST *tthis, SPECLIST_FOO(_list_copy_fn_t) copy_data_func, SPECLIST_FOO(_list_free_fn_t) free_data_func) fc__warn_unused_result
Definition speclist.h:219
_list_remove
static bool SPECLIST_FOO() _list_remove(SPECLIST_LIST *tthis, const SPECLIST_TYPE *pfoo)
Definition speclist.h:309
_list_prepend
static void SPECLIST_FOO() _list_prepend(SPECLIST_LIST *tthis, SPECLIST_TYPE *pfoo)
Definition speclist.h:269
_list_pop_front
static void SPECLIST_FOO() _list_pop_front(SPECLIST_LIST *tthis)
Definition speclist.h:365
_list_pop_back
static void SPECLIST_FOO() _list_pop_back(SPECLIST_LIST *tthis)
Definition speclist.h:373
_list_new
static SPECLIST_LIST *SPECLIST_FOO() _list_new(void) fc__warn_unused_result
Definition speclist.h:168
_list_insert_before
static void SPECLIST_FOO() _list_insert_before(SPECLIST_LIST *tthis, SPECLIST_TYPE *pfoo, SPECLIST_LINK *plink)
Definition speclist.h:298
_list_remove_if
static bool SPECLIST_FOO() _list_remove_if(SPECLIST_LIST *tthis, SPECLIST_FOO(_list_cond_fn_t) cond_data_func)
Definition speclist.h:320
SPECLIST_LINK
#define SPECLIST_LINK
Definition speclist.h:144
_list_get
static SPECLIST_TYPE *SPECLIST_FOO() _list_get(const SPECLIST_LIST *tthis, int slindex)
Definition speclist.h:390
_list_clear
static void SPECLIST_FOO() _list_clear(SPECLIST_LIST *tthis)
Definition speclist.h:232
_list_reverse
static void SPECLIST_FOO() _list_reverse(SPECLIST_LIST *tthis)
Definition speclist.h:488
_list_link_next
static SPECLIST_LINK *SPECLIST_FOO() _list_link_next(const SPECLIST_LINK *plink) fc__warn_unused_result
Definition speclist.h:541
_list_insert_after
static void SPECLIST_FOO() _list_insert_after(SPECLIST_LIST *tthis, SPECLIST_TYPE *pfoo, SPECLIST_LINK *plink)
Definition speclist.h:287
_list_allocate_mutex
static void SPECLIST_FOO() _list_allocate_mutex(SPECLIST_LIST *tthis)
Definition speclist.h:496
_list_shuffle
static void SPECLIST_FOO() _list_shuffle(SPECLIST_LIST *tthis)
Definition speclist.h:480
_list_insert
static void SPECLIST_FOO() _list_insert(SPECLIST_LIST *tthis, SPECLIST_TYPE *pfoo, int idx)
Definition speclist.h:278
_list_remove_all_if
static bool SPECLIST_FOO() _list_remove_all_if(SPECLIST_LIST *tthis, cond_data_func)
Definition speclist.h:341
_list_link_get
static SPECLIST_LINK *SPECLIST_FOO() _list_link_get(const SPECLIST_LIST *tthis, int slindex)
Definition speclist.h:418
_list_unique
static void SPECLIST_FOO() _list_unique(SPECLIST_LIST *tthis)
Definition speclist.h:240
_list_release_mutex
static void SPECLIST_FOO() _list_release_mutex(SPECLIST_LIST *tthis)
Definition speclist.h:504
_list_new_full
static SPECLIST_LIST *SPECLIST_FOO() _list_new_full(SPECLIST_FOO(_list_free_fn_t) free_data_func) fc__warn_unused_result
Definition speclist.h:181
SPECLIST_LIST
#define SPECLIST_LIST
Definition speclist.h:143
_list_unique_full
static void SPECLIST_FOO() _list_unique_full(SPECLIST_LIST *tthis, SPECLIST_FOO(_list_comp_fn_t) comp_data_func)
Definition speclist.h:250
_list_destroy
static void SPECLIST_FOO() _list_destroy(SPECLIST_LIST *tthis)
Definition speclist.h:190
_list_link_prev
static SPECLIST_LINK *SPECLIST_FOO() _list_link_prev(const SPECLIST_LINK *plink) fc__warn_unused_result
Definition speclist.h:527
SPECLIST_FOO
#define SPECLIST_FOO(suffix)
Definition speclist.h:145
_list_remove_all
static int SPECLIST_FOO() _list_remove_all(SPECLIST_LIST *tthis, const SPECLIST_TYPE *pfoo)
Definition speclist.h:330
genlist_link
Definition genlist.h:130
genlist
Definition genlist.h:59
fc__warn_unused_result
#define fc__warn_unused_result
Definition support.h:99
bool
#define bool
Definition support.h:61