Initial upload;

This commit is contained in:
2025-03-25 00:55:48 +09:00
commit aa1e9e6b1d
23 changed files with 1621 additions and 0 deletions

View File

@@ -0,0 +1,113 @@
using Misaki.HighPerformance.Unsafe.Collections.Contracts;
using Misaki.HighPerformance.Unsafe.Helpers;
using System.Collections;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Misaki.HighPerformance.Unsafe.Collections;
public unsafe struct UnsafeArray<T> : IUnsafeCollection<T>, IEnumerable<T> where T : unmanaged
{
public struct Enumerator : IEnumerator<T>
{
private UnsafeArray<T> _collection;
private int _index;
private T _value;
public Enumerator(ref UnsafeArray<T> collection)
{
_collection = collection;
_index = -1;
_value = default;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool MoveNext()
{
_index++;
if (_index < _collection.Size)
{
_value = UnsafeUtilities.ReadArrayElement<T>(_collection.Buffer, _index);
return true;
}
_value = default;
return false;
}
public void Reset()
{
_index = -1;
}
// Let NativeArray indexer check for out of range.
public T Current
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
return _value;
}
}
object IEnumerator.Current
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
return Current;
}
}
public void Dispose()
{
}
}
private T* _buffer;
private int _size;
public readonly T* Buffer => _buffer;
public readonly int Size => _size;
public readonly ref T this[int index] => ref UnsafeUtilities.AsRef<T>(_buffer + index);
public IEnumerator<T> GetEnumerator() => new Enumerator(ref this);
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public UnsafeArray(int size, AllocationType allocationType)
{
_size = size;
_buffer = (T*)Marshal.AllocHGlobal(size * sizeof(T)).ToPointer();
if (allocationType == AllocationType.Clear)
{
Clear();
}
}
public void ReAlloc(int newSize)
{
if (newSize == _size)
{
return;
}
_buffer = (T*)Marshal.ReAllocHGlobal((IntPtr)_buffer, newSize * sizeof(T)).ToPointer();
_size = newSize;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly void Clear()
{
MemClear(_buffer, (uint)(_size * sizeof(T)));
}
public void Dispose()
{
Marshal.FreeHGlobal((IntPtr)_buffer);
_buffer = null;
_size = 0;
}
}