(* Wojciech Muła, $Id: myhash.ml,v 1.3 2006-06-04 08:34:03 wojtek Exp $ *) let itertop f hash = let prev = ref None in let aux key value = let prev' = !prev in begin prev := Some key; match prev' with None -> f key value | Some key' -> if key' <> key then f key value end; in Hashtbl.iter aux hash let foldtop f hash init = let prev = ref None in let aux key value acc = let prev' = !prev in begin prev := Some key; match prev' with None -> f key value acc | Some key' -> if key' <> key then f key value acc else acc end; in Hashtbl.fold aux hash init let keys hash = Hashtbl.fold (fun key value list -> key::list) hash [] let values hash = Hashtbl.fold (fun key value list -> value::list) hash [] let items hash = Hashtbl.fold (fun key value list -> (key,value)::list) hash [] let from_items2 l = let h = ref (Hashtbl.create (List.length l)) in let rec worker = function | [] -> () | (k,v)::xs -> Hashtbl.add !h k v; worker xs in worker l; !h let from_items keys values = let h = ref (Hashtbl.create (List.length keys)) in let rec worker = function | ([], []) -> () | (_ , []) -> failwith "from_items: v shorten then k" | ([], _ ) -> failwith "from_items: k shorten then v" | (k::ks, v::vs) -> Hashtbl.add !h k v; worker (ks, vs) in worker (keys,values); !h let findVariant h x = try Some (Hashtbl.find h x) with Not_found -> None let set_default h x d = try Hashtbl.find h x with Not_found -> Hashtbl.add h x d; d let remove_all hash key = let l = Hashtbl.find_all hash key in let n = List.length l in for i = 0 to n do Hashtbl.remove hash key done; l let replace_all hash key value = let removed = remove_all hash key in Hashtbl.add hash key value; removed let reverse_hash hash = let i = items hash in let i' = List.map (fun (k,v) -> (v,k)) i in from_items2 i'