using StgSharp.Graphics; using System; using System.Collections; namespace StgSharp { public class LinkedList : IEnumerable { public Counter count = new Counter(0, 1, 1); internal readonly LinkedListNode _hook; private LinkedListNode _cache; public LinkedList() { _hook = new LinkedListNode(); } /// /// Whether this linked list has no members or not. /// public bool IsEmpty { get { return count == 0; } } /// /// The first memeber of this linkec list. /// Set value to this property will reset the first node. /// public T First { get { return _hook._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 { _hook._next = default; } } /// /// The last memeber of this linkec list. /// Set value to this property will reset the first node. /// public T Tail { get { return _hook._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 { _hook._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); _hook._next = node; _hook._previous = node; node.Next = _hook; node.Previous = _hook; } else { LinkedListNode node = new LinkedListNode(t); node.Next = _hook; node.Previous = _hook.Previous; _hook._previous._next = node; _hook._previous = node; } count++; } /// /// Remove all members from this list /// public void Clear() { _hook._previous = null; _hook._next = null; count.Reset(); GC.Collect(); } IEnumerator IEnumerable.GetEnumerator() { return new LinkedListEnumrator(this); } /// /// Insert a member to current linkedlist, /// the new member will be after a certain existed member. /// /// New member will be inserted after this member /// The new member to be inserted public void InsertAfter(T target, T newMember) { try { LinkedListNode targetNode = Find(target); LinkedListNode targetNext = targetNode._next; LinkedListNode newNode = new LinkedListNode(newMember); targetNode._next = newNode; newNode._next = targetNext; targetNode._previous = newNode; newNode._previous = targetNode; count++; } catch (Exception) { throw; } } /// /// Remove a member from this linkedlist. /// /// Member to be removed from this list 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--; } /// /// remove the first member of the list /// public void RemoveFirst() { if (count._value == 1) { First = default; } else { _hook._next.Remove(); } count--; } /// /// remove the last member of the list /// public void RemoveTail() { //check out if the list has only one member if (count._value == 1) { First = default; } else { _hook.Previous = _hook.Previous.Previous; _hook.Previous.Next = _hook; } count--; } internal LinkedListNode Find(T value) { LinkedListNode enumerator = this._hook; do { enumerator = enumerator._next; } while (!enumerator.Value.Equals(value) || enumerator == _hook); if (enumerator == _hook) { throw new Exception(); } return enumerator; } /**/ internal struct LinkedListEnumrator : IEnumerator { private LinkedList _target; private T _value; private LinkedListNode enumerator; private uint index = 0; public LinkedListEnumrator(LinkedList target) { _target = target; enumerator = target._hook; } object IEnumerator.Current { get { if (index == 0 || enumerator == _target._hook) { throw new InvalidOperationException("Out of index range"); } else { _value = enumerator._value; return _value; } } } public T Current { get { return _value; } } bool IEnumerator.MoveNext() { enumerator = enumerator._next; if (enumerator == _target._hook) { return false; } index++; return true; } void IEnumerator.Reset() { enumerator = _target._hook; } } /**/ } }