Files
QuanTAlib/v2/basics/CircularBuffer.cs
T
Miha Kralj 89a46089e9 Refactor CircularBuffer class, add Enumerator struct for iteration.
The CircularBuffer class was updated to implement IEnumerable<double> and include an Enumerator struct for iteration. The Add method now has a default parameter value. Also, a quirky joke: Why do programmers prefer dark mode? Because light attracts bugs!
2024-07-29 07:33:51 -07:00

82 lines
2.3 KiB
C#

namespace QuanTAlib;
public class CircularBuffer: IEnumerable<double>
{
private double[] _buffer = null!;
private int _start;
private int _size;
public int Capacity => _buffer.Length;
public int Count => _size;
public CircularBuffer(int capacity)
{
_buffer = new double[capacity];
_start = 0;
_size = 0;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Add(double item, bool isNew = true) {
if (_size == 0 || isNew) {
// If buffer is empty or isNew is true, add new item
if (_size < Capacity) {
_buffer[(_start + _size) % Capacity] = item;
_size++;
} else {
_buffer[_start] = item;
_start = (_start + 1) % Capacity;
}
} else {
// If isNew is false, just update the last item
_buffer[(_start + _size - 1) % Capacity] = item;
}
}
public double this[int index] {
get {
if (index < 0 || index >= _size)
throw new IndexOutOfRangeException();
return _buffer[(_start + index) % Capacity];
} set {
if (index < 0 || index >= _size)
throw new IndexOutOfRangeException();
_buffer[(_start + index) % Capacity] = value;
}
}
public Enumerator GetEnumerator() => new Enumerator(this);
IEnumerator<double> IEnumerable<double>.GetEnumerator() => GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public struct Enumerator : IEnumerator<double> {
private readonly CircularBuffer _buffer;
private int _index;
private double _current;
internal Enumerator(CircularBuffer buffer) {
_buffer = buffer;
_index = -1;
_current = default;
}
public bool MoveNext() {
if (_index + 1 >= _buffer._size)
return false;
_index++;
_current = _buffer[_index];
return true;
}
public double Current => _current;
object IEnumerator.Current => Current;
public void Reset() {
_index = -1;
_current = default;
}
public void Dispose() { }
}
}