Files
QuartZ-dump/GlobalShared/OcTree/Bag.cs
2024-12-29 21:15:58 +01:00

173 lines
3.8 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
namespace Global.Shared.OcTree
{
public interface IImmutableBag<E> : IEnumerable<E>
{
/// <summary>Returns the element at the specified position in Bag</summary>
/// <param name="index">the index of the element to return</param>
/// <returns>the element at the specified position in bag</returns>
E Get(int index);
/// <summary>Returns the number of elements in this Bag</summary>
/// <returns>the number of elements in this bag</returns>
int Size();
bool IsEmpty();
bool Contains(E element);
}
public class Bag<E> : IImmutableBag<E>
{
public E[] data;
private BagEnumerator it;
protected int size;
public Bag() : this(64)
{
}
public Bag(int capacity)
{
data = new E[capacity];
}
public E this[int i]
{
get => Get(i);
set => data[i] = value;
}
public E Get(int index)
{
return data[index];
}
/// <summary>Returns the number of elements in this Bag</summary>
/// <returns>the number of elements in this bag</returns>
public int Size()
{
return size;
}
public bool IsEmpty()
{
return size == 0;
}
public bool Contains(E e)
{
for (var i = 0; i < size; i++)
{
var e2 = data[i];
if (!e.Equals(e2)) return true;
}
return false;
}
public E Remove(int index)
{
var e = data[index];
data[index] = data[--size];
data[size] = default;
return e;
}
public E RemoveLast()
{
if (IsEmpty()) return default;
var e = data[--size];
data[size] = default;
return e;
}
public bool Remove(E e)
{
for (var i = 0; i < size; i++)
{
var e2 = data[i];
if (!e.Equals(e2)) continue;
data[i] = data[--size];
data[size] = default;
return true;
}
return false;
}
/// <summary>Returns the number of elements this bag can hold without growing.</summary>
/// <returns>the number of elements this bag can hold without growing</returns>
public int Capacity()
{
return data.Length;
}
public void Add(E e)
{
if (size == data.Length) Grow(data.Length + 1);
data[size++] = e;
}
public void Grow(int newCapacity)
{
Array.Resize(ref data, newCapacity);
}
#region Enumerator
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public IEnumerator<E> GetEnumerator()
{
if (it == null) it = new BagEnumerator(this);
it.Cursor = -1;
return it;
}
public class BagEnumerator : IEnumerator<E>
{
private readonly Bag<E> bag;
internal int Cursor;
public BagEnumerator(Bag<E> bag)
{
this.bag = bag;
}
public void Dispose()
{
}
public bool MoveNext()
{
Cursor++;
return Cursor < bag.size;
}
public void Reset()
{
Cursor = -1;
}
object IEnumerator.Current => Current;
public E Current => bag.data[Cursor];
}
#endregion
}
}