74 lines
1.6 KiB
C#
74 lines
1.6 KiB
C#
using Qrakhen.Qamp.Core.Collections.Abstractions;
|
|
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();
|
|
}
|