]> git.ipfire.org Git - thirdparty/git.git/blob - strmap.h
strmap: add a strset sub-type
[thirdparty/git.git] / strmap.h
1 #ifndef STRMAP_H
2 #define STRMAP_H
3
4 #include "hashmap.h"
5
6 struct strmap {
7 struct hashmap map;
8 unsigned int strdup_strings:1;
9 };
10
11 struct strmap_entry {
12 struct hashmap_entry ent;
13 const char *key;
14 void *value;
15 };
16
17 int cmp_strmap_entry(const void *hashmap_cmp_fn_data,
18 const struct hashmap_entry *entry1,
19 const struct hashmap_entry *entry2,
20 const void *keydata);
21
22 #define STRMAP_INIT { \
23 .map = HASHMAP_INIT(cmp_strmap_entry, NULL), \
24 .strdup_strings = 1, \
25 }
26 #define STRINTMAP_INIT { \
27 .map = STRMAP_INIT, \
28 .default_value = 0, \
29 }
30 #define STRSET_INIT { .map = STRMAP_INIT }
31
32 /*
33 * Initialize the members of the strmap. Any keys added to the strmap will
34 * be strdup'ed with their memory managed by the strmap.
35 */
36 void strmap_init(struct strmap *map);
37
38 /*
39 * Same as strmap_init, but for those who want to control the memory management
40 * carefully instead of using the default of strdup_strings=1.
41 */
42 void strmap_init_with_options(struct strmap *map,
43 int strdup_strings);
44
45 /*
46 * Remove all entries from the map, releasing any allocated resources.
47 */
48 void strmap_clear(struct strmap *map, int free_values);
49
50 /*
51 * Similar to strmap_clear() but leaves map->map->table allocated and
52 * pre-sized so that subsequent uses won't need as many rehashings.
53 */
54 void strmap_partial_clear(struct strmap *map, int free_values);
55
56 /*
57 * Insert "str" into the map, pointing to "data".
58 *
59 * If an entry for "str" already exists, its data pointer is overwritten, and
60 * the original data pointer returned. Otherwise, returns NULL.
61 */
62 void *strmap_put(struct strmap *map, const char *str, void *data);
63
64 /*
65 * Return the strmap_entry mapped by "str", or NULL if there is not such
66 * an item in map.
67 */
68 struct strmap_entry *strmap_get_entry(struct strmap *map, const char *str);
69
70 /*
71 * Return the data pointer mapped by "str", or NULL if the entry does not
72 * exist.
73 */
74 void *strmap_get(struct strmap *map, const char *str);
75
76 /*
77 * Return non-zero iff "str" is present in the map. This differs from
78 * strmap_get() in that it can distinguish entries with a NULL data pointer.
79 */
80 int strmap_contains(struct strmap *map, const char *str);
81
82 /*
83 * Remove the given entry from the strmap. If the string isn't in the
84 * strmap, the map is not altered.
85 */
86 void strmap_remove(struct strmap *map, const char *str, int free_value);
87
88 /*
89 * Return how many entries the strmap has.
90 */
91 static inline unsigned int strmap_get_size(struct strmap *map)
92 {
93 return hashmap_get_size(&map->map);
94 }
95
96 /*
97 * Return whether the strmap is empty.
98 */
99 static inline int strmap_empty(struct strmap *map)
100 {
101 return strmap_get_size(map) == 0;
102 }
103
104 /*
105 * iterate through @map using @iter, @var is a pointer to a type strmap_entry
106 */
107 #define strmap_for_each_entry(mystrmap, iter, var) \
108 hashmap_for_each_entry(&(mystrmap)->map, iter, var, ent)
109
110
111 /*
112 * strintmap:
113 * A map of string -> int, typecasting the void* of strmap to an int.
114 *
115 * Primary differences:
116 * 1) Since the void* value is just an int in disguise, there is no value
117 * to free. (Thus one fewer argument to strintmap_clear)
118 * 2) strintmap_get() returns an int, or returns the default_value if the
119 * key is not found in the strintmap.
120 * 3) No strmap_put() equivalent; strintmap_set() and strintmap_incr()
121 * instead.
122 */
123
124 struct strintmap {
125 struct strmap map;
126 int default_value;
127 };
128
129 #define strintmap_for_each_entry(mystrmap, iter, var) \
130 strmap_for_each_entry(&(mystrmap)->map, iter, var)
131
132 static inline void strintmap_init(struct strintmap *map, int default_value)
133 {
134 strmap_init(&map->map);
135 map->default_value = default_value;
136 }
137
138 static inline void strintmap_init_with_options(struct strintmap *map,
139 int default_value,
140 int strdup_strings)
141 {
142 strmap_init_with_options(&map->map, strdup_strings);
143 map->default_value = default_value;
144 }
145
146 static inline void strintmap_clear(struct strintmap *map)
147 {
148 strmap_clear(&map->map, 0);
149 }
150
151 static inline void strintmap_partial_clear(struct strintmap *map)
152 {
153 strmap_partial_clear(&map->map, 0);
154 }
155
156 static inline int strintmap_contains(struct strintmap *map, const char *str)
157 {
158 return strmap_contains(&map->map, str);
159 }
160
161 static inline void strintmap_remove(struct strintmap *map, const char *str)
162 {
163 return strmap_remove(&map->map, str, 0);
164 }
165
166 static inline int strintmap_empty(struct strintmap *map)
167 {
168 return strmap_empty(&map->map);
169 }
170
171 static inline unsigned int strintmap_get_size(struct strintmap *map)
172 {
173 return strmap_get_size(&map->map);
174 }
175
176 /*
177 * Returns the value for str in the map. If str isn't found in the map,
178 * the map's default_value is returned.
179 */
180 static inline int strintmap_get(struct strintmap *map, const char *str)
181 {
182 struct strmap_entry *result = strmap_get_entry(&map->map, str);
183 if (!result)
184 return map->default_value;
185 return (intptr_t)result->value;
186 }
187
188 static inline void strintmap_set(struct strintmap *map, const char *str,
189 intptr_t v)
190 {
191 strmap_put(&map->map, str, (void *)v);
192 }
193
194 /*
195 * Increment the value for str by amt. If str isn't in the map, add it and
196 * set its value to default_value + amt.
197 */
198 void strintmap_incr(struct strintmap *map, const char *str, intptr_t amt);
199
200 /*
201 * strset:
202 * A set of strings.
203 *
204 * Primary differences with strmap:
205 * 1) The value is always NULL, and ignored. As there is no value to free,
206 * there is one fewer argument to strset_clear
207 * 2) No strset_get() because there is no value.
208 * 3) No strset_put(); use strset_add() instead.
209 */
210
211 struct strset {
212 struct strmap map;
213 };
214
215 #define strset_for_each_entry(mystrset, iter, var) \
216 strmap_for_each_entry(&(mystrset)->map, iter, var)
217
218 static inline void strset_init(struct strset *set)
219 {
220 strmap_init(&set->map);
221 }
222
223 static inline void strset_init_with_options(struct strset *set,
224 int strdup_strings)
225 {
226 strmap_init_with_options(&set->map, strdup_strings);
227 }
228
229 static inline void strset_clear(struct strset *set)
230 {
231 strmap_clear(&set->map, 0);
232 }
233
234 static inline void strset_partial_clear(struct strset *set)
235 {
236 strmap_partial_clear(&set->map, 0);
237 }
238
239 static inline int strset_contains(struct strset *set, const char *str)
240 {
241 return strmap_contains(&set->map, str);
242 }
243
244 static inline void strset_remove(struct strset *set, const char *str)
245 {
246 return strmap_remove(&set->map, str, 0);
247 }
248
249 static inline int strset_empty(struct strset *set)
250 {
251 return strmap_empty(&set->map);
252 }
253
254 static inline unsigned int strset_get_size(struct strset *set)
255 {
256 return strmap_get_size(&set->map);
257 }
258
259 /* Returns 1 if str is added to the set; returns 0 if str was already in set */
260 int strset_add(struct strset *set, const char *str);
261
262 #endif /* STRMAP_H */