using System; using System.Collections; namespace StgSharp { public class LinkedList : IEnumerable { internal readonly LinkedListNode _heading; private LinkedListNode _cache; private bool isEmpty; public Counter count = new Counter(0, 1, 1); public LinkedList() { _heading = new LinkedListNode(); isEmpty = true; } public T First { get { return _heading._next._value; } /* * This setter is ued to reset the First node, * be careful when use this setter to avoid * unexpected risk of this List lose all nodes. */ private set { _heading._next = default; } } public T Tail { get { return _heading._previous._value; } /* * This setter is ued to reset the Last node, * be careful when use this setter to avoid * unexpected risk of this List lose all nodes. */ private set { _heading._previous = default; } } /// /// Add an item to the tail of linked list. /// /// The item ready to add to the list public void Add(T t) { //checkout if the linkedlist is null if (isEmpty) { LinkedListNode node = new LinkedListNode(t); _heading._next = node; _heading._previous = node; node.Next = _heading; node.Previous = _heading; isEmpty = false; } else { LinkedListNode node = new LinkedListNode(t); node.Next = _heading; node.Previous = _heading.Previous; _heading._previous._next = node; _heading._previous = node; } count++; } public void Remove(T value) { LinkedListNode node = Find(value); node._next._previous = node._previous; node._previous._next = node._next; node._previous = null; node._next = null; count--; } public void RemoveTail() { //check out if the list has only one member if (count._value == 1) { First = default; isEmpty = true; } else { _heading.Previous.Next = _heading; } count--; } internal LinkedListNode Find(T value) { foreach (LinkedListNode node in this) { if (node._value.Equals(value)) { return node; } } throw new Exception("Value not found in this LinkedList"); } public void Clear() { _heading._previous = null; _heading._next = null; count.Reset(); } IEnumerator IEnumerable.GetEnumerator() { return new LinkedListEnumrator(this); } internal struct LinkedListEnumrator : IEnumerator { private LinkedList _target; LinkedListNode enumrator; public LinkedListEnumrator(LinkedList target) { _target = target; enumrator = target._heading; } object IEnumerator.Current { get { return enumrator._value; } } bool IEnumerator.MoveNext() { enumrator = enumrator._next; return enumrator == default(LinkedListNode); } void IEnumerator.Reset() { enumrator = _target._heading; } } } }