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);
}
}
}