qamp/Qrakhen.Qamp.Core/Collections/Expander.cs

73 lines
1.6 KiB
C#

using System.Collections;
namespace Qrakhen.Qamp.Core.Collections;
/// <summary>
/// Expanding Collection based on doubling capacity allocations when adding elements.
/// </summary>
/// <remarks>
/// Not implementing <see cref="IList{T}"/> because it expects <see cref="Add"> to return void,
/// and we don't need that here in Q&.
/// </remarks>
/// <typeparam name="T"></typeparam>
public abstract class Expander<T> :
IEnumerable<T>,
IGetSet<long, T>,
IAdd<long, T>
{
protected T[] Data;
public long Count { get; protected set; }= 0;
public long Capacity => Data.Length;
protected Expander(int capacity = 0x10)
{
Data = new T[capacity];
}
protected Expander(IEnumerable<T> data)
{
Data = data.ToArray();
Count = Data.Length;
}
public T this[long index] {
get => Get(index);
set => Set(index, value);
}
public T Get(long index) => Data[index];
public void Set(long index, T value)
{
Prepare(index);
Data[index] = value;
}
public long Add(T value)
{
Prepare(Count);
Data[Count] = value;
return Count++;
}
protected void Prepare(long position)
{
while (position >= Data.Length) {
T[] grown = new T[Data.Length * 2];
Array.Copy(Data, grown, Count);
Data = grown;
}
}
public IEnumerator<T> GetEnumerator()
{
foreach (T? item in Data) {
yield return item;
}
}
IEnumerator IEnumerable.GetEnumerator()
=> GetEnumerator();
}