diff --git a/Misaki.HighPerformance.LowLevel/Collections/Contracts/IUnsafeCollection.cs b/Misaki.HighPerformance.LowLevel/Collections/Contracts/IUnsafeCollection.cs index 28d7096..36ae03b 100644 --- a/Misaki.HighPerformance.LowLevel/Collections/Contracts/IUnsafeCollection.cs +++ b/Misaki.HighPerformance.LowLevel/Collections/Contracts/IUnsafeCollection.cs @@ -27,7 +27,7 @@ public unsafe interface IUnsafeCollection : IDisposable void* GetUnsafePtr(); } -public interface IUnsafeCollection : IUnsafeCollection, IEnumerable +public interface IUnsafeCollection : IUnsafeCollection where T : unmanaged { /// @@ -47,7 +47,7 @@ public interface IUnsafeCollection : IUnsafeCollection, IEnumerable void Resize(int newSize, AllocationOption option); } -public interface IUnsafeHashCollection : IEnumerable, IDisposable +public interface IUnsafeHashCollection : IDisposable where T : unmanaged { /// diff --git a/Misaki.HighPerformance.LowLevel/Collections/HashMapHelper.cs b/Misaki.HighPerformance.LowLevel/Collections/HashMapHelper.cs index 25ef590..3e9a205 100644 --- a/Misaki.HighPerformance.LowLevel/Collections/HashMapHelper.cs +++ b/Misaki.HighPerformance.LowLevel/Collections/HashMapHelper.cs @@ -9,16 +9,16 @@ namespace Misaki.HighPerformance.LowLevel.Collections; public unsafe struct HashMapHelper : IDisposable where TKey : unmanaged, IEquatable { - internal struct Enumerator + internal ref struct Enumerator { - public HashMapHelper* buffer; + public ref HashMapHelper helper; public int index; public int bucketIndex; public int nextIndex; - public Enumerator(HashMapHelper* data) + public Enumerator(ref HashMapHelper data) { - buffer = data; + helper = ref data; index = -1; bucketIndex = 0; nextIndex = -1; @@ -27,7 +27,7 @@ public unsafe struct HashMapHelper : IDisposable [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool MoveNext() { - return buffer->MoveNext(ref bucketIndex, ref nextIndex, out index); + return helper.MoveNext(ref bucketIndex, ref nextIndex, out index); } public void Reset() @@ -41,7 +41,7 @@ public unsafe struct HashMapHelper : IDisposable public KeyValuePair GetCurrent() where TValue : unmanaged { - return new KeyValuePair(buffer->_keys[index], UnsafeUtility.ReadArrayElementRef(buffer->_buffer, index)); + return new KeyValuePair(helper._keys[index], UnsafeUtility.ReadArrayElementRef(helper._buffer, index)); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -49,7 +49,7 @@ public unsafe struct HashMapHelper : IDisposable { if (index != -1) { - return buffer->_keys[index]; + return helper._keys[index]; } return default; diff --git a/Misaki.HighPerformance.LowLevel/Collections/UnsafeArray.cs b/Misaki.HighPerformance.LowLevel/Collections/UnsafeArray.cs index 2eaf9d9..f17a5ce 100644 --- a/Misaki.HighPerformance.LowLevel/Collections/UnsafeArray.cs +++ b/Misaki.HighPerformance.LowLevel/Collections/UnsafeArray.cs @@ -3,6 +3,7 @@ using Misaki.HighPerformance.LowLevel.Collections.Contracts; using Misaki.HighPerformance.LowLevel.Utilities; using System.Collections; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; namespace Misaki.HighPerformance.LowLevel.Collections; @@ -42,18 +43,16 @@ internal class UnsafeArrayDebugView public unsafe struct UnsafeArray : IUnsafeCollection where T : unmanaged { - public struct Enumerator : IEnumerator + public ref struct Enumerator { - private readonly UnsafeArray* _collection; + private ref UnsafeArray _collection; private int _index; - public readonly ref T Current => ref _collection->_buffer[_index]; - readonly T IEnumerator.Current => Current; - readonly object IEnumerator.Current => Current; + public readonly ref T Current => ref _collection._buffer[_index]; - public Enumerator(UnsafeArray* collection) + public Enumerator(ref UnsafeArray collection) { - _collection = collection; + _collection = ref collection; _index = -1; } @@ -61,17 +60,13 @@ public unsafe struct UnsafeArray : IUnsafeCollection public bool MoveNext() { _index++; - return _index < _collection->_count; + return _index < _collection._count; } public void Reset() { _index = -1; } - - public void Dispose() - { - } } private T* _buffer; @@ -130,21 +125,6 @@ public unsafe struct UnsafeArray : IUnsafeCollection } } - public Enumerator GetEnumerator() - { - return new((UnsafeArray*)UnsafeUtility.AddressOf(ref this)); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - /// /// Invalid constructor, use or instead. /// @@ -245,6 +225,13 @@ public unsafe struct UnsafeArray : IUnsafeCollection return new ReadOnlyUnsafeCollection(_buffer, _count); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [UnscopedRef] + public Enumerator GetEnumerator() + { + return new Enumerator(ref this); + } + /// public void Resize(int newSize, AllocationOption option = AllocationOption.None) { diff --git a/Misaki.HighPerformance.LowLevel/Collections/UnsafeBitSet.cs b/Misaki.HighPerformance.LowLevel/Collections/UnsafeBitSet.cs index 2c8a63b..e677515 100644 --- a/Misaki.HighPerformance.LowLevel/Collections/UnsafeBitSet.cs +++ b/Misaki.HighPerformance.LowLevel/Collections/UnsafeBitSet.cs @@ -1,5 +1,7 @@ using Misaki.HighPerformance.LowLevel.Buffer; +using Misaki.HighPerformance.LowLevel.Utilities; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -36,18 +38,18 @@ public unsafe struct UnsafeBitSet : IDisposable, IEquatable { public ref struct Iterator { - private readonly UnsafeBitSet* _bitSet; + private ref UnsafeBitSet _bitSet; private int _currentBit; - public Iterator(UnsafeBitSet* bitSet, int start) + public Iterator(ref UnsafeBitSet bitSet, int start) { - _bitSet = bitSet; + _bitSet = ref bitSet; _currentBit = start - 1; } public bool Next(out int bitIndex) { - _currentBit = _bitSet->NextSetBit(_currentBit + 1); + _currentBit = _bitSet.NextSetBit(_currentBit + 1); bitIndex = _currentBit; return _currentBit != -1; } @@ -128,6 +130,7 @@ public unsafe struct UnsafeBitSet : IDisposable, IEquatable } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] private static int RoundToPadding(int length) { return (length + s_padding - 1) / s_padding * s_padding; @@ -138,14 +141,17 @@ public unsafe struct UnsafeBitSet : IDisposable, IEquatable /// /// The ID or bit. /// A size of required s for the bitset. + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static int RequiredLength(int id) { return (id >> _INDEX_SIZE) + int.Sign(id & _BIT_SIZE); } - public readonly Iterator GetIterator(int start = 0) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [UnscopedRef] + public Iterator GetIterator(int start = 0) { - return new Iterator((UnsafeBitSet*)Unsafe.AsPointer(in this), start); + return new Iterator(ref this, start); } /// @@ -153,6 +159,7 @@ public unsafe struct UnsafeBitSet : IDisposable, IEquatable /// /// The index. /// True if it is, otherwise false + [MethodImpl(MethodImplOptions.AggressiveInlining)] public readonly bool IsSet(int index) { var b = index >> _INDEX_SIZE; @@ -169,6 +176,7 @@ public unsafe struct UnsafeBitSet : IDisposable, IEquatable /// Resizes its internal array if necessary. /// /// The index. + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void SetBit(int index) { var b = index >> _INDEX_SIZE; @@ -188,6 +196,7 @@ public unsafe struct UnsafeBitSet : IDisposable, IEquatable /// Clears the bit at the given index. /// /// The index. + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ClearBit(int index) { var b = index >> _INDEX_SIZE; @@ -202,6 +211,7 @@ public unsafe struct UnsafeBitSet : IDisposable, IEquatable /// /// Sets all bits. /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void SetAll() { _bits.AsSpan().Fill(0xffffffff); @@ -213,6 +223,7 @@ public unsafe struct UnsafeBitSet : IDisposable, IEquatable /// /// Clears all set bits. /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ClearAll() { _bits.Clear(); diff --git a/Misaki.HighPerformance.LowLevel/Collections/UnsafeHashMap.cs b/Misaki.HighPerformance.LowLevel/Collections/UnsafeHashMap.cs index 9feb394..15fce46 100644 --- a/Misaki.HighPerformance.LowLevel/Collections/UnsafeHashMap.cs +++ b/Misaki.HighPerformance.LowLevel/Collections/UnsafeHashMap.cs @@ -2,6 +2,7 @@ using Misaki.HighPerformance.LowLevel.Buffer; using Misaki.HighPerformance.LowLevel.Collections.Contracts; using Misaki.HighPerformance.LowLevel.Utilities; using System.Collections; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; namespace Misaki.HighPerformance.LowLevel.Collections; @@ -10,16 +11,15 @@ public unsafe struct UnsafeHashMap : IUnsafeHashCollection where TValue : unmanaged { - public struct Enumerator : IEnumerator> + public ref struct Enumerator { internal HashMapHelper.Enumerator _enumerator; public KeyValuePair Current => _enumerator.GetCurrent(); - object IEnumerator.Current => Current; - public Enumerator(HashMapHelper* data) + public Enumerator(ref HashMapHelper data) { - _enumerator = new HashMapHelper.Enumerator(data); + _enumerator = new HashMapHelper.Enumerator(ref data); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -75,21 +75,6 @@ public unsafe struct UnsafeHashMap : IUnsafeHashCollection*)UnsafeUtility.AddressOf(ref this)); - } - - IEnumerator> IEnumerable>.GetEnumerator() - { - return GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - /// /// Invalid constructor, use or instead. /// @@ -108,6 +93,13 @@ public unsafe struct UnsafeHashMap : IUnsafeHashCollection /// Adds a new key-value pair. /// diff --git a/Misaki.HighPerformance.LowLevel/Collections/UnsafeHashSet.cs b/Misaki.HighPerformance.LowLevel/Collections/UnsafeHashSet.cs index 3fd4e7a..f1e7b20 100644 --- a/Misaki.HighPerformance.LowLevel/Collections/UnsafeHashSet.cs +++ b/Misaki.HighPerformance.LowLevel/Collections/UnsafeHashSet.cs @@ -1,7 +1,6 @@ using Misaki.HighPerformance.LowLevel.Buffer; using Misaki.HighPerformance.LowLevel.Collections.Contracts; -using Misaki.HighPerformance.LowLevel.Utilities; -using System.Collections; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; namespace Misaki.HighPerformance.LowLevel.Collections; @@ -11,19 +10,18 @@ namespace Misaki.HighPerformance.LowLevel.Collections; /// removing, and checking for values. /// /// Represents an unmanaged type that can be compared for equality. -public unsafe struct UnsafeHashSet : IUnsafeHashCollection, IEnumerable +public unsafe struct UnsafeHashSet : IUnsafeHashCollection where T : unmanaged, IEquatable { - public struct Enumerator : IEnumerator + public ref struct Enumerator { internal HashMapHelper.Enumerator _enumerator; - public readonly T Current => _enumerator.buffer->_keys[_enumerator.index]; - readonly object IEnumerator.Current => Current; + public readonly T Current => _enumerator.helper._keys[_enumerator.index]; - public Enumerator(HashMapHelper* hashMap) + public Enumerator(ref HashMapHelper hashMap) { - _enumerator = new HashMapHelper.Enumerator(hashMap); + _enumerator = new HashMapHelper.Enumerator(ref hashMap); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -36,10 +34,6 @@ public unsafe struct UnsafeHashSet : IUnsafeHashCollection, IEnumerable { _enumerator.Reset(); } - - public readonly void Dispose() - { - } } private HashMapHelper _helper; @@ -48,21 +42,6 @@ public unsafe struct UnsafeHashSet : IUnsafeHashCollection, IEnumerable public readonly int Capacity => _helper.Capacity; public readonly bool IsCreated => _helper.IsCreated; - public Enumerator GetEnumerator() - { - return new((HashMapHelper*)UnsafeUtility.AddressOf(ref this)); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - /// /// Invalid constructor. Use or instead."/> /// @@ -81,6 +60,13 @@ public unsafe struct UnsafeHashSet : IUnsafeHashCollection, IEnumerable { } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [UnscopedRef] + public Enumerator GetEnumerator() + { + return new Enumerator(ref _helper); + } + /// /// Adds a new value (unless it is already present). /// diff --git a/Misaki.HighPerformance.LowLevel/Collections/UnsafeList.cs b/Misaki.HighPerformance.LowLevel/Collections/UnsafeList.cs index f5a92c5..9fd99f5 100644 --- a/Misaki.HighPerformance.LowLevel/Collections/UnsafeList.cs +++ b/Misaki.HighPerformance.LowLevel/Collections/UnsafeList.cs @@ -3,6 +3,7 @@ using Misaki.HighPerformance.LowLevel.Collections.Contracts; using Misaki.HighPerformance.LowLevel.Utilities; using System.Collections; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; namespace Misaki.HighPerformance.LowLevel.Collections; @@ -39,18 +40,16 @@ internal class UnsafeListDebugView public unsafe struct UnsafeList : IUnsafeCollection where T : unmanaged { - public struct Enumerator : IEnumerator + public ref struct Enumerator { - private readonly UnsafeList* _collection; + private ref UnsafeList _collection; private int _index; - public readonly ref T Current => ref _collection->_array[_index]; - readonly T IEnumerator.Current => Current; - readonly object IEnumerator.Current => Current; + public readonly ref T Current => ref _collection._array[_index]; - public Enumerator(UnsafeList* collection) + public Enumerator(ref UnsafeList collection) { - _collection = collection; + _collection = ref collection; _index = -1; } @@ -58,17 +57,13 @@ public unsafe struct UnsafeList : IUnsafeCollection public bool MoveNext() { _index++; - return _index < _collection->_count; + return _index < _collection._count; } public void Reset() { _index = -1; } - - public readonly void Dispose() - { - } } /// @@ -76,7 +71,7 @@ public unsafe struct UnsafeList : IUnsafeCollection /// /// /// Use to create a parallel reader for a list. - /// The list must live at least as long as the parallel reader, and the parallel reader must not be used after the list is disposed. + /// The list must live and the address of the list remain stable at least as long as the parallel reader, and the parallel reader must not be used after the list is disposed. /// public readonly unsafe struct ParallelReader { @@ -102,7 +97,7 @@ public unsafe struct UnsafeList : IUnsafeCollection public readonly Enumerator GetEnumerator() { - return new Enumerator(listData); + return new Enumerator(ref *listData); } public readonly ReadOnlySpan AsSpan() @@ -116,7 +111,7 @@ public unsafe struct UnsafeList : IUnsafeCollection /// /// /// Use to create a parallel writer for a list. - /// The list must live at least as long as the parallel writer, and the parallel writer must not be used after the list is disposed. + /// The list must live and the address of the list remain stable at least as long as the parallel writer, and the parallel writer must not be used after the list is disposed. /// public readonly struct ParallelWriter { @@ -247,21 +242,10 @@ public unsafe struct UnsafeList : IUnsafeCollection } [MethodImpl(MethodImplOptions.AggressiveInlining)] + [UnscopedRef] public Enumerator GetEnumerator() { - return new((UnsafeList*)UnsafeUtility.AddressOf(ref this)); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); + return new Enumerator(ref this); } /// diff --git a/Misaki.HighPerformance.LowLevel/Collections/UnsafeMultiHashMap.cs b/Misaki.HighPerformance.LowLevel/Collections/UnsafeMultiHashMap.cs index 56a34ee..088eab6 100644 --- a/Misaki.HighPerformance.LowLevel/Collections/UnsafeMultiHashMap.cs +++ b/Misaki.HighPerformance.LowLevel/Collections/UnsafeMultiHashMap.cs @@ -2,6 +2,7 @@ using Misaki.HighPerformance.LowLevel.Buffer; using Misaki.HighPerformance.LowLevel.Collections.Contracts; using Misaki.HighPerformance.LowLevel.Utilities; using System.Collections; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; namespace Misaki.HighPerformance.LowLevel.Collections; @@ -10,16 +11,15 @@ public unsafe struct UnsafeMultiHashMap : IUnsafeHashCollection where TValue : unmanaged { - public struct Enumerator : IEnumerator> + public ref struct Enumerator { internal HashMapHelper.Enumerator _enumerator; public readonly KeyValuePair Current => _enumerator.GetCurrent(); - readonly object IEnumerator.Current => Current; - public Enumerator(HashMapHelper* data) + public Enumerator(ref HashMapHelper data) { - _enumerator = new HashMapHelper.Enumerator(data); + _enumerator = new HashMapHelper.Enumerator(ref data); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -32,10 +32,6 @@ public unsafe struct UnsafeMultiHashMap : IUnsafeHashCollection : IUnsafeHashCollection* _data; + private ref HashMapHelper _helper; private readonly TKey _key; - internal ValueEnumerable(HashMapHelper* data, scoped in TKey key) + internal ValueEnumerable(ref HashMapHelper data, scoped in TKey key) { - _data = data; + _helper = ref data; _key = key; } public readonly ValueEnumerator GetEnumerator() { - return new(_data, _key); + return new ValueEnumerator(ref _helper, _key); } } - public struct ValueEnumerator : IEnumerator + public ref struct ValueEnumerator { - private readonly HashMapHelper* _data; + private ref HashMapHelper helper; private readonly TKey _key; private int _entryIndex; private bool _started; - public readonly TValue Current => UnsafeUtility.ReadArrayElement(_data->Buffer, _entryIndex); - readonly object IEnumerator.Current => Current; + public readonly TValue Current => UnsafeUtility.ReadArrayElement(helper.Buffer, _entryIndex); - internal ValueEnumerator(HashMapHelper* data, scoped in TKey key) + internal ValueEnumerator(ref HashMapHelper data, scoped in TKey key) { - _data = data; + helper = ref data; _key = key; _entryIndex = -1; _started = false; @@ -90,7 +85,7 @@ public unsafe struct UnsafeMultiHashMap : IUnsafeHashCollectionFind(_key); + _entryIndex = helper.Find(_key); _started = true; return _entryIndex != -1; } @@ -100,7 +95,7 @@ public unsafe struct UnsafeMultiHashMap : IUnsafeHashCollectionFindNext(_entryIndex, _key); + _entryIndex = helper.FindNext(_entryIndex, _key); return _entryIndex != -1; } @@ -109,10 +104,6 @@ public unsafe struct UnsafeMultiHashMap : IUnsafeHashCollection _helper; @@ -121,21 +112,6 @@ public unsafe struct UnsafeMultiHashMap : IUnsafeHashCollection _helper.Capacity; public readonly bool IsCreated => _helper.IsCreated; - public Enumerator GetEnumerator() - { - return new((HashMapHelper*)UnsafeUtility.AddressOf(ref this)); - } - - IEnumerator> IEnumerable>.GetEnumerator() - { - return GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - public UnsafeMultiHashMap() : this(0, Allocator.Invalid) { @@ -151,12 +127,21 @@ public unsafe struct UnsafeMultiHashMap : IUnsafeHashCollection : IUnsafeHashCollection(key, out var value)) @@ -213,46 +200,57 @@ public unsafe struct UnsafeMultiHashMap : IUnsafeHashCollection*)UnsafeUtility.AddressOf(ref this), key); + return new ValueEnumerable(ref _helper, key); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public int CountValuesForKey(scoped in TKey key) { return _helper.CountValuesForKey(key); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool ContainsKey(scoped in TKey key) { return _helper.Find(key) != -1; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void TrimExcess() { _helper.TrimExcess(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Resize(int newSize, AllocationOption option = AllocationOption.None) { _helper.Resize(newSize); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Clear() { _helper.Clear(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public UnsafeArray GetKeyArray(Allocator allocator) { return _helper.GetKeyArray(allocator); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public UnsafeArray GetValueArray(Allocator allocator) { return _helper.GetValueArray(allocator); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public UnsafeArray> GetKeyValueArrays(Allocator allocator) { return _helper.GetKeyValueArrays(allocator); @@ -264,6 +262,7 @@ public unsafe struct UnsafeMultiHashMap : IUnsafeHashCollection : IUnsafeCollection where T : unmanaged { - public struct Enumerator : IEnumerator + public ref struct Enumerator { - private readonly UnsafeQueue* _collection; + private readonly ref UnsafeQueue _collection; private int _currentIndex; // We assume _currentIndex will always be in range when accessed. - public readonly ref T Current => ref _collection->_array[(_collection->_offset + _currentIndex) % _collection->Capacity]; - readonly T IEnumerator.Current => Current; - readonly object IEnumerator.Current => Current; + public readonly ref T Current => ref _collection._array[(_collection._offset + _currentIndex) % _collection.Capacity]; - public Enumerator(UnsafeQueue* collection) + public Enumerator(ref UnsafeQueue collection) { - _collection = collection; + _collection = ref collection; _currentIndex = -1; } @@ -33,17 +32,13 @@ public unsafe struct UnsafeQueue : IUnsafeCollection public bool MoveNext() { _currentIndex++; - return _currentIndex < _collection->_count; + return _currentIndex < _collection._count; } public void Reset() { _currentIndex = -1; } - - public readonly void Dispose() - { - } } private UnsafeArray _array; @@ -62,21 +57,6 @@ public unsafe struct UnsafeQueue : IUnsafeCollection set => _array[index] = value; } - public Enumerator GetEnumerator() - { - return new((UnsafeQueue*)UnsafeUtility.AddressOf(ref this)); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - /// /// Invalid constructor. Use or instead."/> /// @@ -97,6 +77,13 @@ public unsafe struct UnsafeQueue : IUnsafeCollection { } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [UnscopedRef] + public Enumerator GetEnumerator() + { + return new Enumerator(ref this); + } + /// /// Returns a reference to the item at the front of the queue without removing it. /// diff --git a/Misaki.HighPerformance.LowLevel/Collections/UnsafeSlotMap.cs b/Misaki.HighPerformance.LowLevel/Collections/UnsafeSlotMap.cs index 2130c9e..49e7b25 100644 --- a/Misaki.HighPerformance.LowLevel/Collections/UnsafeSlotMap.cs +++ b/Misaki.HighPerformance.LowLevel/Collections/UnsafeSlotMap.cs @@ -3,6 +3,7 @@ using Misaki.HighPerformance.LowLevel.Collections.Contracts; using Misaki.HighPerformance.LowLevel.Utilities; using System.Collections; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; namespace Misaki.HighPerformance.LowLevel.Collections; @@ -42,24 +43,22 @@ internal class UnsafeSlotMapDebugView public unsafe struct UnsafeSlotMap : IUnsafeCollection where T : unmanaged { - public struct Enumerator : IEnumerator + public ref struct Enumerator { - private readonly UnsafeSlotMap* _collection; + private ref UnsafeSlotMap _collection; private int _currentIndex; - public readonly ref T Current => ref _collection->_data[_currentIndex]; - readonly T IEnumerator.Current => Current; - readonly object? IEnumerator.Current => Current; + public readonly ref T Current => ref _collection._data[_currentIndex]; - public Enumerator(UnsafeSlotMap* collection) + public Enumerator(ref UnsafeSlotMap collection) { - _collection = collection; + _collection = ref collection; _currentIndex = -1; } public bool MoveNext() { - _currentIndex = _collection->_validBits.NextSetBit(_currentIndex + 1); + _currentIndex = _collection._validBits.NextSetBit(_currentIndex + 1); return _currentIndex != -1; } @@ -67,10 +66,6 @@ public unsafe struct UnsafeSlotMap : IUnsafeCollection { _currentIndex = -1; } - - public void Dispose() - { - } } private UnsafeArray _data; @@ -86,21 +81,6 @@ public unsafe struct UnsafeSlotMap : IUnsafeCollection public readonly bool IsCreated => _data.IsCreated && _generations.IsCreated && _freeSlots.IsCreated && _validBits.IsCreated; - public Enumerator GetEnumerator() - { - return new((UnsafeSlotMap*)UnsafeUtility.AddressOf(ref this)); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - /// /// Invalid constructor. Use or instead."/> /// @@ -151,6 +131,13 @@ public unsafe struct UnsafeSlotMap : IUnsafeCollection { } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [UnscopedRef] + public Enumerator GetEnumerator() + { + return new Enumerator(ref this); + } + /// /// Adds the specified item to the collection and returns the index of the slot where it was stored. /// @@ -328,7 +315,7 @@ public unsafe struct UnsafeSlotMap : IUnsafeCollection public readonly void* GetUnsafePtr() { - return (T*)_data.GetUnsafePtr() + 1; + return (T*)_data.GetUnsafePtr(); } public void Dispose() diff --git a/Misaki.HighPerformance.LowLevel/Collections/UnsafeSparseSet.cs b/Misaki.HighPerformance.LowLevel/Collections/UnsafeSparseSet.cs index 6ec1700..fce3e43 100644 --- a/Misaki.HighPerformance.LowLevel/Collections/UnsafeSparseSet.cs +++ b/Misaki.HighPerformance.LowLevel/Collections/UnsafeSparseSet.cs @@ -3,6 +3,7 @@ using Misaki.HighPerformance.LowLevel.Collections.Contracts; using Misaki.HighPerformance.LowLevel.Utilities; using System.Collections; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; namespace Misaki.HighPerformance.LowLevel.Collections; @@ -44,35 +45,29 @@ internal class ConcurrentSparseSetDebugView public unsafe struct UnsafeSparseSet : IUnsafeCollection where T : unmanaged { - public struct Enumerator : IEnumerator + public ref struct Enumerator { - private readonly UnsafeSparseSet* _collection; + private ref UnsafeSparseSet _collection; private int _currentIndex; - public readonly ref T Current => ref _collection->_dense[_currentIndex]; - readonly T IEnumerator.Current => Current; - readonly object IEnumerator.Current => Current; + public readonly ref T Current => ref _collection._dense[_currentIndex]; - public Enumerator(UnsafeSparseSet* collection) + public Enumerator(ref UnsafeSparseSet collection) { - _collection = collection; + _collection = ref collection; _currentIndex = -1; } public bool MoveNext() { _currentIndex++; - return _currentIndex < _collection->_count; + return _currentIndex < _collection._count; } public void Reset() { _currentIndex = -1; } - - public readonly void Dispose() - { - } } private UnsafeArray _dense; @@ -89,26 +84,11 @@ public unsafe struct UnsafeSparseSet : IUnsafeCollection public readonly int Capacity => _capacity; public readonly bool IsCreated => _dense.IsCreated && _sparse.IsCreated && _reverse.IsCreated; - public Enumerator GetEnumerator() - { - return new((UnsafeSparseSet*)UnsafeUtility.AddressOf(ref this)); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - /// /// Constructs an UnsafeSparseSet with a default size of 1 and uses the Persistent allocator. /// public UnsafeSparseSet() - : this(1, Allocator.Persistent) + : this(0, Allocator.Invalid) { } @@ -164,6 +144,13 @@ public unsafe struct UnsafeSparseSet : IUnsafeCollection return ref _dense[_sparse[sparseIndex]]; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [UnscopedRef] + public Enumerator GetEnumerator() + { + return new Enumerator(ref this); + } + /// /// Adds a value to the sparse set and returns a unique sparse index for the value. /// diff --git a/Misaki.HighPerformance.LowLevel/Collections/UnsafeStack.cs b/Misaki.HighPerformance.LowLevel/Collections/UnsafeStack.cs index 9205f9f..469ddfe 100644 --- a/Misaki.HighPerformance.LowLevel/Collections/UnsafeStack.cs +++ b/Misaki.HighPerformance.LowLevel/Collections/UnsafeStack.cs @@ -3,6 +3,7 @@ using Misaki.HighPerformance.LowLevel.Collections.Contracts; using Misaki.HighPerformance.LowLevel.Utilities; using System.Collections; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; namespace Misaki.HighPerformance.LowLevel.Collections; @@ -42,19 +43,17 @@ internal class UnsafeStackDebugView public unsafe struct UnsafeStack : IUnsafeCollection where T : unmanaged { - public struct Enumerator : IEnumerator + public ref struct Enumerator { - private readonly UnsafeStack* _collection; + private readonly ref UnsafeStack _collection; private int _index; - public readonly ref T Current => ref _collection->_array[_index]; - readonly T IEnumerator.Current => Current; - readonly object IEnumerator.Current => Current; + public readonly ref T Current => ref _collection._array[_index]; - public Enumerator(UnsafeStack* collection) + public Enumerator(ref UnsafeStack collection) { - _collection = collection; - _index = collection->Count; + _collection = ref collection; + _index = collection.Count; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -66,11 +65,7 @@ public unsafe struct UnsafeStack : IUnsafeCollection public void Reset() { - _index = _collection->Count; - } - - public readonly void Dispose() - { + _index = _collection.Count; } } @@ -81,21 +76,6 @@ public unsafe struct UnsafeStack : IUnsafeCollection public readonly int Capacity => _array.Count; public readonly bool IsCreated => _array.IsCreated; - public Enumerator GetEnumerator() - { - return new((UnsafeStack*)UnsafeUtility.AddressOf(ref this)); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - - IEnumerator IEnumerable.GetEnumerator() - { - return GetEnumerator(); - } - /// /// Invalid constructor, use or instead. /// @@ -127,6 +107,13 @@ public unsafe struct UnsafeStack : IUnsafeCollection { } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + [UnscopedRef] + public Enumerator GetEnumerator() + { + return new(ref this); + } + /// /// Adds an element to the top of the stack. ///