using System; using System.Collections; using System.Collections.Generic; using System.Collections.Immutable; namespace BlueWest.Collections { /// /// very basic wrapper around an array that auto-expands it when it reaches capacity. Note that when iterating it should be done /// like this accessing the buffer directly but using the FastList.length field: /// /// for( var i = 0; i <= list.length; i++ ) /// var item = list.buffer[i]; /// public class FastList { /// /// direct access to the backing buffer. Do not use buffer.Length! Use FastList.length /// public T[] Buffer; /// /// direct access to the length of the filled items in the buffer. Do not change. /// public int Length = 0; public FastList(int size) { Buffer = new T[size]; } public FastList() : this(5) { } /// /// provided for ease of access though it is recommended to just access the buffer directly. /// /// Index. public T this[int index] => Buffer[index]; /// /// clears the list and nulls out all items in the buffer /// public void Clear() { Array.Clear(Buffer, 0, Length); Length = 0; } /// /// works just like clear except it does not null our all the items in the buffer. Useful when dealing with structs. /// public void Reset() { Length = 0; } /// /// adds the item to the list /// public void Add(T item) { if (Length == Buffer.Length) Array.Resize(ref Buffer, Math.Max(Buffer.Length << 1, 10)); Buffer[Length++] = item; } /// /// removes the item from the list /// /// Item. public void Remove(T item) { var comp = EqualityComparer.Default; for (var i = 0; i < Length; ++i) { if (comp.Equals(Buffer[i], item)) { RemoveAt(i); return; } } } /// /// removes the item at the given index from the list /// public void RemoveAt(int index) { Length--; if (index < Length) Array.Copy(Buffer, index + 1, Buffer, index, Length - index); Buffer[Length] = default(T); } /// /// removes the item at the given index from the list but does NOT maintain list order /// /// Index. public void RemoveAtWithSwap(int index) { Buffer[index] = Buffer[Length - 1]; Buffer[Length - 1] = default(T); --Length; } /// /// checks to see if item is in the FastList /// /// Item. public bool Contains(T item) { var comp = EqualityComparer.Default; for (var i = 0; i < Length; ++i) { if (comp.Equals(Buffer[i], item)) return true; } return false; } /// /// Converts To a generic List /// /// Item. public System.Collections.Immutable.ImmutableArray ToList() { return Buffer.ToImmutableArray(); } /// /// if the buffer is at its max more space will be allocated to fit additionalItemCount /// public void EnsureCapacity(int additionalItemCount = 1) { if (Length + additionalItemCount >= Buffer.Length) Array.Resize(ref Buffer, Math.Max(Buffer.Length << 1, Length + additionalItemCount)); } /// /// adds all items from array /// /// Array. public void AddRange(IEnumerable array) { foreach (var item in array) Add(item); } /// /// sorts all items in the buffer up to length /// public void Sort() { Array.Sort(Buffer, 0, Length); } /// /// sorts all items in the buffer up to length /// public void Sort(IComparer comparer) { Array.Sort(Buffer, 0, Length, comparer); } /// /// sorts all items in the buffer up to length /// public void Sort(IComparer comparer) { Array.Sort(Buffer, 0, Length, comparer); } } }