using System.Diagnostics; using System.Runtime.CompilerServices; namespace ARMeilleure.IntermediateRepresentation { /// /// Represents a efficient linked list that stores the pointer on the object directly and does not allocate. /// /// Type of the list items class IntrusiveList where T : class, IIntrusiveListNode { /// /// First item of the list, or null if empty. /// public T First { get; private set; } /// /// Last item of the list, or null if empty. /// public T Last { get; private set; } /// /// Total number of items on the list. /// public int Count { get; private set; } /// /// Adds a item as the first item of the list. /// /// Item to be added [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AddFirst(T newNode) { if (First != null) { AddBefore(First, newNode); } else { Debug.Assert(newNode.ListPrevious == null); Debug.Assert(newNode.ListNext == null); Debug.Assert(Last == null); First = newNode; Last = newNode; Debug.Assert(Count == 0); Count = 1; } } /// /// Adds a item as the last item of the list. /// /// Item to be added [MethodImpl(MethodImplOptions.AggressiveInlining)] public void AddLast(T newNode) { if (Last != null) { AddAfter(Last, newNode); } else { Debug.Assert(newNode.ListPrevious == null); Debug.Assert(newNode.ListNext == null); Debug.Assert(First == null); First = newNode; Last = newNode; Debug.Assert(Count == 0); Count = 1; } } /// /// Adds a item before a existing item on the list. /// /// Item on the list that will succeed the new item /// Item to be added /// New item [MethodImpl(MethodImplOptions.AggressiveInlining)] public T AddBefore(T node, T newNode) { Debug.Assert(newNode.ListPrevious == null); Debug.Assert(newNode.ListNext == null); newNode.ListPrevious = node.ListPrevious; newNode.ListNext = node; node.ListPrevious = newNode; if (newNode.ListPrevious != null) { newNode.ListPrevious.ListNext = newNode; } if (First == node) { First = newNode; } Count++; return newNode; } /// /// Adds a item after a existing item on the list. /// /// Item on the list that will preceed the new item /// Item to be added /// New item [MethodImpl(MethodImplOptions.AggressiveInlining)] public T AddAfter(T node, T newNode) { Debug.Assert(newNode.ListPrevious == null); Debug.Assert(newNode.ListNext == null); newNode.ListPrevious = node; newNode.ListNext = node.ListNext; node.ListNext = newNode; if (newNode.ListNext != null) { newNode.ListNext.ListPrevious = newNode; } if (Last == node) { Last = newNode; } Count++; return newNode; } /// /// Removes a item from the list. /// /// The item to be removed [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Remove(T node) { if (node.ListPrevious != null) { node.ListPrevious.ListNext = node.ListNext; } else { Debug.Assert(First == node); First = node.ListNext; } if (node.ListNext != null) { node.ListNext.ListPrevious = node.ListPrevious; } else { Debug.Assert(Last == node); Last = node.ListPrevious; } node.ListPrevious = null; node.ListNext = null; Count--; } } }