/// <summary> /// Returns <paramref name="set"/> with the specified comparer. If the /// comparer does not need to be changed, <paramref name="set"/> is /// returned unmodified. /// </summary> /// <param name="set">The set to convert to a union.</param> /// <param name="comparer">The comparer to use for the set.</param> /// <param name="wasChanged">Returns True if the contents of the /// returned set are different to <paramref name="set"/>.</param> internal static IAnalysisSet AsUnion(this IAnalysisSet set, UnionComparer comparer, out bool wasChanged) { if ((set is AnalysisSetDetails.AnalysisSetOneUnion || set is AnalysisSetDetails.AnalysisSetTwoUnion || set is AnalysisSetDetails.AnalysisSetEmptyUnion || set is AnalysisSetDetails.AnalysisHashSet) && set.Comparer == comparer) { wasChanged = false; return(set); } wasChanged = true; var ns = set as AnalysisProxy; if (ns != null) { return(CreateUnion(ns, comparer)); } var ns2 = set as AnalysisSetDetails.AnalysisSetTwoObject; if (ns2 != null) { if (ns2.Value1 == null) { if (ns2.Value2 == null) { wasChanged = false; return(AnalysisSetEmptyUnion.Instances[comparer.Strength]); } wasChanged = false; return(new AnalysisSetOneUnion(ns2.Value2, comparer)); } else if (ns2.Value2 == null) { wasChanged = false; return(new AnalysisSetOneUnion(ns2.Value1, comparer)); } if (comparer.Equals(ns2.Value1, ns2.Value2)) { bool dummy; return(new AnalysisSetDetails.AnalysisSetOneUnion(comparer.MergeTypes(ns2.Value1, ns2.Value2, out dummy), comparer)); } else { return(new AnalysisSetDetails.AnalysisSetTwoUnion(ns2.Value1, ns2.Value2, comparer)); } } return(new AnalysisSetDetails.AnalysisHashSet(set, comparer)); }
internal static IEnumerable <AnalysisProxy> UnionIter(this IEnumerable <AnalysisProxy> items, UnionComparer comparer, out bool wasChanged) { #endif wasChanged = false; var asSet = items as IAnalysisSet; if (asSet != null && asSet.Comparer == comparer) { return(items); } var newItems = new List <AnalysisProxy>(); var anyMerged = true; while (anyMerged) { anyMerged = false; var matches = new Dictionary <AnalysisProxy, List <AnalysisProxy> >(comparer); foreach (var ns in items) { List <AnalysisProxy> list; if (matches.TryGetValue(ns, out list)) { if (list == null) { matches[ns] = list = new List <AnalysisProxy>(); } list.Add(ns); } else { matches[ns] = null; } } newItems.Clear(); foreach (var keyValue in matches) { var item = keyValue.Key; if (keyValue.Value != null) { foreach (var other in keyValue.Value) { bool merged; #if FULL_VALIDATION Validation.Assert(comparer.Equals(item, other)); #endif item = comparer.MergeTypes(item, other, out merged); if (merged) { anyMerged = true; wasChanged = true; } } } newItems.Add(item); } items = newItems; } return(items); }