X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FSystem.Core%2FSystem.Collections.Generic%2FHashSet.cs;h=a417557d035886e547a32e820076df09524c0111;hb=c0a8ef12af1f473bfc837325581fe738f1b3178c;hp=5a382c1df630658ce1656b1db4c5242088e7a198;hpb=4260619e7ba69dbcea67222ddb53a6e408d1a39c;p=mono.git diff --git a/mcs/class/System.Core/System.Collections.Generic/HashSet.cs b/mcs/class/System.Core/System.Collections.Generic/HashSet.cs index 5a382c1df63..a417557d035 100644 --- a/mcs/class/System.Core/System.Collections.Generic/HashSet.cs +++ b/mcs/class/System.Core/System.Collections.Generic/HashSet.cs @@ -44,7 +44,7 @@ namespace System.Collections.Generic { [DebuggerDisplay ("Count={Count}")] [DebuggerTypeProxy (typeof (CollectionDebuggerView<,>))] public class HashSet : ICollection, ISerializable, IDeserializationCallback -#if NET_4_0 +#if NET_4_0 || MOONLIGHT || MOBILE , ISet #endif { @@ -176,26 +176,26 @@ namespace System.Collections.Generic { { CopyTo (array, 0, count); } - - public void CopyTo (T [] array, int index) + + public void CopyTo (T [] array, int arrayIndex) { - CopyTo (array, index, count); + CopyTo (array, arrayIndex, count); } - public void CopyTo (T [] array, int index, int count) + public void CopyTo (T [] array, int arrayIndex, int count) { if (array == null) throw new ArgumentNullException ("array"); - if (index < 0) - throw new ArgumentOutOfRangeException ("index"); - if (index > array.Length) + if (arrayIndex < 0) + throw new ArgumentOutOfRangeException ("arrayIndex"); + if (arrayIndex > array.Length) throw new ArgumentException ("index larger than largest valid index of array"); - if (array.Length - index < count) + if (array.Length - arrayIndex < count) throw new ArgumentException ("Destination array cannot hold the requested elements!"); for (int i = 0, items = 0; i < touched && items < count; i++) { if (GetLinkHashCode (i) != 0) - array [index++] = slots [i]; + array [arrayIndex++] = slots [i]; } } @@ -352,24 +352,21 @@ namespace System.Collections.Generic { return true; } - public int RemoveWhere (Predicate predicate) + public int RemoveWhere (Predicate match) { - if (predicate == null) - throw new ArgumentNullException ("predicate"); + if (match == null) + throw new ArgumentNullException ("match"); - int counter = 0; + var candidates = new List (); - var copy = new T [count]; - CopyTo (copy, 0); + foreach (var item in this) + if (match (item)) + candidates.Add (item); - foreach (var item in copy) { - if (predicate (item)) { - Remove (item); - counter++; - } - } + foreach (var item in candidates) + Remove (item); - return counter; + return candidates.Count; } public void TrimExcess () @@ -384,16 +381,9 @@ namespace System.Collections.Generic { if (other == null) throw new ArgumentNullException ("other"); - var copy = new T [count]; - CopyTo (copy, 0); + var other_set = ToSet (other); - foreach (var item in copy) - if (!other.Contains (item)) - Remove (item); - - foreach (var item in other) - if (!Contains (item)) - Remove (item); + RemoveWhere (item => !other_set.Contains (item)); } public void ExceptWith (IEnumerable other) @@ -422,11 +412,13 @@ namespace System.Collections.Generic { if (other == null) throw new ArgumentNullException ("other"); - if (count != other.Count ()) + var other_set = ToSet (other); + + if (count != other_set.Count) return false; foreach (var item in this) - if (!other.Contains (item)) + if (!other_set.Contains (item)) return false; return true; @@ -437,12 +429,18 @@ namespace System.Collections.Generic { if (other == null) throw new ArgumentNullException ("other"); - foreach (var item in other) { - if (Contains (item)) + foreach (var item in ToSet (other)) + if (!Add (item)) Remove (item); - else - Add (item); - } + } + + HashSet ToSet (IEnumerable enumerable) + { + var set = enumerable as HashSet; + if (set == null || !Comparer.Equals (set.Comparer)) + set = new HashSet (enumerable, Comparer); + + return set; } public void UnionWith (IEnumerable other) @@ -454,7 +452,7 @@ namespace System.Collections.Generic { Add (item); } - bool CheckIsSubsetOf (IEnumerable other) + bool CheckIsSubsetOf (HashSet other) { if (other == null) throw new ArgumentNullException ("other"); @@ -474,10 +472,12 @@ namespace System.Collections.Generic { if (count == 0) return true; - if (count > other.Count ()) + var other_set = ToSet (other); + + if (count > other_set.Count) return false; - return CheckIsSubsetOf (other); + return CheckIsSubsetOf (other_set); } public bool IsProperSubsetOf (IEnumerable other) @@ -488,13 +488,15 @@ namespace System.Collections.Generic { if (count == 0) return true; - if (count >= other.Count ()) + var other_set = ToSet (other); + + if (count >= other_set.Count) return false; - return CheckIsSubsetOf (other); + return CheckIsSubsetOf (other_set); } - bool CheckIsSupersetOf (IEnumerable other) + bool CheckIsSupersetOf (HashSet other) { if (other == null) throw new ArgumentNullException ("other"); @@ -511,10 +513,12 @@ namespace System.Collections.Generic { if (other == null) throw new ArgumentNullException ("other"); - if (count < other.Count ()) + var other_set = ToSet (other); + + if (count < other_set.Count) return false; - return CheckIsSupersetOf (other); + return CheckIsSupersetOf (other_set); } public bool IsProperSupersetOf (IEnumerable other) @@ -522,34 +526,97 @@ namespace System.Collections.Generic { if (other == null) throw new ArgumentNullException ("other"); - if (count <= other.Count ()) + var other_set = ToSet (other); + + if (count <= other_set.Count) return false; - return CheckIsSupersetOf (other); + return CheckIsSupersetOf (other_set); } - [MonoTODO] + class HashSetEqualityComparer : IEqualityComparer> + { + public bool Equals (HashSet lhs, HashSet rhs) + { + if (lhs == rhs) + return true; + + if (lhs == null || rhs == null || lhs.Count != rhs.Count) + return false; + + foreach (var item in lhs) + if (!rhs.Contains (item)) + return false; + + return true; + } + + public int GetHashCode (HashSet hashset) + { + if (hashset == null) + return 0; + + IEqualityComparer comparer = EqualityComparer.Default; + int hash = 0; + foreach (var item in hashset) + hash ^= comparer.GetHashCode (item); + + return hash; + } + } + + static readonly HashSetEqualityComparer setComparer = new HashSetEqualityComparer (); + public static IEqualityComparer> CreateSetComparer () { - throw new NotImplementedException (); + return setComparer; } - [MonoTODO] [SecurityPermission (SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)] public virtual void GetObjectData (SerializationInfo info, StreamingContext context) { - throw new NotImplementedException (); + if (info == null) { + throw new ArgumentNullException("info"); + } + info.AddValue("Version", generation); + info.AddValue("Comparer", comparer, typeof(IEqualityComparer)); + info.AddValue("Capacity", (table == null) ? 0 : table.Length); + if (table != null) { + T[] tableArray = new T[table.Length]; + CopyTo(tableArray); + info.AddValue("Elements", tableArray, typeof(T[])); + } } - [MonoTODO] public virtual void OnDeserialization (object sender) { - if (si == null) - return; + if (si != null) + { + generation = (int) si.GetValue("Version", typeof(int)); + comparer = (IEqualityComparer) si.GetValue("Comparer", + typeof(IEqualityComparer)); + int capacity = (int) si.GetValue("Capacity", typeof(int)); + + empty_slot = NO_SLOT; + if (capacity > 0) { + table = new int[capacity]; + slots = new T[capacity]; + + T[] tableArray = (T[]) si.GetValue("Elements", typeof(T[])); + if (tableArray == null) + throw new SerializationException("Missing Elements"); + + for (int iElement = 0; iElement < tableArray.Length; iElement++) { + Add(tableArray[iElement]); + } + } else + table = null; - throw new NotImplementedException (); + si = null; + } } + IEnumerator IEnumerable.GetEnumerator () { return new Enumerator (this); @@ -559,11 +626,6 @@ namespace System.Collections.Generic { get { return false; } } - void ICollection.CopyTo (T [] array, int index) - { - CopyTo (array, index); - } - void ICollection.Add (T item) { Add (item);