ZeroVR/ZeroPacientVR/Assets/CodeRespawn/DungeonArchitect/ThirdParty/SharpNav/Collections/Generic/BufferedStack.cs

200 lines
5.1 KiB
C#

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