/// <summary> /// Inserts an element after another in the list. /// </summary> /// <param name="preceding">The element already in the list.</param> /// <param name="element">The element to be inserted.</param> /// <remarks> /// Passing preceding as null will add the element at the /// front of the list. /// </remarks> /// <exception cref="InvalidOperationException">Thrown if the element is already in a list.</exception> public void InsertAfter(IDLElement preceding, IDLElement element) { Flush(); if (element.Previous != null || element.Next != null) { throw new InvalidOperationException(AlreadyInListMsg); } if (preceding == null) { AddToFront(element); } else { element.Previous = preceding; element.Next = preceding.Next; preceding.Next = element; if (object.ReferenceEquals(element.Next, this)) { this.back = element; } else { ((IDLElement)element.Next).Previous = element; } this.count++; } }
/// <summary> /// Adds an element to the end of the list. /// </summary> /// <param name="element">The element to be inserted.</param> /// <exception cref="InvalidOperationException">Thrown if the element is already in a list.</exception> public void AddToEnd(IDLElement element) { Flush(); if (element.Previous != null || element.Next != null) { throw new InvalidOperationException(AlreadyInListMsg); } if (this.front == null) { // The list is empty this.front = element; this.back = element; element.Previous = this; element.Next = this; } else { element.Previous = this.back; element.Next = this; this.back.Next = element; this.back = element; } this.count++; }
/// <summary> /// Removes all elements from the list. /// </summary> public void Clear() { Flush(); this.front = null; this.back = null; this.count = 0; }
private IDLElement lastElement; // The last referenced element (or null) /// <summary> /// Constructs an empty list. /// </summary> public DoubleList() { this.front = null; this.back = null; this.count = 0; this.opCount = 0; this.lastElement = null; this.lastIndex = -1; }
/// <summary> /// Returns the element at the specified position in the list. /// </summary> /// <remarks> /// <note> /// Index=0 references the element at the front of the list and /// Index=Count-1 reference the last element in the list. /// </note> /// <note> /// The class optimizes for scanning forward or backwards /// through the list. /// </note> /// </remarks> /// <exception cref="IndexOutOfRangeException">Thrown if the index is not in the range <b>0..Count-1</b>.</exception> public IDLElement this[int index] { get { if (index < 0 || index >= count) { throw new IndexOutOfRangeException(); } if (lastElement != null) { if (index == lastIndex) { return(lastElement); } else if (index == lastIndex - 1) { lastIndex = index; lastElement = (IDLElement)lastElement.Previous; return(lastElement); } else if (index == lastIndex + 1) { lastIndex = index; lastElement = (IDLElement)lastElement.Next; return(lastElement); } } // $todo(jeff.lill): // // If I ever have some spare time to burn, I // could optimize this by deciding whether it // makes more sense to count up or down from // the current position, count up from the beginning, // or count down from the end of the list. IDLElement element; element = this.front; for (int i = 0; i < index; i++) { element = (IDLElement)element.Next; } lastIndex = index; lastElement = element; return(element); } }
public IDLType(XElement type, IDLElement ownerElement = null) : base(type) { IsPrimitive = Elem.Attribute("type") != null; IsObject = Elem.Attribute("name") != null; IsString = IsPrimitive && Elem.Attribute("type").Value == "DOMString"; IsVoid = IsPrimitive && Elem.Attribute("type").Value == "void"; IsNullable = IsString || IsObject; Name = IsPrimitive ? Elem.Attribute("type").Value : Elem.Attribute("name").Value; // Some attributes on the owner element make sense as type annotations. ByRef = ownerElement != null ? ownerElement.HasExtendedAttribute("ByRef") : false; IsPrivate = ownerElement != null ? ownerElement.HasExtendedAttribute("Private") : false; }
public IDLType(XElement type, IDLElement ownerElement = null) : base(type) { IsPrimitive = Elem.Attribute("type") != null; IsObject = Elem.Attribute("name") != null; IsString = IsPrimitive && Elem.Attribute("type").Value == "DOMString"; IsVoid = IsPrimitive && Elem.Attribute("type").Value == "void"; IsNullable = IsString || IsObject; Name = IsPrimitive ? Elem.Attribute("type").Value : Elem.Attribute("name").Value; // Some attributes on the owner element make sense as type annotations. ByRef = ownerElement != null?ownerElement.HasExtendedAttribute("ByRef") : false; IsPrivate = ownerElement != null?ownerElement.HasExtendedAttribute("Private") : false; }
/// <summary> /// Removes an element from the list. /// </summary> /// <param name="element">The element to be removed.</param> /// <exception cref="InvalidOperationException">Thrown if the element is not in the list.</exception> public void Remove(IDLElement element) { Flush(); if (element.Previous == null || element.Next == null) { throw new InvalidOperationException(NotInListMsg); } if (count == 1) { this.front = null; this.back = null; } else { if (this.front == element) { this.front = (IDLElement)element.Next; ((IDLElement)element.Next).Previous = this; } else if (this.back == element) { this.back = (IDLElement)element.Previous; ((IDLElement)element.Previous).Next = this; } else { ((IDLElement)element.Previous).Next = element.Next; ((IDLElement)element.Next).Previous = element.Previous; } } element.Previous = null; element.Next = null; this.count--; if (count < 0) { throw new InvalidOperationException("Remove error."); } }
/// <summary> /// Inserts an element at s specified position in the list. /// </summary> /// <param name="index">The index where the element will be inserted.</param> /// <param name="element">The element to be inserted.</param> /// <exception cref="InvalidOperationException">Thrown if the element is already in a list.</exception> /// <exception cref="IndexOutOfRangeException">Thrown if the index is outside the range of <b>0..Count</b>.</exception> public void InsertAt(int index, IDLElement element) { Flush(); if (element.Previous != null || element.Next != null) { throw new InvalidOperationException(AlreadyInListMsg); } if (index < 0 || index > count) { throw new IndexOutOfRangeException(); } if (index == 0) { AddToFront(element); } else { InsertAfter(this[index - 1], element); } }
/// <summary> /// Indicates that an element has been touched by moving it /// to the most recently used end of the list. /// </summary> /// <param name="element">The element.</param> public void Touch(IDLElement element) { list.Remove(element); list.AddToEnd(element); }
/// <summary> /// Removes and element from the list. /// </summary> /// <param name="element">The element.</param> public void Remove(IDLElement element) { list.Remove(element); }
/// <summary> /// Adds an element to the list. /// </summary> /// <param name="element">The element.</param> public void Add(IDLElement element) { list.AddToEnd(element); }
/// <summary> /// Called whenever the list is modified to update the opCount, as well /// as clearing the cached index and element. /// </summary> private void Flush() { opCount++; lastIndex = -1; lastElement = null; }