@@ -64,17 +64,18 @@ namespace Microsoft.FSharp.Collections
6464
6565let empty = MapEmpty
6666
67- let height = function
67+ let height ( m : MapTree < 'Key , 'Value >) =
68+ match mwith
6869| MapEmpty-> 0
6970| MapOne_ -> 1
7071| MapNode(_,_,_,_, h) -> h
7172
72- let isEmpty m =
73+ let isEmpty ( m : MapTree < 'Key , 'Value >) =
7374match mwith
7475| MapEmpty-> true
7576| _ -> false
7677
77- let mk l k v r =
78+ let mk l k v r : MapTree < 'Key , 'Value > =
7879match l, rwith
7980| MapEmpty, MapEmpty-> MapOne( k, v)
8081| _ ->
@@ -83,7 +84,7 @@ namespace Microsoft.FSharp.Collections
8384let m = if hl< hrthen hrelse hl
8485 MapNode( k, v, l, r, m+ 1 )
8586
86- let rebalance t1k v t2 =
87+ let rebalance t1 ( k : 'Key ) ( v : 'Value ) t2 =
8788let t1h = height t1
8889let t2h = height t2
8990if t2h> t1h+ 2 then (* right is heavier than left*)
@@ -114,7 +115,7 @@ namespace Microsoft.FSharp.Collections
114115| _ -> failwith" rebalance"
115116else mk t1 k v t2
116117
117- let rec add ( comparer : IComparer < 'Value >) kv m =
118+ let rec add ( comparer : IComparer < 'Key >) k ( v : 'Value ) ( m : MapTree < 'Key , 'Value >) =
118119match mwith
119120| MapEmpty-> MapOne( k, v)
120121| MapOne( k2,_) ->
@@ -128,36 +129,37 @@ namespace Microsoft.FSharp.Collections
128129elif c= 0 then MapNode( k, v, l, r, h)
129130else rebalance l k2 v2( add comparer k v r)
130131
131- let rec find ( comparer : IComparer < 'Value >) km =
132+ let rec tryGetValue ( comparer : IComparer < 'Key >) k ( v : byref < 'Value >) ( m : MapTree < 'Key , 'Value >) =
132133match mwith
133- | MapEmpty-> raise ( KeyNotFoundException ())
134+ | MapEmpty-> false
134135| MapOne( k2, v2) ->
135136let c = comparer.Compare( k, k2)
136- if c= 0 then v2
137- else raise ( KeyNotFoundException ())
137+ if c= 0 then v <- v2 ; true
138+ else false
138139| MapNode( k2, v2, l, r,_) ->
139140let c = comparer.Compare( k, k2)
140- if c< 0 then find comparer k l
141- elif c= 0 then v2
142- else find comparer k r
141+ if c< 0 then tryGetValue comparer k& v l
142+ elif c= 0 then v<- v2; true
143+ else tryGetValue comparer k& v r
144+
145+ let find ( comparer : IComparer < 'Key >) k ( m : MapTree < 'Key , 'Value >) =
146+ let mutable v = Unchecked.defaultof< 'Value>
147+ if tryGetValue comparer k& v mthen
148+ v
149+ else
150+ raise( KeyNotFoundException())
143151
144- let rec tryFind ( comparer : IComparer < 'Value >) k m =
145- match mwith
146- | MapEmpty-> None
147- | MapOne( k2, v2) ->
148- let c = comparer.Compare( k, k2)
149- if c= 0 then Some v2
150- else None
151- | MapNode( k2, v2, l, r,_) ->
152- let c = comparer.Compare( k, k2)
153- if c< 0 then tryFind comparer k l
154- elif c= 0 then Some v2
155- else tryFind comparer k r
152+ let tryFind ( comparer : IComparer < 'Key >) k ( m : MapTree < 'Key , 'Value >) =
153+ let mutable v = Unchecked.defaultof< 'Value>
154+ if tryGetValue comparer k& v mthen
155+ Some v
156+ else
157+ None
156158
157- let partition1 ( comparer : IComparer < 'Value >) ( f : OptimizedClosures.FSharpFunc < _ , _ , _ >) k v ( acc1 , acc2 ) =
159+ let partition1 ( comparer : IComparer < 'Key >) ( f : OptimizedClosures.FSharpFunc < _ , _ , _ >) k v ( acc1 , acc2 ) =
158160if f.Invoke( k, v) then ( add comparer k v acc1, acc2) else ( acc1, add comparer k v acc2)
159161
160- let rec partitionAux ( comparer : IComparer < 'Value >) ( f : OptimizedClosures.FSharpFunc < _ , _ , _ >) s acc =
162+ let rec partitionAux ( comparer : IComparer < 'Key >) ( f : OptimizedClosures.FSharpFunc < _ , _ , _ >) s acc =
161163match swith
162164| MapEmpty-> acc
163165| MapOne( k, v) -> partition1 comparer f k v acc
@@ -166,11 +168,11 @@ namespace Microsoft.FSharp.Collections
166168let acc = partition1 comparer f k v acc
167169 partitionAux comparer f l acc
168170
169- let partition ( comparer : IComparer < 'Value >) f s = partitionAux comparer( OptimizedClosures.FSharpFunc<_,_,_>. Adapt( f)) s( empty, empty)
171+ let partition ( comparer : IComparer < 'Key >) f s = partitionAux comparer( OptimizedClosures.FSharpFunc<_,_,_>. Adapt( f)) s( empty, empty)
170172
171- let filter1 ( comparer : IComparer < 'Value >) ( f : OptimizedClosures.FSharpFunc < _ , _ , _ >) k v acc = if f.Invoke( k, v) then add comparer k v accelse acc
173+ let filter1 ( comparer : IComparer < 'Key >) ( f : OptimizedClosures.FSharpFunc < _ , _ , _ >) k v acc = if f.Invoke( k, v) then add comparer k v accelse acc
172174
173- let rec filterAux ( comparer : IComparer < 'Value >) ( f : OptimizedClosures.FSharpFunc < _ , _ , _ >) s acc =
175+ let rec filterAux ( comparer : IComparer < 'Key >) ( f : OptimizedClosures.FSharpFunc < _ , _ , _ >) s acc =
174176match swith
175177| MapEmpty-> acc
176178| MapOne( k, v) -> filter1 comparer f k v acc
@@ -179,9 +181,9 @@ namespace Microsoft.FSharp.Collections
179181let acc = filter1 comparer f k v acc
180182 filterAux comparer f r acc
181183
182- let filter ( comparer : IComparer < 'Value >) f s = filterAux comparer( OptimizedClosures.FSharpFunc<_,_,_>. Adapt( f)) s empty
184+ let filter ( comparer : IComparer < 'Key >) f s = filterAux comparer( OptimizedClosures.FSharpFunc<_,_,_>. Adapt( f)) s empty
183185
184- let rec spliceOutSuccessor m =
186+ let rec spliceOutSuccessor ( m : MapTree < 'Key , 'Value >) =
185187match mwith
186188| MapEmpty-> failwith" internal error: Map.spliceOutSuccessor"
187189| MapOne( k2, v2) -> k2, v2, MapEmpty
@@ -190,7 +192,7 @@ namespace Microsoft.FSharp.Collections
190192| MapEmpty-> k2, v2, r
191193| _ -> let k3 , v3 , l' = spliceOutSuccessor lin k3, v3, mk l' k2 v2 r
192194
193- let rec remove ( comparer : IComparer < 'Value >) km =
195+ let rec remove ( comparer : IComparer < 'Key >) k ( m : MapTree < 'Key , 'Value >) =
194196match mwith
195197| MapEmpty-> empty
196198| MapOne( k2,_) ->
@@ -208,7 +210,7 @@ namespace Microsoft.FSharp.Collections
208210 mk l sk sv r'
209211else rebalance l k2 v2( remove comparer k r)
210212
211- let rec mem ( comparer : IComparer < 'Value >) km =
213+ let rec mem ( comparer : IComparer < 'Key >) k ( m : MapTree < 'Key , 'Value >) =
212214match mwith
213215| MapEmpty-> false
214216| MapOne( k2,_) -> ( comparer.Compare( k, k2) = 0 )
@@ -217,7 +219,7 @@ namespace Microsoft.FSharp.Collections
217219if c< 0 then mem comparer k l
218220else ( c= 0 || mem comparer k r)
219221
220- let rec iterOpt ( f : OptimizedClosures.FSharpFunc < _ , _ , _ >) m =
222+ let rec iterOpt ( f : OptimizedClosures.FSharpFunc < _ , _ , _ >) ( m : MapTree < 'Key , 'Value >) =
221223match mwith
222224| MapEmpty-> ()
223225| MapOne( k2, v2) -> f.Invoke( k2, v2)
@@ -300,7 +302,7 @@ namespace Microsoft.FSharp.Collections
300302
301303let fold f x m = foldOpt( OptimizedClosures.FSharpFunc<_,_,_,_>. Adapt( f)) x m
302304
303- let foldSectionOpt ( comparer : IComparer < 'Value >) lo hi ( f : OptimizedClosures.FSharpFunc < _ , _ , _ , _ >) m x =
305+ let foldSectionOpt ( comparer : IComparer < 'Key >) lo hi ( f : OptimizedClosures.FSharpFunc < _ , _ , _ , _ >) m x =
304306let rec foldFromTo ( f : OptimizedClosures.FSharpFunc < _ , _ , _ , _ >) m x =
305307match mwith
306308| MapEmpty-> x
@@ -319,7 +321,7 @@ namespace Microsoft.FSharp.Collections
319321
320322if comparer.Compare( lo, hi) = 1 then xelse foldFromTo f m x
321323
322- let foldSection ( comparer : IComparer < 'Value >) lo hi f m x =
324+ let foldSection ( comparer : IComparer < 'Key >) lo hi f m x =
323325 foldSectionOpt comparer lo hi( OptimizedClosures.FSharpFunc<_,_,_,_>. Adapt( f)) m x
324326
325327let toList m =
@@ -531,6 +533,9 @@ namespace Microsoft.FSharp.Collections
531533member m.Remove ( key ) : Map < 'Key , 'Value > =
532534new Map< 'Key, 'Value>( comparer, MapTree.remove comparer key tree)
533535
536+ member m.TryGetValue ( key , [<System.Runtime.InteropServices.Out>] value : byref < 'Value >) =
537+ MapTree.tryGetValue comparer key& value tree
538+
534539member m.TryFind ( key ) =
535540#if TRACE_ SETS_ AND_ MAPS
536541 MapTree.report()
@@ -588,7 +593,7 @@ namespace Microsoft.FSharp.Collections
588593
589594member s.Add ( k , v ) = ignore( k, v); raise( NotSupportedException( SR.GetString( SR.mapCannotBeMutated)))
590595member s.ContainsKey ( k ) = s.ContainsKey( k)
591- member s.TryGetValue ( k , r ) = if s.ContainsKey ( k ) then ( r <- s .[ k ]; true ) else false
596+ member s.TryGetValue ( k , r ) = s.TryGetValue ( k ,& r )
592597member s.Remove ( k : 'Key ) = ignore( k); ( raise( NotSupportedException( SR.GetString( SR.mapCannotBeMutated))) : bool)
593598
594599interface ICollection< KeyValuePair< 'Key, 'Value>> with
@@ -618,7 +623,7 @@ namespace Microsoft.FSharp.Collections
618623interface IReadOnlyDictionary< 'Key, 'Value> with
619624member s.Item with get( key ) = s.[ key]
620625member s.Keys = seq { for kvpin s-> kvp.Key}
621- member s.TryGetValue ( key , value ) = if s.ContainsKey ( key) then ( value<- s .[ key ]; true ) else false
626+ member s.TryGetValue ( key , value : byref < 'Value > )= s.TryGetValue ( key, & value)
622627member s.Values = seq { for kvpin s-> kvp.Value}
623628member s.ContainsKey key = s.ContainsKey key
624629