using System; using System.Collections; using System.Collections.Generic; using System.Linq; namespace Microsoft.CodeAnalysis.CSharp; internal sealed class FirstAmongEqualsSet : IEnumerable, IEnumerable { private readonly HashSet _hashSet; private readonly Dictionary _dictionary; private readonly Func _canonicalComparer; public FirstAmongEqualsSet(IEnumerable items, IEqualityComparer equalityComparer, Func canonicalComparer) { _canonicalComparer = canonicalComparer; _dictionary = new Dictionary(equalityComparer); _hashSet = new HashSet(equalityComparer); UnionWith(items); } public void UnionWith(IEnumerable items) { foreach (T item in items) { if (!_dictionary.TryGetValue(item, out var value) || IsMoreCanonical(item, value)) { _dictionary[item] = item; } } } private bool IsMoreCanonical(T newItem, T oldItem) { return _canonicalComparer(newItem, oldItem) > 0; } public void IntersectWith(IEnumerable items) { _hashSet.UnionWith(items); foreach (T item in _dictionary.Keys.ToList()) { if (!_hashSet.Contains(item)) { _dictionary.Remove(item); } } foreach (T item2 in _hashSet) { if (_dictionary.TryGetValue(item2, out var value) && IsMoreCanonical(item2, value)) { _dictionary[item2] = item2; } } _hashSet.Clear(); } public IEnumerator GetEnumerator() { return _dictionary.Values.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } }