using System; using System.Collections; using System.Collections.Generic; namespace QSB.Utility; /// /// A LIFO collection with List<> functionality. /// public class ListStack : IEnumerable { private List _items = new(); public int Count => _items.Count; private readonly bool _removeDuplicates; /// If true, all elements equal to the added item will be removed prior to adding the new element. public ListStack(bool removeDuplicates) { _removeDuplicates = removeDuplicates; } /// /// Removes all items from the stack. /// public void Clear() => _items.Clear(); /// /// Pushes an element onto the front of the stack. /// public void Push(T item) { if (_removeDuplicates && _items.Contains(item)) { RemoveAll(x => EqualityComparer.Default.Equals(x, item)); } _items.Add(item); } /// /// Pops an element off the front of the stack. /// public T PopFromFront() { if (_items.Count > 0) { var temp = _items[_items.Count - 1]; _items.RemoveAt(_items.Count - 1); return temp; } return default; } /// /// Pops an element off the back of the stack and shifts the entire stack backwards. /// public T PopFromBack() { if (_items.Count == 0) { return default; } var firstElement = _items[0]; _items.RemoveAt(0); return firstElement; } /// /// Returns the element at the front of the stack. /// public T PeekFront() => _items.Count > 0 ? _items[_items.Count - 1] : default; /// /// Returns the element at the back of the stack. /// public T PeekBack() => _items.Count > 0 ? _items[0] : default; /// /// Removes the element at the given index, where 0 is the back of the stack. The stack will shift backwards to fill empty space. /// public void RemoveAt(int index) => _items.RemoveAt(index); /// /// Removes the first occurence (back to front) of an item. /// public bool Remove(T item) => _items.Remove(item); /// /// Removes all elements that match the given predicate. /// public int RemoveAll(Predicate match) => _items.RemoveAll(match); /// /// Returns the index of the given item, where 0 is the back of the stack. /// public int IndexOf(T item) => _items.IndexOf(item); public T this[int index] { get => _items[index]; set => _items[index] = value; } IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable)_items).GetEnumerator(); public IEnumerator GetEnumerator() => ((IEnumerable)_items).GetEnumerator(); }