// Copyright (c) 2014 Robert Rouhani and other contributors (see CONTRIBUTORS file). // Licensed under the MIT License - https://raw.github.com/Robmaister/SharpNav/master/LICENSE using System; using System.Collections; using System.Collections.Generic; using System.Linq; namespace SharpNav.Collections.Generic { /// /// Typical FIFO generic stack container that stores data inside of /// a fixed-size internal buffer (array). /// /// Type of element that given BufferedStack object stores. public class BufferedStack : ICollection { private T[] data; // Internal data array private int top; // Index of the position "above" the top of the stack /// /// Initializes a new instance of the class. /// /// The maximum number of items that will be stored. public BufferedStack(int size) { data = new T[size]; top = 0; } /// /// Initializes a new instance of the class as a copy of an /// of the same type. /// /// The number of elements to copy from the collection. /// The collection to copy from. public BufferedStack(int size, ICollection items) { if (items.Count <= size) { data = new T[size]; items.CopyTo(data, 0); top = items.Count; } else { data = items.Skip(items.Count - size).ToArray(); top = size; } } /// /// Gets the number of elements in the stack. /// public int Count { get { return top; } } /// /// Gets a value indicating whether the stack is read-only (False for now) /// bool ICollection.IsReadOnly { get { return false; } } /// /// Gets the value at specified index (valid ranges are from 0 to size-1) /// /// Index value /// The value at the index public T this[int index] { get { return data[index]; } } /// /// Pushes a new element to the top of the stack. /// /// The element to be added to the stack /// True if element was added to stack, False otherwise public bool Push(T item) { if (top == data.Length) return false; data[top++] = item; return true; } /// /// Removes most recent (top) element from stack and returns it. /// /// Top element public T Pop() { if (top == 0) throw new InvalidOperationException("The stack is empty."); return data[--top]; } /// /// Returns copy of the top element of the stack. /// /// Top element public T Peek() { if (top == 0) throw new InvalidOperationException("The stack is empty."); return data[top - 1]; } /// /// Resets stack pointer back to default, essentially clearing the stack. /// public void Clear() { top = 0; } /// /// Returns whether the stack contains a given item. /// /// Item to search for /// True if item exists in stack, False if not public bool Contains(T item) { for (int i = 0; i < top; i++) if (item.Equals(data[i])) return true; return false; } /// /// Copies the contents of the to an array. /// /// The array to copy to. /// The index within the array to start copying to. public void CopyTo(T[] array, int arrayIndex) { throw new NotImplementedException(); } /// /// Gets the 's enumerator. /// /// The enumerator. public IEnumerator GetEnumerator() { if (top == 0) yield break; //TODO handle wrap-arounds. for (int i = 0; i < top; i++) yield return data[i]; } /// /// Calls . /// /// The item to add. void ICollection.Add(T item) { Push(item); } /// /// Unsupported, but necessary to implement . /// /// An item. /// Nothing. This method will always throw . /// Will always be thrown. This is not a valid operation. bool ICollection.Remove(T item) { throw new InvalidOperationException("Cannot remove from an arbitrary index in a stack"); } /// /// The non-generic version of . /// /// A non-generic enumerator. IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } }