0386656f3a73fa9ee1c512132426f50e97a50c83
[isl.git] / isl_map_to_basic_set.c
blob0386656f3a73fa9ee1c512132426f50e97a50c83
1 /*
2 * Copyright 2011 INRIA Saclay
3 * Copyright 2013 Ecole Normale Superieure
5 * Use of this software is governed by the MIT license
7 * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
8 * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
9 * 91893 Orsay, France
10 * and Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
13 #include <isl_map_to_basic_set.h>
15 struct isl_map_basic_set_pair {
16 isl_map *key;
17 isl_basic_set *val;
20 __isl_give isl_map_to_basic_set *isl_map_to_basic_set_alloc(isl_ctx *ctx,
21 int min_size)
23 isl_map_to_basic_set *hmap;
25 hmap = isl_calloc_type(ctx, isl_map_to_basic_set);
26 if (!hmap)
27 return NULL;
29 hmap->ctx = ctx;
30 isl_ctx_ref(ctx);
31 hmap->ref = 1;
33 if (isl_hash_table_init(ctx, &hmap->table, min_size) < 0)
34 return isl_map_to_basic_set_free(hmap);
36 return hmap;
39 static int free_pair(void **entry, void *user)
41 struct isl_map_basic_set_pair *pair = *entry;
42 isl_map_free(pair->key);
43 isl_basic_set_free(pair->val);
44 free(pair);
45 *entry = NULL;
46 return 0;
49 void *isl_map_to_basic_set_free(__isl_take isl_map_to_basic_set *hmap)
51 if (!hmap)
52 return NULL;
53 if (--hmap->ref > 0)
54 return NULL;
55 isl_hash_table_foreach(hmap->ctx, &hmap->table, &free_pair, NULL);
56 isl_hash_table_clear(&hmap->table);
57 isl_ctx_deref(hmap->ctx);
58 free(hmap);
59 return NULL;
62 isl_ctx *isl_map_to_basic_set_get_ctx(__isl_keep isl_map_to_basic_set *hmap)
64 return hmap ? hmap->ctx : NULL;
67 /* Add a mapping from "key" to "val" to the associative array
68 * pointed to by user.
70 static int add_key_val(__isl_take isl_map *key, __isl_take isl_basic_set *val,
71 void *user)
73 isl_map_to_basic_set **hmap = (isl_map_to_basic_set **) user;
75 *hmap = isl_map_to_basic_set_set(*hmap, key, val);
77 if (!*hmap)
78 return -1;
80 return 0;
83 __isl_give isl_map_to_basic_set *isl_map_to_basic_set_dup(
84 __isl_keep isl_map_to_basic_set *hmap)
86 isl_map_to_basic_set *dup;
88 if (!hmap)
89 return NULL;
91 dup = isl_map_to_basic_set_alloc(hmap->ctx, hmap->table.n);
92 if (isl_map_to_basic_set_foreach(hmap, &add_key_val, &dup) < 0)
93 return isl_map_to_basic_set_free(dup);
95 return dup;
98 __isl_give isl_map_to_basic_set *isl_map_to_basic_set_cow(
99 __isl_take isl_map_to_basic_set *hmap)
101 if (!hmap)
102 return NULL;
104 if (hmap->ref == 1)
105 return hmap;
106 hmap->ref--;
107 return isl_map_to_basic_set_dup(hmap);
110 __isl_give isl_map_to_basic_set *isl_map_to_basic_set_copy(
111 __isl_keep isl_map_to_basic_set *hmap)
113 if (!hmap)
114 return NULL;
116 hmap->ref++;
117 return hmap;
120 static int has_key(const void *entry, const void *key)
122 const struct isl_map_basic_set_pair *pair = entry;
123 isl_map *map = (isl_map *)key;
125 return isl_map_plain_is_equal(pair->key, map);
128 int isl_map_to_basic_set_has(__isl_keep isl_map_to_basic_set *hmap,
129 __isl_keep isl_map *key)
131 uint32_t hash;
133 if (!hmap)
134 return -1;
136 hash = isl_map_get_hash(key);
137 return !!isl_hash_table_find(hmap->ctx, &hmap->table, hash,
138 &has_key, key, 0);
141 __isl_give isl_basic_set *isl_map_to_basic_set_get(
142 __isl_keep isl_map_to_basic_set *hmap, __isl_take isl_map *key)
144 struct isl_hash_table_entry *entry;
145 struct isl_map_basic_set_pair *pair;
146 uint32_t hash;
148 if (!hmap || !key)
149 goto error;
151 hash = isl_map_get_hash(key);
152 entry = isl_hash_table_find(hmap->ctx, &hmap->table, hash,
153 &has_key, key, 0);
154 isl_map_free(key);
156 if (!entry)
157 return NULL;
159 pair = entry->data;
161 return isl_basic_set_copy(pair->val);
162 error:
163 isl_map_free(key);
164 return NULL;
167 /* Add a mapping from "key" to "val" to "hmap".
168 * If "key" was already mapped to something else, then that mapping
169 * is replaced.
170 * If key happened to be mapped to "val" already, then we leave
171 * "hmap" untouched.
173 __isl_give isl_map_to_basic_set *isl_map_to_basic_set_set(
174 __isl_take isl_map_to_basic_set *hmap,
175 __isl_take isl_map *key, __isl_take isl_basic_set *val)
177 struct isl_hash_table_entry *entry;
178 struct isl_map_basic_set_pair *pair;
179 uint32_t hash;
181 if (!hmap)
182 goto error;
184 hash = isl_map_get_hash(key);
185 entry = isl_hash_table_find(hmap->ctx, &hmap->table, hash,
186 &has_key, key, 0);
187 if (entry) {
188 int equal;
189 pair = entry->data;
190 equal = isl_basic_set_plain_is_equal(pair->val, val);
191 if (equal < 0)
192 goto error;
193 if (equal) {
194 isl_map_free(key);
195 isl_basic_set_free(val);
196 return hmap;
200 hmap = isl_map_to_basic_set_cow(hmap);
201 if (!hmap)
202 goto error;
204 entry = isl_hash_table_find(hmap->ctx, &hmap->table, hash,
205 &has_key, key, 1);
207 if (!entry)
208 goto error;
210 if (entry->data) {
211 pair = entry->data;
212 isl_basic_set_free(pair->val);
213 pair->val = val;
214 isl_map_free(key);
215 return hmap;
218 pair = isl_alloc_type(hmap->ctx, struct isl_map_basic_set_pair);
219 if (!pair)
220 goto error;
222 entry->data = pair;
223 pair->key = key;
224 pair->val = val;
225 return hmap;
226 error:
227 isl_map_free(key);
228 isl_basic_set_free(val);
229 return isl_map_to_basic_set_free(hmap);
232 /* Internal data structure for isl_map_to_basic_set_foreach.
234 * fn is the function that should be called on each entry.
235 * user is the user-specified final argument to fn.
237 struct isl_map_to_basic_set_foreach_data {
238 int (*fn)(__isl_take isl_map *key, __isl_take isl_basic_set *val,
239 void *user);
240 void *user;
243 /* Call data->fn on a copy of the key and value in *entry.
245 static int call_on_copy(void **entry, void *user)
247 struct isl_map_basic_set_pair *pair = *entry;
248 struct isl_map_to_basic_set_foreach_data *data;
249 data = (struct isl_map_to_basic_set_foreach_data *) user;
251 return data->fn(isl_map_copy(pair->key), isl_basic_set_copy(pair->val),
252 data->user);
255 /* Call "fn" on each pair of key and value in "hmap".
257 int isl_map_to_basic_set_foreach(__isl_keep isl_map_to_basic_set *hmap,
258 int (*fn)(__isl_take isl_map *key, __isl_take isl_basic_set *val,
259 void *user), void *user)
261 struct isl_map_to_basic_set_foreach_data data = { fn, user };
263 if (!hmap)
264 return -1;
266 return isl_hash_table_foreach(hmap->ctx, &hmap->table,
267 &call_on_copy, &data);
270 /* Internal data structure for print_pair.
272 * p is the printer on which the associative array is being printed.
273 * first is set if the current key-value pair is the first to be printed.
275 struct isl_map_to_basic_set_print_data {
276 isl_printer *p;
277 int first;
280 /* Print the given key-value pair to data->p.
282 static int print_pair(__isl_take isl_map *key, __isl_take isl_basic_set *val,
283 void *user)
285 struct isl_map_to_basic_set_print_data *data = user;
287 if (!data->first)
288 data->p = isl_printer_print_str(data->p, ", ");
289 data->p = isl_printer_print_map(data->p, key);
290 data->p = isl_printer_print_str(data->p, ": ");
291 data->p = isl_printer_print_basic_set(data->p, val);
292 data->first = 0;
294 isl_map_free(key);
295 isl_basic_set_free(val);
296 return 0;
299 /* Print the associative array to "p".
301 __isl_give isl_printer *isl_printer_print_map_to_basic_set(
302 __isl_take isl_printer *p, __isl_keep isl_map_to_basic_set *hmap)
304 struct isl_map_to_basic_set_print_data data;
306 if (!p || !hmap)
307 return isl_printer_free(p);
309 p = isl_printer_print_str(p, "{");
310 data.p = p;
311 data.first = 1;
312 if (isl_map_to_basic_set_foreach(hmap, &print_pair, &data) < 0)
313 data.p = isl_printer_free(data.p);
314 p = data.p;
315 p = isl_printer_print_str(p, "}");
317 return p;
320 void isl_map_to_basic_set_dump(__isl_keep isl_map_to_basic_set *hmap)
322 isl_printer *printer;
324 if (!hmap)
325 return;
327 printer = isl_printer_to_file(isl_map_to_basic_set_get_ctx(hmap),
328 stderr);
329 printer = isl_printer_print_map_to_basic_set(printer, hmap);
330 printer = isl_printer_end_line(printer);
332 isl_printer_free(printer);