120 lines
2.7 KiB
C#
Raw Normal View History

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