Freeciv21
Develop your civilization from humble roots to a global empire
genlist.h
Go to the documentation of this file.
1 /**************************************************************************
2  Copyright (c) 1996-2020 Freeciv21 and Freeciv contributors. This file is
3  __ __ part of Freeciv21. Freeciv21 is free software: you can
4 / \\..// \ redistribute it and/or modify it under the terms of the GNU
5  ( oo ) General Public License as published by the Free Software
6  \__/ Foundation, either version 3 of the License, or (at your
7  option) any later version. You should have received
8  a copy of the GNU General Public License along with Freeciv21. If not,
9  see https://www.gnu.org/licenses/.
10 **************************************************************************/
11 #pragma once
12 
13 /****************************************************************************
14  MODULE: genlist
15 
16  A "genlist" is a generic doubly-linked list. That is:
17  generic: stores (void*) pointers to arbitrary user data;
18  doubly-linked: can be efficiently traversed both "forwards"
19  and "backwards".
20 
21  The list data structures are allocated dynamically, and list elements can
22  be added or removed at arbitrary positions.
23 
24  Positions in the list are specified starting from 0, up to n - 1 for a
25  list with n elements. The position -1 can be used to refer to the last
26  element (that is, the same as n - 1, or n when adding a new element), but
27  other negative numbers are not meaningful.
28 
29  A trap to beware of with iterators is modifying the list while the
30  iterator is active, in particular removing the next element pointed
31  to by the iterator (see further comments below).
32 
33  See also the speclist module.
34 ****************************************************************************/
35 
36 // utility
37 #include "support.h" // bool, fc__warn_unused_result
38 
39 #include <QMutex>
40 
41 // A single element of a genlist, opaque type.
42 struct genlist_link;
43 
44 // Function type definitions.
45 typedef void (*genlist_free_fn_t)(void *);
46 typedef void *(*genlist_copy_fn_t)(const void *);
47 typedef bool (*genlist_cond_fn_t)(const void *);
48 typedef bool (*genlist_comp_fn_t)(const void *, const void *);
49 
50 /* A genlist, storing the number of elements (for quick retrieval and
51  * testing for empty lists), and pointers to the first and last elements
52  * of the list. */
53 struct genlist {
54  int nelements;
55  QMutex mutex;
59 };
60 
62 struct genlist *
64 void genlist_destroy(struct genlist *pgenlist);
65 
66 struct genlist *
67 genlist_copy(const struct genlist *pgenlist) fc__warn_unused_result;
68 struct genlist *
69 genlist_copy_full(const struct genlist *pgenlist,
70  genlist_copy_fn_t copy_data_func,
72 
73 void genlist_clear(struct genlist *pgenlist);
74 
75 void genlist_unique(struct genlist *pgenlist);
76 void genlist_unique_full(struct genlist *pgenlist,
77  genlist_comp_fn_t comp_data_func);
78 
79 void genlist_append(struct genlist *pgenlist, void *data);
80 void genlist_prepend(struct genlist *pgenlist, void *data);
81 void genlist_insert(struct genlist *pgenlist, void *data, int idx);
82 void genlist_insert_after(struct genlist *pgenlist, void *data,
83  struct genlist_link *plink);
84 void genlist_insert_before(struct genlist *pgenlist, void *data,
85  struct genlist_link *plink);
86 
87 bool genlist_remove(struct genlist *pgenlist, const void *data);
88 bool genlist_remove_if(struct genlist *pgenlist,
89  genlist_cond_fn_t cond_data_func);
90 int genlist_remove_all(struct genlist *pgenlist, const void *data);
91 int genlist_remove_all_if(struct genlist *pgenlist,
92  genlist_cond_fn_t cond_data_func);
93 void genlist_erase(struct genlist *pgenlist, struct genlist_link *plink);
94 void genlist_pop_front(struct genlist *pgenlist);
95 void genlist_pop_back(struct genlist *pgenlist);
96 
97 int genlist_size(const struct genlist *pgenlist);
98 void *genlist_get(const struct genlist *pgenlist, int idx);
99 void *genlist_front(const struct genlist *pgenlist);
100 void *genlist_back(const struct genlist *pgenlist);
101 struct genlist_link *genlist_link_get(const struct genlist *pgenlist,
102  int idx);
103 inline static struct genlist_link *
104 genlist_head(const struct genlist *pgenlist)
105 {
106  return (nullptr != pgenlist ? pgenlist->head_link : nullptr);
107 }
108 struct genlist_link *genlist_tail(const struct genlist *pgenlist);
109 
110 struct genlist_link *genlist_search(const struct genlist *pgenlist,
111  const void *data);
112 struct genlist_link *genlist_search_if(const struct genlist *pgenlist,
113  genlist_cond_fn_t cond_data_func);
114 
115 void genlist_sort(struct genlist *pgenlist,
116  int (*compar)(const void *, const void *));
117 void genlist_shuffle(struct genlist *pgenlist);
118 void genlist_reverse(struct genlist *pgenlist);
119 
120 void genlist_allocate_mutex(struct genlist *pgenlist);
121 void genlist_release_mutex(struct genlist *pgenlist);
122 
123 /* A single element of a genlist, storing the pointer to user
124  * data, and pointers to the next and previous elements: */
125 struct genlist_link {
126  struct genlist_link *next, *prev;
127  void *dataptr;
128 };
129 
130 /****************************************************************************
131  Returns the pointer of this link.
132 ****************************************************************************/
133 static inline void *genlist_link_data(const struct genlist_link *plink)
134 {
135  return (nullptr != plink ? plink->dataptr : nullptr);
136 }
137 
138 /****************************************************************************
139  Returns the previous link.
140 ****************************************************************************/
141 fc__warn_unused_result static inline struct genlist_link *
142 genlist_link_prev(const struct genlist_link *plink)
143 {
144  return plink->prev;
145 }
146 
147 /****************************************************************************
148  Returns the next link.
149 ****************************************************************************/
150 fc__warn_unused_result static inline struct genlist_link *
151 genlist_link_next(const struct genlist_link *plink)
152 {
153  return plink->next;
154 }
void genlist_insert(struct genlist *pgenlist, void *data, int idx)
Insert a new element in the list, at position 'pos', with the specified user-data pointer 'data'.
Definition: genlist.cpp:465
static struct genlist_link * genlist_head(const struct genlist *pgenlist)
Definition: genlist.h:104
void genlist_allocate_mutex(struct genlist *pgenlist)
Allocates list mutex.
Definition: genlist.cpp:676
static void * genlist_link_data(const struct genlist_link *plink)
Definition: genlist.h:133
void genlist_release_mutex(struct genlist *pgenlist)
Releases list mutex.
Definition: genlist.cpp:684
void * genlist_get(const struct genlist *pgenlist, int idx)
Returns the user-data pointer stored in the genlist at the position given by 'idx'.
Definition: genlist.cpp:212
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.
Definition: genlist.cpp:558
void * genlist_back(const struct genlist *pgenlist)
Returns the user-data pointer stored in the last element of the genlist.
Definition: genlist.cpp:228
bool(* genlist_cond_fn_t)(const void *)
Definition: genlist.h:47
void genlist_erase(struct genlist *pgenlist, struct genlist_link *plink)
Remove the element pointed to plink.
Definition: genlist.cpp:424
static fc__warn_unused_result struct genlist_link * genlist_link_next(const struct genlist_link *plink)
Definition: genlist.h:151
struct genlist * genlist_copy(const struct genlist *pgenlist) fc__warn_unused_result
Returns a new genlist that's a copy of the existing one.
Definition: genlist.cpp:144
void genlist_clear(struct genlist *pgenlist)
Frees all the internal data used by the genlist (but doesn't touch the user-data).
Definition: genlist.cpp:238
void genlist_prepend(struct genlist *pgenlist, void *data)
Insert an item at the start of the list.
Definition: genlist.cpp:515
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).
Definition: genlist.cpp:367
void genlist_append(struct genlist *pgenlist, void *data)
Insert an item at the end of the list.
Definition: genlist.cpp:525
bool(* genlist_comp_fn_t)(const void *, const void *)
Definition: genlist.h:48
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...
Definition: genlist.cpp:280
struct genlist_link * genlist_tail(const struct genlist *pgenlist)
Returns the tail link of the genlist.
Definition: genlist.cpp:201
struct genlist_link * genlist_link_get(const struct genlist *pgenlist, int idx)
Returns the link in the genlist at the position given by 'idx'.
Definition: genlist.cpp:190
void genlist_destroy(struct genlist *pgenlist)
Destroys the genlist.
Definition: genlist.cpp:45
int genlist_remove_all(struct genlist *pgenlist, const void *data)
Remove all elements of the genlist with the specified user-data pointer given by 'punlink'.
Definition: genlist.cpp:339
void genlist_pop_front(struct genlist *pgenlist)
Remove the first element of the genlist.
Definition: genlist.cpp:436
void * genlist_front(const struct genlist *pgenlist)
Returns the user-data pointer stored in the first element of the genlist.
Definition: genlist.cpp:220
void genlist_insert_before(struct genlist *pgenlist, void *data, struct genlist_link *plink)
Insert an item before the link.
Definition: genlist.cpp:502
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).
Definition: genlist.cpp:392
void genlist_unique(struct genlist *pgenlist)
Remove all duplicates of element from every consecutive group of equal elements in the list.
Definition: genlist.cpp:270
void genlist_insert_after(struct genlist *pgenlist, void *data, struct genlist_link *plink)
Insert an item after the link.
Definition: genlist.cpp:490
struct genlist * genlist_copy_full(const struct genlist *pgenlist, genlist_copy_fn_t copy_data_func, genlist_free_fn_t free_data_func) fc__warn_unused_result
Returns a new genlist that's a copy of the existing one.
Definition: genlist.cpp:152
static fc__warn_unused_result struct genlist_link * genlist_link_prev(const struct genlist_link *plink)
Definition: genlist.h:142
void genlist_sort(struct genlist *pgenlist, int(*compar)(const void *, const void *))
Sort the elements of a genlist.
Definition: genlist.cpp:587
void genlist_reverse(struct genlist *pgenlist)
Reverse the order of the elements in the genlist.
Definition: genlist.cpp:653
struct genlist_link * genlist_search(const struct genlist *pgenlist, const void *data)
Return the link where data is equal to 'data'.
Definition: genlist.cpp:538
void genlist_pop_back(struct genlist *pgenlist)
Remove the last element of the genlist.
Definition: genlist.cpp:448
void(* genlist_free_fn_t)(void *)
Definition: genlist.h:45
void *(* genlist_copy_fn_t)(const void *)
Definition: genlist.h:46
int genlist_size(const struct genlist *pgenlist)
Returns the number of elements stored in the genlist.
Definition: genlist.cpp:179
void genlist_shuffle(struct genlist *pgenlist)
Randomize the elements of a genlist using the Fisher-Yates shuffle.
Definition: genlist.cpp:619
bool genlist_remove(struct genlist *pgenlist, const void *data)
Remove an element of the genlist with the specified user-data pointer given by 'punlink'.
Definition: genlist.cpp:317
struct genlist * genlist_new_full(genlist_free_fn_t free_data_func) fc__warn_unused_result
Create a new empty genlist with a free data function.
Definition: genlist.cpp:30
struct genlist * genlist_new() fc__warn_unused_result
Create a new empty genlist.
Definition: genlist.cpp:25
struct genlist_link * tail_link
Definition: genlist.h:57
struct genlist_link * head_link
Definition: genlist.h:56
QMutex mutex
Definition: genlist.h:55
int nelements
Definition: genlist.h:54
genlist_free_fn_t free_data_func
Definition: genlist.h:58
#define fc__warn_unused_result
Definition: support.h:41