Skip to content

Instantly share code, notes, and snippets.

@lucasteles
Last active February 8, 2024 22:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lucasteles/5d901d50a903a44b6dd000586c5ba1fc to your computer and use it in GitHub Desktop.
Save lucasteles/5d901d50a903a44b6dd000586c5ba1fc to your computer and use it in GitHub Desktop.
C# Circular Buffer
public sealed class CircularBuffer<T>(int capacity = 64) : IReadOnlyList<T>
where T : notnull
{
readonly T[] elements = new T[capacity];
int head, tail;
public int Capacity => elements.Length;
public int Length { get; private set; }
public void Clear()
{
head = tail;
Array.Clear(elements, 0, elements.Length);
Length = 0;
}
public ref T this[int idx] => ref elements[(tail + idx) % Capacity];
int IReadOnlyCollection<T>.Count => Length;
T IReadOnlyList<T>.this[int idx] => elements[(tail + idx) % Capacity];
public ref T Pop()
{
ref var value = ref Peek();
tail = (tail + 1) % Capacity;
Length--;
return ref value;
}
public void MoveTo(int index) {
Length = Math.Abs(index - head);
head = index % Capacity;
}
public void Advance()
{
head = (head + 1) % Capacity;
Length++;
}
public ref T Peek() => ref elements[head];
public void Push(in T val)
{
Peek() = val;
Advance();
}
public override string ToString() => $"[{string.Join(',', this)}]";
public IEnumerator<T> GetEnumerator()
{
for (var i = 0; i < Length; i++)
yield return this[i];
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment