Simple static implementation of generic QUEUE in C#

public class CircularQueue<T>
{
	private const int InitialCapacity = 16;

	private T[] storage;

	private int capacity;
	private int startIndex;
	private int endIndex;

	public CircularQueue(int capacity = InitialCapacity)
	{
		this.Capacity = capacity;
		this.storage = new T[this.Capacity];
	}

	public int Count { get; private set; }

	private int Capacity
	{
		get
		{
			return this.capacity;
		}

		set
		{
			if (value <= 0)
			{
				throw new ArgumentOutOfRangeException(
					nameof(value),
					"Queue capacity should be a positive integer");
			}

			this.capacity = value;
		}
	}

	public void Enqueue(T element)
	{
		if (this.GrowNeeded())
		{
			this.Grow();
		}

		this.storage[this.endIndex] = element;
		this.endIndex = (this.endIndex + 1) % this.Capacity;
		this.Count++;
	}

	public T Dequeue()
	{
		if (this.Count <= 0)
		{
			throw new InvalidOperationException("Queue is empty.");
		}

		var element = this.storage[this.startIndex];
		this.storage[this.startIndex] = default(T);
		this.startIndex = (this.startIndex + 1) % this.Capacity;
		this.Count--;

		return element;
	}

	public T[] ToArray()
	{
		var resultArray = new T[this.Count];
		this.ResizeArrayStorage(resultArray);

		return resultArray;
	}

	private bool GrowNeeded()
	{
		var result = this.Count >= this.Capacity;

		return result;
	}

	private void Grow()
	{
		var newStorage = new T[this.Capacity * 2];
		this.ResizeArrayStorage(newStorage);
		this.startIndex = 0;
		this.endIndex = this.Capacity;
		this.Capacity *= 2;

		this.storage = newStorage;
	}

	private void ResizeArrayStorage(T[] array)
	{
		for (int i = 0; i < this.Count; i++)
		{
			var currentIndex = (this.startIndex + i) % this.Capacity;
			array[i] = this.storage[currentIndex];
		}
	}
}

Leave a Reply

Your email address will not be published. Required fields are marked *