Cyclic Queue
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Collections; namespace Lilium.Collections { public class CyclicQueue<T>: IEnumerable<T> { public CyclicQueue(int length) { if (length < 0) throw new InvalidOperationException("Queue length can't be less then zero"); m_Queue = new T[length]; } public void Enqueue(T item) { var length = Queue.Length ; if (length == 0) return; Queue[Tail] = item; Tail = (Tail + 1) % length; if (Count == length) Head = (Head + 1) % length; else Count++; } public T Dequeue() { if (Count == 0) throw new InvalidOperationException("Queue is empty"); T local = Queue[Head]; Queue[Head] = default(T); Head = (Head + 1) % Queue.Length; return local; } /// <summary> /// Returns enumerator which enumerates from queue tail to the head. /// </summary> /// <returns></returns> public IEnumerator<T> GetReversedEnumerator() { var length = Count; if (length == 0) yield break; if (Tail > Head) for (int i = Tail - 1; i >= Head; i--) yield return Queue[i]; else { for (int i = Tail - 1; i >= 0; i--) yield return Queue[i]; for (int i = length - 1; i >= Head; i--) yield return Queue[i]; } } public bool TryPeekLast(out T item) { if (Count != 0) { item = Queue[Tail != 0 ? Tail - 1 : Queue.Length - 1]; return true; } else { item = default(T); return false; } } #region public int Count private int m_Count; public int Count { get { return m_Count; } private set { m_Count = value; } } #endregion #region IEnumerable<T> Members public IEnumerator<T> GetEnumerator() { var length = Queue.Length; if (length == 0) yield break; if (Tail > Head) for (int i = Head; i < Tail; i++) yield return Queue[i]; else { for (int i = Head; i < length; i++) yield return Queue[i]; for (int i = 0; i < Tail - 1; i++) yield return Queue[i]; } } #endregion #region IEnumerable Members IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } #endregion #region private T[] Queue private readonly T[] m_Queue; private T[] Queue { get { return m_Queue; } } #endregion #region private int Head private int m_Head; private int Head { get { return m_Head; } set { m_Head = value; } } #endregion #region private int Tail private int m_Tail; private int Tail { get { return m_Tail; } set { m_Tail = value; } } #endregion } }