/// <summary> /// Removes all elements in the specified hashset from the current hashset. /// </summary> public static void ExceptWith <T>(UnsafeHashSet *set, UnsafeHashSet *other) where T : unmanaged, IEquatable <T> { UDebug.Assert(set != null); UDebug.Assert(typeof(T).TypeHandle.Value == set->_typeHandle); UDebug.Assert(other != null); UDebug.Assert(typeof(T).TypeHandle.Value == other->_typeHandle); // When this set has no elements, return if (GetCount(set) == 0) { return; } // A set except itself is an empty set. if (other == set) { Clear(set); return; } for (int i = other->_collection.UsedCount - 1; i >= 0; --i) { var entry = UnsafeHashCollection.GetEntry(&other->_collection, i); if (entry->State == UnsafeHashCollection.EntryState.Used) { var key = *(T *)((byte *)entry + other->_collection.KeyOffset); var keyHash = key.GetHashCode(); UnsafeHashCollection.Remove(&set->_collection, key, keyHash); } } }
/// <summary> /// Modifies the current hashset to contain all elements that are present in itself, the specified hashset, or both. /// </summary> public static void UnionWith <T>(UnsafeHashSet *set, UnsafeHashSet *other) where T : unmanaged, IEquatable <T> { UDebug.Assert(set != null); UDebug.Assert(typeof(T).TypeHandle.Value == set->_typeHandle); UDebug.Assert(other != null); UDebug.Assert(typeof(T).TypeHandle.Value == other->_typeHandle); for (int i = other->_collection.UsedCount - 1; i >= 0; --i) { var entry = UnsafeHashCollection.GetEntry(&other->_collection, i); if (entry->State == UnsafeHashCollection.EntryState.Used) { // always add to this collection Add <T>(set, *(T *)((byte *)entry + other->_collection.KeyOffset)); } } }
/// <summary> /// Modifies the current hashset to contain only elements that are present in that hashset and in the specified hashset. /// </summary> public static void IntersectsWith <T>(UnsafeHashSet *set, UnsafeHashSet *other) where T : unmanaged, IEquatable <T> { UDebug.Assert(set != null); UDebug.Assert(typeof(T).TypeHandle.Value == set->_typeHandle); UDebug.Assert(other != null); UDebug.Assert(typeof(T).TypeHandle.Value == other->_typeHandle); // When this set has no elements, there is nothing to intersect. // When this set equals other, it is already intersecting. if (GetCount(set) == 0 || set == other) { return; } // When the other set has no elements, clear this one completely if (GetCount(other) == 0) { Clear(set); return; } for (int i = set->_collection.UsedCount - 1; i >= 0; --i) { var entry = UnsafeHashCollection.GetEntry(&set->_collection, i); if (entry->State == UnsafeHashCollection.EntryState.Used) { var key = *(T *)((byte *)entry + set->_collection.KeyOffset); var keyHash = key.GetHashCode(); // if we don't find this in other collection, remove it (And) if (UnsafeHashCollection.Find <T>(&other->_collection, key, keyHash) == null) { UnsafeHashCollection.Remove <T>(&set->_collection, key, keyHash); } } } }