Last active
February 8, 2024 22:46
-
-
Save lucasteles/5d901d50a903a44b6dd000586c5ba1fc to your computer and use it in GitHub Desktop.
C# Circular Buffer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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