From dba81902ed0a6a956522a1529e19485bc774ed50 Mon Sep 17 00:00:00 2001 From: Steffen Forkmann Date: Mon, 11 May 2015 12:16:47 +0200 Subject: [PATCH 1/4] Try to implement System.Collections.IDictionary for dict --- .../FSharp.Core/fslib-extra-pervasives.fs | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs b/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs index 0fa7edf74e2..60033fefd8b 100644 --- a/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs +++ b/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs @@ -70,6 +70,53 @@ module ExtraTopLevelOperators = let key = RuntimeHelpers.StructBox(k) if d.ContainsKey(key) then (r <- d.[key]; true) else false member s.Remove(k : 'Key) = (raise (NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated))) : bool) + interface System.Collections.IDictionary with + member s.IsReadOnly = true + member s.IsFixedSize = true + member s.IsSynchronized = true + member s.Item + with get x = d.[RuntimeHelpers.StructBox(x :?> 'Key)] :> obj + and set x v = raise (NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated))) + member s.Keys = + let keys = d.Keys + { new System.Collections.ICollection with + member s.CopyTo(arr,i) = + let mutable n = 0 + for k in keys do + arr.SetValue(k.Value,i+n) + n <- n + 1 + member s.IsSynchronized = true + member s.SyncRoot = s :> obj + member s.Count = keys.Count + interface System.Collections.IEnumerable with + member s.GetEnumerator() = ((keys |> Seq.map (fun v -> v.Value)) :> System.Collections.IEnumerable).GetEnumerator() } + + member s.Values = + { new System.Collections.ICollection with + member s.CopyTo(arr,i) = + let mutable n = 0 + for k in d.Values do + arr.SetValue(k,i+n) + n <- n + 1 + member s.IsSynchronized = true + member s.SyncRoot = s :> obj + member s.Count = d.Values.Count + interface System.Collections.IEnumerable with + member s.GetEnumerator() = (d.Values :> System.Collections.IEnumerable).GetEnumerator() } + member s.Count = c.Count + member s.SyncRoot = s :> obj + member s.Add(k,v) = raise (NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated))) + member s.Contains(k) = d.ContainsKey(RuntimeHelpers.StructBox(k :?> 'Key)) + member s.GetEnumerator() = + ((c |> Seq.map (fun (KeyValue(k,v)) -> System.Collections.DictionaryEntry(k.Value,v))) :> System.Collections.IDictionary).GetEnumerator() + + member s.Remove(k) = (raise (NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated))) : unit) + member s.Clear() = raise (NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated))); + member s.CopyTo(arr,i) = + let mutable n = 0 + for (KeyValue(k,v)) in c do + arr.SetValue(System.Collections.DictionaryEntry(k.Value,v),i+n) + n <- n + 1 interface ICollection> with member s.Add(x) = raise (NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated))); member s.Clear() = raise (NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated))); From 0fcad7fb87bd10db16c57006fe24fdb8b7d0061a Mon Sep 17 00:00:00 2001 From: enricosada Date: Mon, 11 May 2015 14:38:52 +0200 Subject: [PATCH 2/4] add IDictionaryEnumerator --- src/fsharp/FSharp.Core/fslib-extra-pervasives.fs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs b/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs index 60033fefd8b..83a6a87386d 100644 --- a/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs +++ b/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs @@ -39,6 +39,17 @@ module ExtraTopLevelOperators = t.[RuntimeHelpers.StructBox(k)] <- v let d = (t :> IDictionary<_,_>) let c = (t :> ICollection<_>) + + let dictEnumerator (a: System.Collections.Generic.IEnumerator) = + { new System.Collections.IDictionaryEnumerator with + member x.Current = a.Current :> obj + member x.Entry = a.Current + member x.Key = x.Entry.Key + member x.Value = x.Entry.Value + member x.MoveNext () = a.MoveNext() + member x.Reset () = a.Reset() + } + // Give a read-only view of the dictionary { new IDictionary<'Key, 'T> with member s.Item @@ -108,7 +119,8 @@ module ExtraTopLevelOperators = member s.Add(k,v) = raise (NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated))) member s.Contains(k) = d.ContainsKey(RuntimeHelpers.StructBox(k :?> 'Key)) member s.GetEnumerator() = - ((c |> Seq.map (fun (KeyValue(k,v)) -> System.Collections.DictionaryEntry(k.Value,v))) :> System.Collections.IDictionary).GetEnumerator() + (c |> Seq.map (fun (KeyValue(k,v)) -> System.Collections.DictionaryEntry(k.Value,v))).GetEnumerator() + |> dictEnumerator member s.Remove(k) = (raise (NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated))) : unit) member s.Clear() = raise (NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated))); From 50a2e40873ecaf3c8397c0c560193fac94769f71 Mon Sep 17 00:00:00 2001 From: Steffen Forkmann Date: Mon, 11 May 2015 15:25:53 +0200 Subject: [PATCH 3/4] Implement IReadOnlyDictionary<'Key, 'T> and IReadOnlyCollection for dict --- src/FSharpSource.targets | 3 +++ .../FSharp.Core/fslib-extra-pervasives.fs | 24 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/src/FSharpSource.targets b/src/FSharpSource.targets index 27b47b1c008..4c615d066c2 100644 --- a/src/FSharpSource.targets +++ b/src/FSharpSource.targets @@ -115,6 +115,7 @@ $(DefineConstants);FX_NO_EXCEPTIONDISPATCHINFO $(DefineConstants);FX_NO_TASK $(DefineConstants);FX_NO_IOBSERVABLE + $(DefineConstants);FX_NO_READONLY_COLLECTIONS $(DefineConstants);FX_NO_LAZY $(DefineConstants);FX_NO_TUPLE $(DefineConstants);FX_NO_MONITOR_REPORTS_LOCKTAKEN @@ -170,6 +171,7 @@ $(DefineConstants);FX_NO_APP_DOMAINS $(DefineConstants);FX_NO_PROCESS_DIAGNOSTICS $(DefineConstants);FX_NO_IOBSERVABLE + $(DefineConstants);FX_NO_READONLY_COLLECTIONS $(DefineConstants);FX_NO_WEB_CLIENT $(DefineConstants);FX_NO_CONVERTER $(DefineConstants);FX_NO_GET_HASH_CODE_HELPER @@ -525,6 +527,7 @@ $(DefineConstants);FX_NO_PARAMETERIZED_THREAD_START $(DefineConstants);FX_NO_STRUCTURAL_EQUALITY $(DefineConstants);FX_NO_IOBSERVABLE + $(DefineConstants);FX_NO_READONLY_COLLECTIONS $(DefineConstants);FX_NO_LAZY $(DefineConstants);FX_NO_TUPLE $(DefineConstants);FX_NO_DELEGATE_CREATE_DELEGATE_FROM_STATIC_METHOD diff --git a/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs b/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs index 83a6a87386d..640d72ba626 100644 --- a/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs +++ b/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs @@ -81,6 +81,30 @@ module ExtraTopLevelOperators = let key = RuntimeHelpers.StructBox(k) if d.ContainsKey(key) then (r <- d.[key]; true) else false member s.Remove(k : 'Key) = (raise (NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated))) : bool) +#if FX_NO_READONLY_COLLECTIONS +#else + interface IReadOnlyDictionary<'Key, 'T> with + member s.Item + with get x = d.[RuntimeHelpers.StructBox(x)] + member s.Keys = + let keys = d.Keys + { new IEnumerable<'Key> with + member s.GetEnumerator() = (keys |> Seq.map (fun v -> v.Value)).GetEnumerator() + interface System.Collections.IEnumerable with + member s.GetEnumerator() = ((keys |> Seq.map (fun v -> v.Value)) :> System.Collections.IEnumerable).GetEnumerator() } + + member s.Values = + { new IEnumerable<'T> with + member s.GetEnumerator() = d.Values.GetEnumerator() + interface System.Collections.IEnumerable with + member s.GetEnumerator() = (d.Values :> System.Collections.IEnumerable).GetEnumerator() } + member s.ContainsKey(k) = d.ContainsKey(RuntimeHelpers.StructBox(k)) + member s.TryGetValue(k,r) = + let key = RuntimeHelpers.StructBox(k) + if d.ContainsKey(key) then (r <- d.[key]; true) else false + interface IReadOnlyCollection> with + member s.Count = c.Count +#endif interface System.Collections.IDictionary with member s.IsReadOnly = true member s.IsFixedSize = true From 1ea96290fb3176d944716b8218eb9b50b2df4e38 Mon Sep 17 00:00:00 2001 From: enricosada Date: Wed, 13 May 2015 10:17:38 +0200 Subject: [PATCH 4/4] fix syncroot --- src/fsharp/FSharp.Core/fslib-extra-pervasives.fs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs b/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs index 640d72ba626..eed87c4ca87 100644 --- a/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs +++ b/src/fsharp/FSharp.Core/fslib-extra-pervasives.fs @@ -121,7 +121,7 @@ module ExtraTopLevelOperators = arr.SetValue(k.Value,i+n) n <- n + 1 member s.IsSynchronized = true - member s.SyncRoot = s :> obj + member s.SyncRoot = (t :> System.Collections.ICollection).SyncRoot member s.Count = keys.Count interface System.Collections.IEnumerable with member s.GetEnumerator() = ((keys |> Seq.map (fun v -> v.Value)) :> System.Collections.IEnumerable).GetEnumerator() } @@ -134,12 +134,12 @@ module ExtraTopLevelOperators = arr.SetValue(k,i+n) n <- n + 1 member s.IsSynchronized = true - member s.SyncRoot = s :> obj + member s.SyncRoot = (t :> System.Collections.ICollection).SyncRoot member s.Count = d.Values.Count interface System.Collections.IEnumerable with member s.GetEnumerator() = (d.Values :> System.Collections.IEnumerable).GetEnumerator() } member s.Count = c.Count - member s.SyncRoot = s :> obj + member s.SyncRoot = (t :> System.Collections.ICollection).SyncRoot member s.Add(k,v) = raise (NotSupportedException(SR.GetString(SR.thisValueCannotBeMutated))) member s.Contains(k) = d.ContainsKey(RuntimeHelpers.StructBox(k :?> 'Key)) member s.GetEnumerator() =