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 xCAT(A,B) A ## B
17 #define CAT(A,B) xCAT(A,B)
18 #define KEY CAT(isl_,KEY_BASE)
19 #define VAL CAT(isl_,VAL_BASE)
20 #define xFN(TYPE,NAME) TYPE ## _ ## NAME
21 #define FN(TYPE,NAME) xFN(TYPE,NAME)
22 #define xHMAP(KEY,VAL_BASE) KEY ## _to_ ## VAL_BASE
23 #define yHMAP(KEY,VAL_BASE) xHMAP(KEY,VAL_BASE)
24 #define HMAP yHMAP(KEY,VAL_BASE)
25 #define HMAP_BASE yHMAP(KEY_BASE,VAL_BASE)
26 #define xS(TYPE1,TYPE2,NAME) struct isl_ ## TYPE1 ## _ ## TYPE2 ## _ ## NAME
27 #define yS(TYPE1,TYPE2,NAME) xS(TYPE1,TYPE2,NAME)
28 #define S(NAME) yS(KEY_BASE,VAL_BASE,NAME)
33 struct isl_hash_table table
;
41 __isl_give HMAP
*FN(HMAP
,alloc
)(isl_ctx
*ctx
, int min_size
)
45 hmap
= isl_calloc_type(ctx
, HMAP
);
53 if (isl_hash_table_init(ctx
, &hmap
->table
, min_size
) < 0)
54 return FN(HMAP
,free
)(hmap
);
59 static int free_pair(void **entry
, void *user
)
61 S(pair
) *pair
= *entry
;
62 FN(KEY
,free
)(pair
->key
);
63 FN(VAL
,free
)(pair
->val
);
69 __isl_null HMAP
*FN(HMAP
,free
)(__isl_take HMAP
*hmap
)
75 isl_hash_table_foreach(hmap
->ctx
, &hmap
->table
, &free_pair
, NULL
);
76 isl_hash_table_clear(&hmap
->table
);
77 isl_ctx_deref(hmap
->ctx
);
82 isl_ctx
*FN(HMAP
,get_ctx
)(__isl_keep HMAP
*hmap
)
84 return hmap
? hmap
->ctx
: NULL
;
87 /* Add a mapping from "key" to "val" to the associative array
90 static int add_key_val(__isl_take KEY
*key
, __isl_take VAL
*val
, void *user
)
92 HMAP
**hmap
= (HMAP
**) user
;
94 *hmap
= FN(HMAP
,set
)(*hmap
, key
, val
);
102 __isl_give HMAP
*FN(HMAP
,dup
)(__isl_keep HMAP
*hmap
)
109 dup
= FN(HMAP
,alloc
)(hmap
->ctx
, hmap
->table
.n
);
110 if (FN(HMAP
,foreach
)(hmap
, &add_key_val
, &dup
) < 0)
111 return FN(HMAP
,free
)(dup
);
116 __isl_give HMAP
*FN(HMAP
,cow
)(__isl_take HMAP
*hmap
)
124 return FN(HMAP
,dup
)(hmap
);
127 __isl_give HMAP
*FN(HMAP
,copy
)(__isl_keep HMAP
*hmap
)
136 static int has_key(const void *entry
, const void *c_key
)
138 const S(pair
) *pair
= entry
;
139 KEY
*key
= (KEY
*) c_key
;
141 return KEY_EQUAL(pair
->key
, key
);
144 int FN(HMAP
,has
)(__isl_keep HMAP
*hmap
, __isl_keep KEY
*key
)
151 hash
= FN(KEY
,get_hash
)(key
);
152 return !!isl_hash_table_find(hmap
->ctx
, &hmap
->table
, hash
,
156 __isl_give VAL
*FN(HMAP
,get
)(__isl_keep HMAP
*hmap
, __isl_take KEY
*key
)
158 struct isl_hash_table_entry
*entry
;
165 hash
= FN(KEY
,get_hash
)(key
);
166 entry
= isl_hash_table_find(hmap
->ctx
, &hmap
->table
, hash
,
175 return FN(VAL
,copy
)(pair
->val
);
181 /* Remove the mapping between "key" and its associated value (if any)
184 * If "key" is not mapped to anything, then we leave "hmap" untouched"
186 __isl_give HMAP
*FN(HMAP
,drop
)(__isl_take HMAP
*hmap
, __isl_take KEY
*key
)
188 struct isl_hash_table_entry
*entry
;
195 hash
= FN(KEY
,get_hash
)(key
);
196 entry
= isl_hash_table_find(hmap
->ctx
, &hmap
->table
, hash
,
203 hmap
= FN(HMAP
,cow
)(hmap
);
206 entry
= isl_hash_table_find(hmap
->ctx
, &hmap
->table
, hash
,
211 isl_die(hmap
->ctx
, isl_error_internal
,
212 "missing entry" , goto error
);
215 isl_hash_table_remove(hmap
->ctx
, &hmap
->table
, entry
);
216 FN(KEY
,free
)(pair
->key
);
217 FN(VAL
,free
)(pair
->val
);
227 /* Add a mapping from "key" to "val" to "hmap".
228 * If "key" was already mapped to something else, then that mapping
230 * If key happened to be mapped to "val" already, then we leave
233 __isl_give HMAP
*FN(HMAP
,set
)(__isl_take HMAP
*hmap
,
234 __isl_take KEY
*key
, __isl_take VAL
*val
)
236 struct isl_hash_table_entry
*entry
;
240 if (!hmap
|| !key
|| !val
)
243 hash
= FN(KEY
,get_hash
)(key
);
244 entry
= isl_hash_table_find(hmap
->ctx
, &hmap
->table
, hash
,
249 equal
= VAL_EQUAL(pair
->val
, val
);
259 hmap
= FN(HMAP
,cow
)(hmap
);
263 entry
= isl_hash_table_find(hmap
->ctx
, &hmap
->table
, hash
,
271 FN(VAL
,free
)(pair
->val
);
277 pair
= isl_alloc_type(hmap
->ctx
, S(pair
));
288 return FN(HMAP
,free
)(hmap
);
291 /* Internal data structure for isl_map_to_basic_set_foreach.
293 * fn is the function that should be called on each entry.
294 * user is the user-specified final argument to fn.
297 int (*fn
)(__isl_take KEY
*key
, __isl_take VAL
*val
, void *user
);
301 /* Call data->fn on a copy of the key and value in *entry.
303 static int call_on_copy(void **entry
, void *user
)
305 S(pair
) *pair
= *entry
;
306 S(foreach_data
) *data
= (S(foreach_data
) *) user
;
308 return data
->fn(FN(KEY
,copy
)(pair
->key
), FN(VAL
,copy
)(pair
->val
),
312 /* Call "fn" on each pair of key and value in "hmap".
314 int FN(HMAP
,foreach
)(__isl_keep HMAP
*hmap
,
315 int (*fn
)(__isl_take KEY
*key
, __isl_take VAL
*val
, void *user
),
318 S(foreach_data
) data
= { fn
, user
};
323 return isl_hash_table_foreach(hmap
->ctx
, &hmap
->table
,
324 &call_on_copy
, &data
);
327 /* Internal data structure for print_pair.
329 * p is the printer on which the associative array is being printed.
330 * first is set if the current key-value pair is the first to be printed.
337 /* Print the given key-value pair to data->p.
339 static int print_pair(__isl_take KEY
*key
, __isl_take VAL
*val
, void *user
)
341 S(print_data
) *data
= user
;
344 data
->p
= isl_printer_print_str(data
->p
, ", ");
345 data
->p
= FN(isl_printer_print
,KEY_BASE
)(data
->p
, key
);
346 data
->p
= isl_printer_print_str(data
->p
, ": ");
347 data
->p
= FN(isl_printer_print
,VAL_BASE
)(data
->p
, val
);
355 /* Print the associative array to "p".
357 __isl_give isl_printer
*FN(isl_printer_print
,HMAP_BASE
)(
358 __isl_take isl_printer
*p
, __isl_keep HMAP
*hmap
)
363 return isl_printer_free(p
);
365 p
= isl_printer_print_str(p
, "{");
368 if (FN(HMAP
,foreach
)(hmap
, &print_pair
, &data
) < 0)
369 data
.p
= isl_printer_free(data
.p
);
371 p
= isl_printer_print_str(p
, "}");
376 void FN(HMAP
,dump
)(__isl_keep HMAP
*hmap
)
378 isl_printer
*printer
;
383 printer
= isl_printer_to_file(FN(HMAP
,get_ctx
)(hmap
), stderr
);
384 printer
= FN(isl_printer_print
,HMAP_BASE
)(printer
, hmap
);
385 printer
= isl_printer_end_line(printer
);
387 isl_printer_free(printer
);