127 #error Must define a SPECLIST_TAG to use this header
130 #ifndef SPECLIST_TYPE
131 #define SPECLIST_TYPE struct SPECLIST_TAG
134 #define SPECLIST_PASTE_(x, y) x##y
135 #define SPECLIST_PASTE(x, y) SPECLIST_PASTE_(x, y)
137 #define SPECLIST_LIST struct SPECLIST_PASTE(SPECLIST_TAG, _list)
138 #define SPECLIST_LINK struct SPECLIST_PASTE(SPECLIST_TAG, _list_link)
139 #define SPECLIST_FOO(suffix) SPECLIST_PASTE(SPECLIST_TAG, suffix)
215 reinterpret_cast<const struct
genlist *
>(tthis),
313 reinterpret_cast<struct
genlist *
>(tthis),
334 reinterpret_cast<struct
genlist *
>(tthis),
383 reinterpret_cast<const struct
genlist *
>(tthis), slindex)));
413 reinterpret_cast<const struct
genlist *
>(tthis), slindex)));
444 reinterpret_cast<const struct
genlist *
>(tthis), pfoo)));
454 reinterpret_cast<const struct
genlist *
>(tthis),
467 reinterpret_cast<struct
genlist *
>(tthis),
468 reinterpret_cast<int (*)(
const void *,
const void *)
>(compar));
510 reinterpret_cast<const struct
genlist_link *
>(plink))));
523 reinterpret_cast<const struct
genlist_link *
>(plink))));
536 reinterpret_cast<const struct
genlist_link *
>(plink))));
541 #undef SPECLIST_PASTE_
542 #undef SPECLIST_PASTE
547 #ifndef FC__SPECLIST_H
549 #define FC__SPECLIST_H
552 #define TYPED_LIST_CHECK(ARG_list) \
553 fc_assert_action(nullptr != ARG_list, break)
555 #define TYPED_LIST_CHECK(ARG_list)
568 #define TYPED_LIST_ITERATE(TYPE_data, ARG_list, NAME_data) \
570 const struct genlist_link *NAME_data##_iter; \
571 TYPE_data *NAME_data; \
572 TYPED_LIST_CHECK(ARG_list); \
573 NAME_data##_iter = genlist_head((const struct genlist *) ARG_list); \
574 while (nullptr != NAME_data##_iter) { \
575 NAME_data = (TYPE_data *) genlist_link_data(NAME_data##_iter); \
576 NAME_data##_iter = genlist_link_next(NAME_data##_iter);
579 #define LIST_ITERATE_END \
596 #define MUTEXED_LIST_ITERATE(TYPE_data, LIST_tag, ARG_list, NAME_data) \
598 const struct genlist_link *NAME_data##_iter; \
599 TYPE_data *NAME_data; \
600 LIST_tag##_list_allocate_mutex(ARG_list); \
601 TYPED_LIST_CHECK(ARG_list); \
602 NAME_data##_iter = genlist_head((const struct genlist *) ARG_list); \
603 while (nullptr != NAME_data##_iter) { \
604 NAME_data = (TYPE_data *) genlist_link_data(NAME_data##_iter); \
605 NAME_data##_iter = genlist_link_next(NAME_data##_iter);
608 #define MUTEXED_ITERATE_END(LIST_tag, ARG_list) \
610 LIST_tag##_list_release_mutex(ARG_list); \
615 #define MUTEXED_ITERATE_BREAK(LIST_tag, ARG_list) \
617 LIST_tag##_list_release_mutex(ARG_list); \
625 #define TYPED_LIST_ITERATE_REV(TYPE_data, ARG_list, NAME_data) \
627 const struct genlist_link *NAME_data##_iter; \
628 TYPE_data *NAME_data; \
629 TYPED_LIST_CHECK(ARG_list); \
630 NAME_data##_iter = genlist_tail((const struct genlist *) ARG_list); \
631 while (nullptr != NAME_data##_iter) { \
632 NAME_data = (TYPE_data *) genlist_link_data(NAME_data##_iter); \
633 NAME_data##_iter = genlist_link_prev(NAME_data##_iter);
636 #define LIST_ITERATE_REV_END \
650 #define TYPED_LIST_LINK_ITERATE(TYPE_link, ARG_list, NAME_link) \
652 TYPE_link *NAME_link = \
653 ((TYPE_link *) genlist_head((const struct genlist *) ARG_list)); \
654 TYPE_link *NAME_link##_next; \
655 TYPED_LIST_CHECK(ARG_list); \
656 for (; nullptr != NAME_link; NAME_link = NAME_link##_next) { \
657 NAME_link##_next = ((TYPE_link *) genlist_link_next( \
658 (struct genlist_link *) NAME_link));
661 #define LIST_LINK_ITERATE_END \
672 #define TYPED_LIST_LINK_ITERATE_REV(TYPE_link, ARG_list, NAME_link) \
674 TYPE_link *NAME_link = \
675 ((TYPE_link *) genlist_tail((const struct genlist *) ARG_list)); \
676 TYPE_link *NAME_link##_prev; \
677 TYPED_LIST_CHECK(ARG_list); \
678 for (; nullptr != NAME_link; NAME_link = NAME_link##_prev) { \
679 NAME_link##_prev = ((TYPE_link *) genlist_link_prev( \
680 (struct genlist_link *) NAME_link));
683 #define LIST_LINK_ITERATE_REV_END \
699 #define TYPED_LIST_BOTH_ITERATE(TYPE_link, TYPE_data, ARG_list, NAME_link, \
702 TYPE_link *NAME_link = \
703 ((TYPE_link *) genlist_head((const struct genlist *) ARG_list)); \
704 TYPE_link *NAME_link##_next; \
705 TYPE_data *NAME_data; \
706 TYPED_LIST_CHECK(ARG_list); \
707 for (; nullptr != NAME_link; NAME_link = NAME_link##_next) { \
708 NAME_link##_next = ((TYPE_link *) genlist_link_next( \
709 (struct genlist_link *) NAME_link)); \
710 NAME_data = ((TYPE_data *) genlist_link_data( \
711 (struct genlist_link *) NAME_link));
714 #define LIST_BOTH_ITERATE_END \
727 #define TYPED_LIST_BOTH_ITERATE_REV(TYPE_link, TYPE_data, ARG_list, \
728 NAME_link, NAME_data) \
730 TYPE_link *NAME_link = \
731 ((TYPE_link *) genlist_tail((const struct genlist *) ARG_list)); \
732 TYPE_link *NAME_link##_prev; \
733 TYPE_data *NAME_data; \
734 TYPED_LIST_CHECK(ARG_list); \
735 for (; nullptr != NAME_link; NAME_link = NAME_link##_prev) { \
736 NAME_link##_prev = ((TYPE_link *) genlist_link_prev( \
737 (struct genlist_link *) NAME_link)); \
738 NAME_data = ((TYPE_data *) genlist_link_data( \
739 (struct genlist_link *) NAME_link));
742 #define LIST_BOTH_ITERATE_REV_END \
bool genlist_remove(struct genlist *pgenlist, const void *punlink)
Remove an element of the genlist with the specified user-data pointer given by 'punlink'.
void genlist_allocate_mutex(struct genlist *pgenlist)
Allocates list mutex.
void genlist_insert(struct genlist *pgenlist, void *data, int pos)
Insert a new element in the list, at position 'pos', with the specified user-data pointer 'data'.
void genlist_release_mutex(struct genlist *pgenlist)
Releases list mutex.
void * genlist_get(const struct genlist *pgenlist, int idx)
Returns the user-data pointer stored in the genlist at the position given by 'idx'.
struct genlist_link * genlist_search_if(const struct genlist *pgenlist, genlist_cond_fn_t cond_data_func)
Return the link which fit the conditional function.
void * genlist_back(const struct genlist *pgenlist)
Returns the user-data pointer stored in the last element of the genlist.
int genlist_remove_all(struct genlist *pgenlist, const void *punlink)
Remove all elements of the genlist with the specified user-data pointer given by 'punlink'.
void genlist_erase(struct genlist *pgenlist, struct genlist_link *plink)
Remove the element pointed to plink.
void genlist_clear(struct genlist *pgenlist)
Frees all the internal data used by the genlist (but doesn't touch the user-data).
void genlist_prepend(struct genlist *pgenlist, void *data)
Insert an item at the start of the list.
bool genlist_remove_if(struct genlist *pgenlist, genlist_cond_fn_t cond_data_func)
Remove the first element of the genlist which fit the function (the function return TRUE).
void genlist_append(struct genlist *pgenlist, void *data)
Insert an item at the end of the list.
void genlist_unique_full(struct genlist *pgenlist, genlist_comp_fn_t comp_data_func)
Remove all duplicates of element from every consecutive group of equal elements in the list (equality...
struct genlist_link * genlist_tail(const struct genlist *pgenlist)
Returns the tail link of the genlist.
struct genlist_link * genlist_link_get(const struct genlist *pgenlist, int idx)
Returns the link in the genlist at the position given by 'idx'.
void genlist_destroy(struct genlist *pgenlist)
Destroys the genlist.
void genlist_pop_front(struct genlist *pgenlist)
Remove the first element of the genlist.
void * genlist_front(const struct genlist *pgenlist)
Returns the user-data pointer stored in the first element of the genlist.
void genlist_insert_before(struct genlist *pgenlist, void *data, struct genlist_link *plink)
Insert an item before the link.
int genlist_remove_all_if(struct genlist *pgenlist, genlist_cond_fn_t cond_data_func)
Remove all elements of the genlist which fit the function (the function return TRUE).
void genlist_unique(struct genlist *pgenlist)
Remove all duplicates of element from every consecutive group of equal elements in the list.
void genlist_insert_after(struct genlist *pgenlist, void *data, struct genlist_link *plink)
Insert an item after the link.
struct genlist * genlist_copy(const struct genlist *pgenlist)
Returns a new genlist that's a copy of the existing one.
void genlist_sort(struct genlist *pgenlist, int(*compar)(const void *, const void *))
Sort the elements of a genlist.
void genlist_reverse(struct genlist *pgenlist)
Reverse the order of the elements in the genlist.
struct genlist_link * genlist_search(const struct genlist *pgenlist, const void *data)
Return the link where data is equal to 'data'.
void genlist_pop_back(struct genlist *pgenlist)
Remove the last element of the genlist.
struct genlist * genlist_new()
Create a new empty genlist.
struct genlist * genlist_new_full(genlist_free_fn_t free_data_func)
Create a new empty genlist with a free data function.
struct genlist * genlist_copy_full(const struct genlist *pgenlist, genlist_copy_fn_t copy_data_func, genlist_free_fn_t free_data_func)
Returns a new genlist that's a copy of the existing one.
int genlist_size(const struct genlist *pgenlist)
Returns the number of elements stored in the genlist.
void genlist_shuffle(struct genlist *pgenlist)
Randomize the elements of a genlist using the Fisher-Yates shuffle.
static struct genlist_link * genlist_head(const struct genlist *pgenlist)
static void * genlist_link_data(const struct genlist_link *plink)
bool(* genlist_cond_fn_t)(const void *)
static fc__warn_unused_result struct genlist_link * genlist_link_next(const struct genlist_link *plink)
bool(* genlist_comp_fn_t)(const void *, const void *)
static fc__warn_unused_result struct genlist_link * genlist_link_prev(const struct genlist_link *plink)
void(* genlist_free_fn_t)(void *)
void *(* genlist_copy_fn_t)(const void *)
static void SPECLIST_FOO() _list_sort(SPECLIST_LIST *tthis, int(*compar)(const SPECLIST_TYPE *const *, const SPECLIST_TYPE *const *))
static void SPECLIST_FOO() _list_append(SPECLIST_LIST *tthis, SPECLIST_TYPE *pfoo)
static SPECLIST_LIST *SPECLIST_FOO() _list_new_full(SPECLIST_FOO(_list_free_fn_t) free_data_func) fc__warn_unused_result
static int SPECLIST_FOO() _list_size(const SPECLIST_LIST *tthis)
static SPECLIST_LINK *SPECLIST_FOO() _list_search_if(const SPECLIST_LIST *tthis, SPECLIST_FOO(_list_cond_fn_t) cond_data_func)
static void SPECLIST_FOO() _list_erase(SPECLIST_LIST *tthis, SPECLIST_LINK *plink)
static SPECLIST_TYPE *SPECLIST_FOO() _list_get(const SPECLIST_LIST *tthis, int slindex)
static bool SPECLIST_FOO() _list_remove(SPECLIST_LIST *tthis, const SPECLIST_TYPE *pfoo)
static void SPECLIST_FOO() _list_prepend(SPECLIST_LIST *tthis, SPECLIST_TYPE *pfoo)
static void SPECLIST_FOO() _list_pop_front(SPECLIST_LIST *tthis)
static void SPECLIST_FOO() _list_pop_back(SPECLIST_LIST *tthis)
static void SPECLIST_FOO() _list_insert_before(SPECLIST_LIST *tthis, SPECLIST_TYPE *pfoo, SPECLIST_LINK *plink)
static bool SPECLIST_FOO() _list_remove_if(SPECLIST_LIST *tthis, SPECLIST_FOO(_list_cond_fn_t) cond_data_func)
static SPECLIST_TYPE *SPECLIST_FOO() _list_back(const SPECLIST_LIST *tthis)
static SPECLIST_LIST *SPECLIST_FOO() _list_new() fc__warn_unused_result
static void SPECLIST_FOO() _list_clear(SPECLIST_LIST *tthis)
static void SPECLIST_FOO() _list_reverse(SPECLIST_LIST *tthis)
static void SPECLIST_FOO() _list_insert_after(SPECLIST_LIST *tthis, SPECLIST_TYPE *pfoo, SPECLIST_LINK *plink)
static SPECLIST_LINK *SPECLIST_FOO() _list_head(const SPECLIST_LIST *tthis)
static void SPECLIST_FOO() _list_allocate_mutex(SPECLIST_LIST *tthis)
static void SPECLIST_FOO() _list_shuffle(SPECLIST_LIST *tthis)
static void SPECLIST_FOO() _list_insert(SPECLIST_LIST *tthis, SPECLIST_TYPE *pfoo, int idx)
static SPECLIST_LINK *SPECLIST_FOO() _list_tail(const SPECLIST_LIST *tthis)
static SPECLIST_LINK *SPECLIST_FOO() _list_link_get(const SPECLIST_LIST *tthis, int slindex)
static SPECLIST_LIST *SPECLIST_FOO() _list_copy(const SPECLIST_LIST *tthis) fc__warn_unused_result
static bool SPECLIST_FOO() _list_remove_all_if(SPECLIST_LIST *tthis, SPECLIST_FOO(_list_cond_fn_t) cond_data_func)
static SPECLIST_LINK *SPECLIST_FOO() _list_search(const SPECLIST_LIST *tthis, const SPECLIST_TYPE *pfoo)
static SPECLIST_LINK *SPECLIST_FOO() _list_link_prev(const SPECLIST_LINK *plink) fc__warn_unused_result
static void SPECLIST_FOO() _list_unique(SPECLIST_LIST *tthis)
static SPECLIST_TYPE *SPECLIST_FOO() _list_link_data(const SPECLIST_LINK *plink)
static void SPECLIST_FOO() _list_release_mutex(SPECLIST_LIST *tthis)
static void SPECLIST_FOO() _list_unique_full(SPECLIST_LIST *tthis, SPECLIST_FOO(_list_comp_fn_t) comp_data_func)
static void SPECLIST_FOO() _list_destroy(SPECLIST_LIST *tthis)
static SPECLIST_LINK *SPECLIST_FOO() _list_link_next(const SPECLIST_LINK *plink) fc__warn_unused_result
#define SPECLIST_FOO(suffix)
static SPECLIST_TYPE *SPECLIST_FOO() _list_front(const SPECLIST_LIST *tthis)
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
static int SPECLIST_FOO() _list_remove_all(SPECLIST_LIST *tthis, const SPECLIST_TYPE *pfoo)
#define fc__warn_unused_result