Source file CCSet.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
(* This file is free software, part of containers. See file "license" for more details. *)

(** {1 Wrapper around Set} *)

type 'a iter = ('a -> unit) -> unit
type 'a printer = Format.formatter -> 'a -> unit

module type OrderedType = Set.OrderedType

module type S = sig
  include Set.S

  val min_elt_opt : t -> elt option
  (** Safe version of {!min_elt}.
      @since 1.5 *)

  val max_elt_opt : t -> elt option
  (** Safe version of {!max_elt}.
      @since 1.5 *)

  val choose_opt : t -> elt option
  (** Safe version of {!choose}.
      @since 1.5 *)

  val find_opt : elt -> t -> elt option
  (** Safe version of {!find}.
      @since 1.5 *)

  val find_first : (elt -> bool) -> t -> elt
  (** Find minimum element satisfying predicate.
      @since 1.5 *)

  val find_first_opt : (elt -> bool) -> t -> elt option
  (** Safe version of {!find_first}.
      @since 1.5 *)

  val find_first_map : (elt -> 'a option) -> t -> 'a option
  (** [find_first_map f s] find the minimum element [x] of [s] such that [f x = Some y]
      and return [Some y]. Otherwise returns [None].
      @since 3.12 *)

  val find_last : (elt -> bool) -> t -> elt
  (** Find maximum element satisfying predicate.
      @since 1.5 *)

  val find_last_opt : (elt -> bool) -> t -> elt option
  (** Safe version of {!find_last}.
      @since 1.5 *)

  val find_last_map : (elt -> 'a option) -> t -> 'a option
  (** [find_last_map f s] find the maximum element [x] of [s] such that [f x = Some y]
      and return [Some y]. Otherwise returns [None].
      @since 3.12 *)

  val of_iter : elt iter -> t
  (** Build a set from the given [iter] of elements.
      @since 2.8 *)

  val of_seq : elt Seq.t -> t
  (** Build a set from the given [seq] of elements.
      @since 3.0 *)

  val add_iter : t -> elt iter -> t
  (** @since 2.8 *)

  val add_seq : elt Seq.t -> t -> t
  (** @since 3.0 *)

  val to_iter : t -> elt iter
  (** [to_iter t] converts the set [t] to a [iter] of the elements.
      @since 2.8 *)

  val add_list : t -> elt list -> t
  (** @since 0.14 *)

  val to_list : t -> elt list
  (** [to_list t] converts the set [t] to a list of the elements. *)

  val to_string :
    ?start:string ->
    ?stop:string ->
    ?sep:string ->
    (elt -> string) ->
    t ->
    string
  (**  Print the set in a string
       @since 2.7 *)

  val pp :
    ?pp_start:unit printer ->
    ?pp_stop:unit printer ->
    ?pp_sep:unit printer ->
    elt printer ->
    t printer
  (** Print the set. *)
end

module Make (O : Map.OrderedType) = struct
  module S = Set.Make (O)

  (* backport functions from recent stdlib.
     they will be shadowed by inclusion of [S] if present. *)

  [@@@ocaml.warning "-32"]

  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

  let find_first_map f m =
    let res = ref None in
    try
      S.iter
        (fun x ->
          match f x with
          | None -> ()
          | Some y ->
            res := Some y;
            raise Find_binding_exit)
        m;
      None
    with Find_binding_exit -> !res

  (* 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

  [@@@ocaml.warning "+32"]

  include S

  (* Use find_last which is linear time on OCaml < 4.05 *)
  let find_last_map f m =
    let res = ref None in
    let _ =
      find_last_opt
        (fun x ->
          match f x with
          | None -> false
          | Some y ->
            res := Some y;
            true)
        m
    in
    !res

  let add_seq seq set =
    let set = ref set in
    Seq.iter (fun x -> set := add x !set) seq;
    !set

  let of_seq s = add_seq s empty

  let add_iter set i =
    let set = ref set in
    i (fun x -> set := add x !set);
    !set

  let of_iter s = add_iter empty s
  let to_iter s yield = iter yield s
  let add_list = List.fold_left (fun set x -> add x set)
  let to_list = elements

  let to_string ?(start = "") ?(stop = "") ?(sep = ",") elt_to_string h =
    to_list h |> CCList.to_string ~start ~stop ~sep elt_to_string

  let pp ?(pp_start = fun _ () -> ()) ?(pp_stop = fun _ () -> ())
      ?(pp_sep = fun fmt () -> Format.fprintf fmt ",@ ") pp_x fmt m =
    pp_start fmt ();
    let first = ref true in
    iter
      (fun x ->
        if !first then
          first := false
        else
          pp_sep fmt ();
        pp_x fmt x)
      m;
    pp_stop fmt ()
end