From de494e9667eba7e263a7e67d2f038ffbe2421741 Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Mon, 20 Oct 2014 18:28:44 +0200 Subject: [PATCH] a bunch of useful functions in CCMap --- core/CCMap.ml | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++ core/CCMap.mli | 25 ++++++++++++++++ 2 files changed, 104 insertions(+) diff --git a/core/CCMap.ml b/core/CCMap.ml index bb92ab80..f2b7c50b 100644 --- a/core/CCMap.ml +++ b/core/CCMap.ml @@ -26,16 +26,95 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (** {1 Extensions of Standard Map} *) +type 'a sequence = ('a -> unit) -> unit +type 'a printer = Buffer.t -> 'a -> unit +type 'a formatter = Format.formatter -> 'a -> unit + module type S = sig include Map.S + val get : key -> 'a t -> 'a option + (** Safe version of {!find} *) + + val update : key -> ('a option -> 'a option) -> 'a t -> 'a t + (** [update k f m] calls [f (Some v)] if [find k m = v], + otherwise it calls [f None]. In any case, if the result is [None] + [k] is removed from [m], and if the result is [Some v'] then + [add k v' m] is returned. *) + + val of_seq : (key * 'a) sequence -> 'a t + + val to_seq : 'a t -> (key * 'a) sequence + + val of_list : (key * 'a) list -> 'a t + val to_list : 'a t -> (key * 'a) list + + val pp : ?start:string -> ?stop:string -> ?arrow:string -> ?sep:string -> + key printer -> 'a printer -> 'a t printer + + val print : ?start:string -> ?stop:string -> ?arrow:string -> ?sep:string -> + key formatter -> 'a formatter -> 'a t formatter end module Make(O : Map.OrderedType) = struct include Map.Make(O) + let get k m = + try Some (find k m) + with Not_found -> None + + let update k f m = + let x = + try f (Some (find k m)) + with Not_found -> f None + in + match x with + | None -> remove k m + | Some v' -> add k v' m + + let of_seq s = + let m = ref empty in + s (fun (k,v) -> m := add k v !m); + !m + + let to_seq m yield = + iter (fun k v -> yield (k,v)) m + + let of_list l = + List.fold_left + (fun m (k,v) -> add k v m) empty l + let to_list m = fold (fun k v acc -> (k,v)::acc) m [] + + let pp ?(start="{") ?(stop="}") ?(arrow="->") ?(sep=", ") pp_k pp_v buf m = + let first = ref true in + Buffer.add_string buf start; + iter + (fun k v -> + if !first then first := false else Buffer.add_string buf sep; + pp_k buf k; + Buffer.add_string buf arrow; + pp_v buf v + ) m; + Buffer.add_string buf stop + + (*$T + CCPrint.to_string (pp CCPrint.int) [1;2;3] = "[1, 2, 3]" + *) + + let print ?(start="[") ?(stop="]") ?(arrow="->") ?(sep=", ") pp_k pp_v fmt m = + Format.pp_print_string fmt start; + let first = ref true in + iter + (fun k v -> + if !first then first := false else Format.pp_print_string fmt sep; + pp_k fmt k; + Format.pp_print_string fmt arrow; + pp_v fmt v; + Format.pp_print_cut fmt () + ) m; + Format.pp_print_string fmt stop end diff --git a/core/CCMap.mli b/core/CCMap.mli index 25493a22..385c714a 100644 --- a/core/CCMap.mli +++ b/core/CCMap.mli @@ -29,10 +29,35 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Provide useful functions and iterators on [Map.S] @since NEXT_RELEASE *) +type 'a sequence = ('a -> unit) -> unit +type 'a printer = Buffer.t -> 'a -> unit +type 'a formatter = Format.formatter -> 'a -> unit + module type S = sig include Map.S + val get : key -> 'a t -> 'a option + (** Safe version of {!find} *) + + val update : key -> ('a option -> 'a option) -> 'a t -> 'a t + (** [update k f m] calls [f (Some v)] if [find k m = v], + otherwise it calls [f None]. In any case, if the result is [None] + [k] is removed from [m], and if the result is [Some v'] then + [add k v' m] is returned. *) + + val of_seq : (key * 'a) sequence -> 'a t + + val to_seq : 'a t -> (key * 'a) sequence + + val of_list : (key * 'a) list -> 'a t + val to_list : 'a t -> (key * 'a) list + + val pp : ?start:string -> ?stop:string -> ?arrow:string -> ?sep:string -> + key printer -> 'a printer -> 'a t printer + + val print : ?start:string -> ?stop:string -> ?arrow:string -> ?sep:string -> + key formatter -> 'a formatter -> 'a t formatter end module Make(O : Map.OrderedType) : S