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,
10 * and Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
16 #define ISL_xCAT(A,B) A ## B
17 #define ISL_CAT(A,B) ISL_xCAT(A,B)
18 #define ISL_xFN(TYPE,NAME) TYPE ## _ ## NAME
19 #define ISL_FN(TYPE,NAME) ISL_xFN(TYPE,NAME)
20 #define ISL_xS(TYPE1,TYPE2,NAME) struct isl_ ## TYPE1 ## _ ## TYPE2 ## _ ## NAME
21 #define ISL_yS(TYPE1,TYPE2,NAME) ISL_xS(TYPE1,TYPE2,NAME)
22 #define ISL_S(NAME) ISL_yS(ISL_KEY,ISL_VAL,NAME)
27 struct isl_hash_table table
;
35 __isl_give ISL_HMAP
*ISL_FN(ISL_HMAP
,alloc
)(isl_ctx
*ctx
, int min_size
)
39 hmap
= isl_calloc_type(ctx
, ISL_HMAP
);
47 if (isl_hash_table_init(ctx
, &hmap
->table
, min_size
) < 0)
48 return ISL_FN(ISL_HMAP
,free
)(hmap
);
53 static isl_stat
free_pair(void **entry
, void *user
)
55 ISL_S(pair
) *pair
= *entry
;
56 ISL_FN(ISL_KEY
,free
)(pair
->key
);
57 ISL_FN(ISL_VAL
,free
)(pair
->val
);
63 __isl_null ISL_HMAP
*ISL_FN(ISL_HMAP
,free
)(__isl_take ISL_HMAP
*hmap
)
69 isl_hash_table_foreach(hmap
->ctx
, &hmap
->table
, &free_pair
, NULL
);
70 isl_hash_table_clear(&hmap
->table
);
71 isl_ctx_deref(hmap
->ctx
);
76 isl_ctx
*ISL_FN(ISL_HMAP
,get_ctx
)(__isl_keep ISL_HMAP
*hmap
)
78 return hmap
? hmap
->ctx
: NULL
;
81 /* Add a mapping from "key" to "val" to the associative array
84 static isl_stat
add_key_val(__isl_take ISL_KEY
*key
, __isl_take ISL_VAL
*val
,
87 ISL_HMAP
**hmap
= (ISL_HMAP
**) user
;
89 *hmap
= ISL_FN(ISL_HMAP
,set
)(*hmap
, key
, val
);
92 return isl_stat_error
;
97 __isl_give ISL_HMAP
*ISL_FN(ISL_HMAP
,dup
)(__isl_keep ISL_HMAP
*hmap
)
104 dup
= ISL_FN(ISL_HMAP
,alloc
)(hmap
->ctx
, hmap
->table
.n
);
105 if (ISL_FN(ISL_HMAP
,foreach
)(hmap
, &add_key_val
, &dup
) < 0)
106 return ISL_FN(ISL_HMAP
,free
)(dup
);
111 __isl_give ISL_HMAP
*ISL_FN(ISL_HMAP
,cow
)(__isl_take ISL_HMAP
*hmap
)
119 return ISL_FN(ISL_HMAP
,dup
)(hmap
);
122 __isl_give ISL_HMAP
*ISL_FN(ISL_HMAP
,copy
)(__isl_keep ISL_HMAP
*hmap
)
131 static int has_key(const void *entry
, const void *c_key
)
133 const ISL_S(pair
) *pair
= entry
;
134 ISL_KEY
*key
= (ISL_KEY
*) c_key
;
136 return ISL_KEY_IS_EQUAL(pair
->key
, key
);
139 /* If "hmap" contains a value associated to "key", then return
140 * (isl_bool_true, copy of value).
142 * (isl_bool_false, NULL).
143 * If an error occurs, then return
144 * (isl_bool_error, NULL).
146 __isl_give
ISL_MAYBE(ISL_VAL
) ISL_FN(ISL_HMAP
,try_get
)(
147 __isl_keep ISL_HMAP
*hmap
, __isl_keep ISL_KEY
*key
)
149 struct isl_hash_table_entry
*entry
;
152 ISL_MAYBE(ISL_VAL
) res
= { isl_bool_false
, NULL
};
157 hash
= ISL_FN(ISL_KEY
,get_hash
)(key
);
158 entry
= isl_hash_table_find(hmap
->ctx
, &hmap
->table
, hash
,
166 res
.valid
= isl_bool_true
;
167 res
.value
= ISL_FN(ISL_VAL
,copy
)(pair
->val
);
169 res
.valid
= isl_bool_error
;
172 res
.valid
= isl_bool_error
;
177 /* If "hmap" contains a value associated to "key", then return
178 * isl_bool_true. Otherwise, return isl_bool_false.
179 * Return isl_bool_error on error.
181 isl_bool
ISL_FN(ISL_HMAP
,has
)(__isl_keep ISL_HMAP
*hmap
,
182 __isl_keep ISL_KEY
*key
)
184 ISL_MAYBE(ISL_VAL
) res
;
186 res
= ISL_FN(ISL_HMAP
,try_get
)(hmap
, key
);
187 ISL_FN(ISL_VAL
,free
)(res
.value
);
192 /* If "hmap" contains a value associated to "key", then return
193 * a copy of that value. Otherwise, return NULL.
194 * Return NULL on error.
196 __isl_give ISL_VAL
*ISL_FN(ISL_HMAP
,get
)(__isl_keep ISL_HMAP
*hmap
,
197 __isl_take ISL_KEY
*key
)
201 res
= ISL_FN(ISL_HMAP
,try_get
)(hmap
, key
).value
;
202 ISL_FN(ISL_KEY
,free
)(key
);
206 /* Remove the mapping between "key" and its associated value (if any)
209 * If "key" is not mapped to anything, then we leave "hmap" untouched"
211 __isl_give ISL_HMAP
*ISL_FN(ISL_HMAP
,drop
)(__isl_take ISL_HMAP
*hmap
,
212 __isl_take ISL_KEY
*key
)
214 struct isl_hash_table_entry
*entry
;
221 hash
= ISL_FN(ISL_KEY
,get_hash
)(key
);
222 entry
= isl_hash_table_find(hmap
->ctx
, &hmap
->table
, hash
,
225 ISL_FN(ISL_KEY
,free
)(key
);
229 hmap
= ISL_FN(ISL_HMAP
,cow
)(hmap
);
232 entry
= isl_hash_table_find(hmap
->ctx
, &hmap
->table
, hash
,
234 ISL_FN(ISL_KEY
,free
)(key
);
237 isl_die(hmap
->ctx
, isl_error_internal
,
238 "missing entry" , goto error
);
241 isl_hash_table_remove(hmap
->ctx
, &hmap
->table
, entry
);
242 ISL_FN(ISL_KEY
,free
)(pair
->key
);
243 ISL_FN(ISL_VAL
,free
)(pair
->val
);
248 ISL_FN(ISL_KEY
,free
)(key
);
249 ISL_FN(ISL_HMAP
,free
)(hmap
);
253 /* Add a mapping from "key" to "val" to "hmap".
254 * If "key" was already mapped to something else, then that mapping
256 * If key happened to be mapped to "val" already, then we leave
259 __isl_give ISL_HMAP
*ISL_FN(ISL_HMAP
,set
)(__isl_take ISL_HMAP
*hmap
,
260 __isl_take ISL_KEY
*key
, __isl_take ISL_VAL
*val
)
262 struct isl_hash_table_entry
*entry
;
266 if (!hmap
|| !key
|| !val
)
269 hash
= ISL_FN(ISL_KEY
,get_hash
)(key
);
270 entry
= isl_hash_table_find(hmap
->ctx
, &hmap
->table
, hash
,
275 equal
= ISL_VAL_IS_EQUAL(pair
->val
, val
);
279 ISL_FN(ISL_KEY
,free
)(key
);
280 ISL_FN(ISL_VAL
,free
)(val
);
285 hmap
= ISL_FN(ISL_HMAP
,cow
)(hmap
);
289 entry
= isl_hash_table_find(hmap
->ctx
, &hmap
->table
, hash
,
297 ISL_FN(ISL_VAL
,free
)(pair
->val
);
299 ISL_FN(ISL_KEY
,free
)(key
);
303 pair
= isl_alloc_type(hmap
->ctx
, ISL_S(pair
));
312 ISL_FN(ISL_KEY
,free
)(key
);
313 ISL_FN(ISL_VAL
,free
)(val
);
314 return ISL_FN(ISL_HMAP
,free
)(hmap
);
317 /* Internal data structure for isl_map_to_basic_set_foreach.
319 * fn is the function that should be called on each entry.
320 * user is the user-specified final argument to fn.
322 ISL_S(foreach_data
) {
323 isl_stat (*fn
)(__isl_take ISL_KEY
*key
, __isl_take ISL_VAL
*val
,
328 /* Call data->fn on a copy of the key and value in *entry.
330 static isl_stat
call_on_copy(void **entry
, void *user
)
332 ISL_S(pair
) *pair
= *entry
;
333 ISL_S(foreach_data
) *data
= (ISL_S(foreach_data
) *) user
;
335 return data
->fn(ISL_FN(ISL_KEY
,copy
)(pair
->key
),
336 ISL_FN(ISL_VAL
,copy
)(pair
->val
), data
->user
);
339 /* Call "fn" on each pair of key and value in "hmap".
341 isl_stat
ISL_FN(ISL_HMAP
,foreach
)(__isl_keep ISL_HMAP
*hmap
,
342 isl_stat (*fn
)(__isl_take ISL_KEY
*key
, __isl_take ISL_VAL
*val
,
346 ISL_S(foreach_data
) data
= { fn
, user
};
349 return isl_stat_error
;
351 return isl_hash_table_foreach(hmap
->ctx
, &hmap
->table
,
352 &call_on_copy
, &data
);
355 /* Internal data structure for print_pair.
357 * p is the printer on which the associative array is being printed.
358 * first is set if the current key-value pair is the first to be printed.
365 /* Print the given key-value pair to data->p.
367 static isl_stat
print_pair(__isl_take ISL_KEY
*key
, __isl_take ISL_VAL
*val
,
370 ISL_S(print_data
) *data
= user
;
373 data
->p
= isl_printer_print_str(data
->p
, ", ");
374 data
->p
= ISL_KEY_PRINT(data
->p
, key
);
375 data
->p
= isl_printer_print_str(data
->p
, ": ");
376 data
->p
= ISL_VAL_PRINT(data
->p
, val
);
379 ISL_FN(ISL_KEY
,free
)(key
);
380 ISL_FN(ISL_VAL
,free
)(val
);
384 /* Print the associative array to "p".
386 __isl_give isl_printer
*ISL_FN(isl_printer_print
,ISL_HMAP_SUFFIX
)(
387 __isl_take isl_printer
*p
, __isl_keep ISL_HMAP
*hmap
)
389 ISL_S(print_data
) data
;
392 return isl_printer_free(p
);
394 p
= isl_printer_print_str(p
, "{");
397 if (ISL_FN(ISL_HMAP
,foreach
)(hmap
, &print_pair
, &data
) < 0)
398 data
.p
= isl_printer_free(data
.p
);
400 p
= isl_printer_print_str(p
, "}");
405 void ISL_FN(ISL_HMAP
,dump
)(__isl_keep ISL_HMAP
*hmap
)
407 isl_printer
*printer
;
412 printer
= isl_printer_to_file(ISL_FN(ISL_HMAP
,get_ctx
)(hmap
), stderr
);
413 printer
= ISL_FN(isl_printer_print
,ISL_HMAP_SUFFIX
)(printer
, hmap
);
414 printer
= isl_printer_end_line(printer
);
416 isl_printer_free(printer
);