Skip to content

Instantly share code, notes, and snippets.

@dadhi
Forked from kolebynov/Program.cs
Created May 7, 2024 13:43
Show Gist options
  • Save dadhi/7e6d10bdc75a5d3e2ea83344dbc6312a to your computer and use it in GitHub Desktop.
Save dadhi/7e6d10bdc75a5d3e2ea83344dbc6312a to your computer and use it in GitHub Desktop.
Fixed stack/heap array with any element type
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
var list1 = new FixedList<string, Buffer16<string>>();
var list2 = new FixedList<string, Buffer32<string>>();
UseList(ref list1, "Hello");
UseList(ref list2, "World");
Console.WriteLine(list1.GetRef(0));
Console.WriteLine(list2.GetRef(0));
static void UseList<TItem, TList>(ref TList list, TItem item)
where TList : IFixedList<TItem>
{
list.Add(item);
}
public interface IFixedList<T>
{
int Count { get; }
ref T GetRef(int index);
void Add(T item);
}
public struct FixedList<TElement, TBuffer> : IFixedList<TElement>
where TBuffer : struct, IBuffer<TElement>
{
private TBuffer _buffer;
private TElement[] _heapBuffer;
private int _count;
public int Count => _count;
public ref TElement GetRef(int index)
{
// CheckIndex
return ref _heapBuffer != null
? ref _heapBuffer[index]
: ref _buffer.GetRef(index);
}
public void Add(TElement item)
{
if (_heapBuffer == null && _buffer.Count > _count)
{
_buffer.GetRef(_count++) = item;
return;
}
_heapBuffer ??= new TElement[16];
// Reallocate heap buffer if needed
_heapBuffer[_count++] = item;
}
}
public interface IBuffer<T>
{
int Count { get; }
ref T GetRef(int index);
}
[InlineArray(16)]
public struct Buffer16<T> : IBuffer<T>
{
private T _element0;
public int Count => 16;
public ref T GetRef(int index) => ref MemoryMarshal.CreateSpan(ref _element0, Count)[index];
}
[InlineArray(32)]
public struct Buffer32<T> : IBuffer<T>
{
private T _element0;
public int Count => 32;
public ref T GetRef(int index) => ref MemoryMarshal.CreateSpan(ref _element0, Count)[index];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment