2 * PMap - Polymorphic maps
3 * Copyright (C) 1996-2003 Xavier Leroy, Nicolas Cannasse, Markus Mottl
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version,
9 * with the special exception on linking described in file LICENSE.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 | Node
of ('k
, 'v
) map
* 'k
* 'v
* ('k
, 'v
) map
* int
27 cmp
: 'k
-> 'k
-> int;
32 | Node
(_
, _
, _
, _
, h
) -> h
35 let make l k v r
= Node
(l
, k
, v
, r
, max
(height l
) (height r
) + 1)
42 | Node
(ll
, lk
, lv
, lr
, _
) ->
43 if height ll
>= height lr
then make ll lk lv
(make lr k v r
)
46 | Node
(lrl
, lrk
, lrv
, lrr
, _
) ->
47 make (make ll lk lv lrl
) lrk lrv
(make lrr k v r
)
48 | Empty
-> assert false)
49 | Empty
-> assert false
50 else if hr > hl + 2 then
52 | Node
(rl
, rk
, rv
, rr
, _
) ->
53 if height rr
>= height rl
then make (make l k v rl
) rk rv rr
56 | Node
(rll
, rlk
, rlv
, rlr
, _
) ->
57 make (make l k v rll
) rlk rlv
(make rlr rk rv rr
)
58 | Empty
-> assert false)
59 | Empty
-> assert false
60 else Node
(l
, k
, v
, r
, max
hl hr + 1)
62 let rec min_binding = function
63 | Node
(Empty
, k
, v
, _
, _
) -> k
, v
64 | Node
(l
, _
, _
, _
, _
) -> min_binding l
65 | Empty
-> raise Not_found
67 let rec remove_min_binding = function
68 | Node
(Empty
, _
, _
, r
, _
) -> r
69 | Node
(l
, k
, v
, r
, _
) -> bal (remove_min_binding l
) k v r
70 | Empty
-> invalid_arg
"PMap.remove_min_binding"
77 let k, v
= min_binding t2
in
78 bal t1
k v
(remove_min_binding t2
)
80 let create cmp
= { cmp
= cmp
; map
= Empty
}
81 let empty = { cmp
= compare
; map
= Empty
}
86 let add x d
{ cmp
= cmp
; map
= map
} =
87 let rec loop = function
88 | Node
(l
, k, v
, r
, h
) ->
90 if c = 0 then Node
(l
, x
, d
, r
, h
)
97 | Empty
-> Node
(Empty
, x
, d
, Empty
, 1) in
98 { cmp
= cmp
; map
= loop map
}
100 let find x
{ cmp
= cmp
; map
= map
} =
101 let rec loop = function
102 | Node
(l
, k, v
, r
, _
) ->
105 else if c > 0 then loop r
107 | Empty
-> raise Not_found
in
110 let remove x
{ cmp
= cmp
; map
= map
} =
111 let rec loop = function
112 | Node
(l
, k, v
, r
, _
) ->
114 if c = 0 then merge l r
else
115 if c < 0 then bal (loop l
) k v r
else bal l
k v
(loop r
)
117 { cmp
= cmp
; map
= loop map
}
119 let mem x
{ cmp
= cmp
; map
= map
} =
120 let rec loop = function
121 | Node
(l
, k, v
, r
, _
) ->
123 c = 0 || loop (if c < 0 then l
else r
)
129 let iter f
{ map
= map
} =
130 let rec loop = function
132 | Node
(l
, k, v
, r
, _
) -> loop l
; f
k v
; loop r
in
135 let map f
{ cmp
= cmp
; map = map } =
136 let rec loop = function
138 | Node
(l
, k, v
, r
, h
) ->
141 Node
(l, k, f v
, r, h
) in
142 { cmp
= cmp
; map = loop map }
144 let mapi f
{ cmp
= cmp
; map = map } =
145 let rec loop = function
147 | Node
(l, k, v
, r, h
) ->
150 Node
(l, k, f
k v
, r, h
) in
151 { cmp
= cmp
; map = loop map }
153 let fold f
{ cmp
= cmp
; map = map } acc
=
154 let rec loop acc
= function
156 | Node
(l, k, v
, r, _
) ->
157 loop (f v
(loop acc
l)) r in
160 let foldi f
{ cmp
= cmp
; map = map } acc
=
161 let rec loop acc
= function
163 | Node
(l, k, v
, r, _
) ->
164 loop (f
k v
(loop acc
l)) r in
172 | [] -> raise
Enum.No_more_elements
173 | Empty
:: tl
-> l := tl
; next()
174 | Node
(m1
, key
, data
, m2
, h
) :: tl
->
188 Enum.No_more_elements
-> l := r; !n
190 let clone() = make !l in
191 Enum.make ~
next ~
count ~
clone
196 let uncurry_add (k, v
) m
= add k v m
197 let of_enum ?
(cmp
= compare
) e
= Enum.fold uncurry_add (create cmp
) e