mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-06 11:15:31 -05:00
add functions from 4.05 into CC{Map,Set}
This commit is contained in:
parent
170d7662e7
commit
d09820b916
4 changed files with 233 additions and 13 deletions
|
|
@ -23,6 +23,31 @@ module type S = sig
|
||||||
[k] is removed from [m], and if the result is [Some v'] then
|
[k] is removed from [m], and if the result is [Some v'] then
|
||||||
[add k v' m] is returned. *)
|
[add k v' m] is returned. *)
|
||||||
|
|
||||||
|
val choose_opt : 'a t -> (key * 'a) option
|
||||||
|
(** Safe version of {!choose}
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val min_binding_opt : 'a t -> (key * 'a) option
|
||||||
|
(** Safe version of {!min_binding}
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val max_binding_opt : 'a t -> (key * 'a) option
|
||||||
|
(** Safe version of {!max_binding}
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val find_opt : key -> 'a t -> 'a option
|
||||||
|
(** Safe version of {!find}
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val find_first : (key -> bool) -> 'a t -> key * 'a
|
||||||
|
(** Find smallest binding satisfying the monotonic predicate.
|
||||||
|
See {!Map.S.find_first}.
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val find_first_opt : (key -> bool) -> 'a t -> (key * 'a) option
|
||||||
|
(** Safe version of {!find_first}
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val merge_safe :
|
val merge_safe :
|
||||||
f:(key -> [`Left of 'a | `Right of 'b | `Both of 'a * 'b] -> 'c option) ->
|
f:(key -> [`Left of 'a | `Right of 'b | `Both of 'a * 'b] -> 'c option) ->
|
||||||
'a t -> 'b t -> 'c t
|
'a t -> 'b t -> 'c t
|
||||||
|
|
@ -35,6 +60,7 @@ module type S = sig
|
||||||
@since 1.4 *)
|
@since 1.4 *)
|
||||||
|
|
||||||
val of_seq : (key * 'a) sequence -> 'a t
|
val of_seq : (key * 'a) sequence -> 'a t
|
||||||
|
(** Same as {!of_list} *)
|
||||||
|
|
||||||
val add_seq : 'a t -> (key * 'a) sequence -> 'a t
|
val add_seq : 'a t -> (key * 'a) sequence -> 'a t
|
||||||
(** @since 0.14 *)
|
(** @since 0.14 *)
|
||||||
|
|
@ -42,6 +68,10 @@ module type S = sig
|
||||||
val to_seq : 'a t -> (key * 'a) sequence
|
val to_seq : 'a t -> (key * 'a) sequence
|
||||||
|
|
||||||
val of_list : (key * 'a) list -> 'a t
|
val of_list : (key * 'a) list -> 'a t
|
||||||
|
(** Build a map from the given list of bindings [k_i -> v_i],
|
||||||
|
added in order using {!add}.
|
||||||
|
If a key occurs several times, only its last binding
|
||||||
|
will be present in the result. *)
|
||||||
|
|
||||||
val add_list : 'a t -> (key * 'a) list -> 'a t
|
val add_list : 'a t -> (key * 'a) list -> 'a t
|
||||||
(** @since 0.14 *)
|
(** @since 0.14 *)
|
||||||
|
|
@ -62,12 +92,70 @@ module type S = sig
|
||||||
end
|
end
|
||||||
|
|
||||||
module Make(O : Map.OrderedType) = struct
|
module Make(O : Map.OrderedType) = struct
|
||||||
include Map.Make(O)
|
module M = Map.Make(O)
|
||||||
|
|
||||||
let get k m =
|
(* overload [union] if it's not in [M] *)
|
||||||
try Some (find k m)
|
let union f a b =
|
||||||
|
M.merge
|
||||||
|
(fun k v1 v2 -> match v1, v2 with
|
||||||
|
| None, None -> assert false
|
||||||
|
| None, (Some _ as r) -> r
|
||||||
|
| Some _ as r, None -> r
|
||||||
|
| Some v1, Some v2 -> f k v1 v2)
|
||||||
|
a b
|
||||||
|
|
||||||
|
let choose_opt m =
|
||||||
|
try Some (M.choose m)
|
||||||
with Not_found -> None
|
with Not_found -> None
|
||||||
|
|
||||||
|
let find_opt k m =
|
||||||
|
try Some (M.find k m)
|
||||||
|
with Not_found -> None
|
||||||
|
|
||||||
|
let max_binding_opt m =
|
||||||
|
try Some (M.max_binding m)
|
||||||
|
with Not_found -> None
|
||||||
|
|
||||||
|
let min_binding_opt m =
|
||||||
|
try Some (M.min_binding m)
|
||||||
|
with Not_found -> None
|
||||||
|
|
||||||
|
exception Find_binding_exit
|
||||||
|
|
||||||
|
let find_first_opt f m =
|
||||||
|
let res = ref None in
|
||||||
|
try
|
||||||
|
M.iter
|
||||||
|
(fun k v ->
|
||||||
|
if f k then (
|
||||||
|
res := Some (k,v);
|
||||||
|
raise Find_binding_exit
|
||||||
|
))
|
||||||
|
m;
|
||||||
|
None
|
||||||
|
with Find_binding_exit ->
|
||||||
|
!res
|
||||||
|
|
||||||
|
let find_first f m = match find_first_opt f m with
|
||||||
|
| None -> raise Not_found
|
||||||
|
| Some (k,v) -> k, v
|
||||||
|
|
||||||
|
(* linear time, must traverse the whole map… *)
|
||||||
|
let find_last_opt f m =
|
||||||
|
let res = ref None in
|
||||||
|
M.iter
|
||||||
|
(fun k v -> if f k then res := Some (k,v))
|
||||||
|
m;
|
||||||
|
!res
|
||||||
|
|
||||||
|
let find_last f m = match find_last_opt f m with
|
||||||
|
| None -> raise Not_found
|
||||||
|
| Some (k,v) -> k, v
|
||||||
|
|
||||||
|
include M
|
||||||
|
|
||||||
|
let get = find_opt
|
||||||
|
|
||||||
let get_or k m ~default =
|
let get_or k m ~default =
|
||||||
try find k m
|
try find k m
|
||||||
with Not_found -> default
|
with Not_found -> default
|
||||||
|
|
@ -90,15 +178,6 @@ module Make(O : Map.OrderedType) = struct
|
||||||
| Some v1, Some v2 -> f k (`Both (v1,v2)))
|
| Some v1, Some v2 -> f k (`Both (v1,v2)))
|
||||||
a b
|
a b
|
||||||
|
|
||||||
let union f a b =
|
|
||||||
merge
|
|
||||||
(fun k v1 v2 -> match v1, v2 with
|
|
||||||
| None, None -> assert false
|
|
||||||
| None, (Some _ as r) -> r
|
|
||||||
| Some _ as r, None -> r
|
|
||||||
| Some v1, Some v2 -> f k v1 v2)
|
|
||||||
a b
|
|
||||||
|
|
||||||
let add_seq m s =
|
let add_seq m s =
|
||||||
let m = ref m in
|
let m = ref m in
|
||||||
s (fun (k,v) -> m := add k v !m);
|
s (fun (k,v) -> m := add k v !m);
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,31 @@ module type S = sig
|
||||||
[k] is removed from [m], and if the result is [Some v'] then
|
[k] is removed from [m], and if the result is [Some v'] then
|
||||||
[add k v' m] is returned. *)
|
[add k v' m] is returned. *)
|
||||||
|
|
||||||
|
val choose_opt : 'a t -> (key * 'a) option
|
||||||
|
(** Safe version of {!choose}
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val min_binding_opt : 'a t -> (key * 'a) option
|
||||||
|
(** Safe version of {!min_binding}
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val max_binding_opt : 'a t -> (key * 'a) option
|
||||||
|
(** Safe version of {!max_binding}
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val find_opt : key -> 'a t -> 'a option
|
||||||
|
(** Safe version of {!find}
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val find_first : (key -> bool) -> 'a t -> key * 'a
|
||||||
|
(** Find smallest binding satisfying the monotonic predicate.
|
||||||
|
See {!Map.S.find_first}.
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val find_first_opt : (key -> bool) -> 'a t -> (key * 'a) option
|
||||||
|
(** Safe version of {!find_first}
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val merge_safe :
|
val merge_safe :
|
||||||
f:(key -> [`Left of 'a | `Right of 'b | `Both of 'a * 'b] -> 'c option) ->
|
f:(key -> [`Left of 'a | `Right of 'b | `Both of 'a * 'b] -> 'c option) ->
|
||||||
'a t -> 'b t -> 'c t
|
'a t -> 'b t -> 'c t
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,38 @@ type 'a printer = Format.formatter -> 'a -> unit
|
||||||
module type S = sig
|
module type S = sig
|
||||||
include Set.S
|
include Set.S
|
||||||
|
|
||||||
|
val min_elt_opt : t -> elt option
|
||||||
|
(** Safe version of {!min_elt}
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val max_elt_opt : t -> elt option
|
||||||
|
(** Safe version of {!max_elt}
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val choose_opt : t -> elt option
|
||||||
|
(** Safe version of {!choose}
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val find_opt : elt -> t -> elt option
|
||||||
|
(** Safe version of {!find}
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val find_first : (elt -> bool) -> t -> elt
|
||||||
|
(** Find minimum element satisfying predicate
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val find_first_opt : (elt -> bool) -> t -> elt option
|
||||||
|
(** Safe version of {!find_first}
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val find_last : (elt -> bool) -> t -> elt
|
||||||
|
(** Find maximum element satisfying predicate
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val find_last_opt : (elt -> bool) -> t -> elt option
|
||||||
|
(** Safe version of {!find_last}
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val of_seq : elt sequence -> t
|
val of_seq : elt sequence -> t
|
||||||
|
|
||||||
val add_seq : t -> elt sequence -> t
|
val add_seq : t -> elt sequence -> t
|
||||||
|
|
@ -17,6 +49,8 @@ module type S = sig
|
||||||
val to_seq : t -> elt sequence
|
val to_seq : t -> elt sequence
|
||||||
|
|
||||||
val of_list : elt list -> t
|
val of_list : elt list -> t
|
||||||
|
(** Build a set from the given list of elements,
|
||||||
|
added in order using {!add}. *)
|
||||||
|
|
||||||
val add_list : t -> elt list -> t
|
val add_list : t -> elt list -> t
|
||||||
(** @since 0.14 *)
|
(** @since 0.14 *)
|
||||||
|
|
@ -29,7 +63,57 @@ module type S = sig
|
||||||
end
|
end
|
||||||
|
|
||||||
module Make(O : Map.OrderedType) = struct
|
module Make(O : Map.OrderedType) = struct
|
||||||
include Set.Make(O)
|
module S = Set.Make(O)
|
||||||
|
|
||||||
|
let find_opt x s =
|
||||||
|
try Some (S.find x s)
|
||||||
|
with Not_found -> None
|
||||||
|
|
||||||
|
let choose_opt s =
|
||||||
|
try Some (S.choose s)
|
||||||
|
with Not_found -> None
|
||||||
|
|
||||||
|
let min_elt_opt s =
|
||||||
|
try Some (S.min_elt s)
|
||||||
|
with Not_found -> None
|
||||||
|
|
||||||
|
let max_elt_opt s =
|
||||||
|
try Some (S.max_elt s)
|
||||||
|
with Not_found -> None
|
||||||
|
|
||||||
|
exception Find_binding_exit
|
||||||
|
|
||||||
|
let find_first_opt f m =
|
||||||
|
let res = ref None in
|
||||||
|
try
|
||||||
|
S.iter
|
||||||
|
(fun x ->
|
||||||
|
if f x then (
|
||||||
|
res := Some x;
|
||||||
|
raise Find_binding_exit
|
||||||
|
))
|
||||||
|
m;
|
||||||
|
None
|
||||||
|
with Find_binding_exit ->
|
||||||
|
!res
|
||||||
|
|
||||||
|
let find_first f m = match find_first_opt f m with
|
||||||
|
| None -> raise Not_found
|
||||||
|
| Some x -> x
|
||||||
|
|
||||||
|
(* linear time, must traverse the whole set… *)
|
||||||
|
let find_last_opt f m =
|
||||||
|
let res = ref None in
|
||||||
|
S.iter
|
||||||
|
(fun x -> if f x then res := Some x)
|
||||||
|
m;
|
||||||
|
!res
|
||||||
|
|
||||||
|
let find_last f m = match find_last_opt f m with
|
||||||
|
| None -> raise Not_found
|
||||||
|
| Some x -> x
|
||||||
|
|
||||||
|
include S
|
||||||
|
|
||||||
let add_seq set seq =
|
let add_seq set seq =
|
||||||
let set = ref set in
|
let set = ref set in
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,38 @@ type 'a printer = Format.formatter -> 'a -> unit
|
||||||
module type S = sig
|
module type S = sig
|
||||||
include Set.S
|
include Set.S
|
||||||
|
|
||||||
|
val min_elt_opt : t -> elt option
|
||||||
|
(** Safe version of {!min_elt}
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val max_elt_opt : t -> elt option
|
||||||
|
(** Safe version of {!max_elt}
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val choose_opt : t -> elt option
|
||||||
|
(** Safe version of {!choose}
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val find_opt : elt -> t -> elt option
|
||||||
|
(** Safe version of {!find}
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val find_first : (elt -> bool) -> t -> elt
|
||||||
|
(** Find minimum element satisfying predicate
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val find_first_opt : (elt -> bool) -> t -> elt option
|
||||||
|
(** Safe version of {!find_first}
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val find_last : (elt -> bool) -> t -> elt
|
||||||
|
(** Find maximum element satisfying predicate
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
|
val find_last_opt : (elt -> bool) -> t -> elt option
|
||||||
|
(** Safe version of {!find_last}
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val of_seq : elt sequence -> t
|
val of_seq : elt sequence -> t
|
||||||
|
|
||||||
val add_seq : t -> elt sequence -> t
|
val add_seq : t -> elt sequence -> t
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue