using Misaki.HighPerformance.LowLevel.Buffer; using Misaki.HighPerformance.LowLevel.Collections.Contracts; using Misaki.HighPerformance.LowLevel.Utilities; using System.Collections; using System.Runtime.CompilerServices; namespace Misaki.HighPerformance.LowLevel.Collections; /// /// A collection that provides fast, unsafe operations for managing a set of unmanaged types. It supports adding, /// removing, and checking for values. /// /// Represents an unmanaged type that can be compared for equality. public unsafe struct UnsafeHashSet : IUnsafeHashCollection, IEnumerable where T : unmanaged, IEquatable { public struct Enumerator : IEnumerator { internal HashMapHelper.Enumerator _enumerator; public readonly T Current => _enumerator.buffer->_keys[_enumerator.index]; readonly object IEnumerator.Current => Current; public Enumerator(HashMapHelper* hashMap) { _enumerator = new HashMapHelper.Enumerator(hashMap); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool MoveNext() => _enumerator.MoveNext(); public void Reset() => _enumerator.Reset(); public readonly void Dispose() { } } private HashMapHelper _helper; public readonly int Count => _helper.Count; public readonly int Capacity => _helper.Capacity; public readonly bool IsCreated => _helper.IsCreated; public Enumerator GetEnumerator() => new((HashMapHelper*)UnsafeUtility.AddressOf(ref this)); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); /// /// Invalid constructor. Use or instead."/> /// public UnsafeHashSet() : this(0, Allocator.Invalid) { } public UnsafeHashSet(int capacity, AllocationHandle handle, AllocationOption allocationOption = AllocationOption.None) { _helper = new HashMapHelper(capacity, 0, 0, HashMapHelper.MINIMAL_CAPACITY, handle, allocationOption); } public UnsafeHashSet(int capacity, Allocator allocator, AllocationOption allocationOption = AllocationOption.None) : this(capacity, AllocationManager.GetAllocationHandle(allocator), allocationOption) { } /// /// Adds a new value (unless it is already present). /// /// The value to add. /// True if the value was not already present. public bool Add(T item) { return -1 != _helper.TryAdd(item); } /// /// Removes a particular value. /// /// The value to remove. /// True if the value was present. public bool Remove(T item) { return -1 != _helper.TryRemove(item); } /// /// Returns true if a particular value is present. /// /// The value to check for. /// True if the value was present. public bool Contains(T item) { return -1 != _helper.Find(item); } /// /// Sets the capacity to match what it would be if it had been originally initialized with all its entries. /// public void TrimExcess() => _helper.TrimExcess(); /// /// Returns an array with a copy of this set's values (in no particular order). /// /// The allocator to use. /// An array with a copy of the set's values. public UnsafeArray ToNativeArray(Allocator allocator) { return _helper.GetKeyArray(allocator); } public void Resize(int newSize, AllocationOption option = AllocationOption.None) { _helper.Resize(newSize); } public void Clear() { _helper.Clear(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly void* GetUnsafePtr() { return _helper.Buffer; } public void Dispose() { _helper.Dispose(); } }