feat: add EnqueueAll/DequeueAll, PushAll/PopAll for Queue and Stack

This commit is contained in:
Oliver Booth 2024-06-12 14:06:54 +01:00
parent b627d21b59
commit 62cb9a36fe
Signed by: oliverbooth
GPG Key ID: E60B570D1B7557B5
5 changed files with 250 additions and 0 deletions

View File

@ -12,6 +12,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- X10D: Add support for generic math interfaces.
- X10D: Added extension methods for `DateOnly`, for parity with `DateTime` and `DateTimeOffset`.
- X10D: Added math-related extension methods for `BigInteger`.
- X10D: Added `Queue<T>.EnqueueAll` and `Queue<T>.DequeueAll`.
- X10D: Added `Stack<T>.PushAll` and `Stack<T>.PopAll`.
- X10D: Added `Span<T>.Replace(T, T)`.
- X10D: Added `CountDigits` for integer types.
- X10D: Added `IEnumerable<T>.Except(T)`.

View File

@ -0,0 +1,68 @@
using NUnit.Framework;
using X10D.Collections;
namespace X10D.Tests.Collections;
[TestFixture]
internal class QueueTests
{
[Test]
public void EnqueueAll_ShouldThrowArgumentNullException_GivenNullQueue()
{
Queue<int> queue = null!;
Assert.Throws<ArgumentNullException>(() => queue.EnqueueAll([]));
}
[Test]
public void EnqueueAll_ShouldThrowArgumentNullException_GivenNullElements()
{
var queue = new Queue<int>();
Assert.Throws<ArgumentNullException>(() => queue.EnqueueAll(null!));
}
[Test]
public void DequeueAll_ShouldThrowArgumentNullException_GivenNullQueue()
{
Queue<int> queue = null!;
Assert.Throws<ArgumentNullException>(() => _ = queue.DequeueAll().ToArray());
}
[Test]
public void EnqueueAll_ShouldAddElementsToQueue_GivenValidEnumerable()
{
var queue = new Queue<int>();
int[] elements = [1, 2, 3, 4, 5];
Assert.That(queue, Is.Empty);
queue.EnqueueAll(elements);
Assert.That(queue, Is.Not.Empty);
Assert.That(queue, Has.Count.EqualTo(5));
var index = 0;
foreach (int i in queue)
{
Assert.That(i, Is.EqualTo(elements[index]));
index++;
}
}
[Test]
public void DequeueAll_ShouldRemoveElementsFromQueue()
{
var queue = new Queue<int>([1, 2, 3, 4, 5]);
Assert.That(queue, Is.Not.Empty);
Assert.That(queue, Has.Count.EqualTo(5));
var index = 1;
foreach (int i in queue.DequeueAll())
{
Assert.That(i, Is.EqualTo(index));
index++;
}
Assert.That(queue, Is.Empty);
}
}

View File

@ -0,0 +1,68 @@
using NUnit.Framework;
using X10D.Collections;
namespace X10D.Tests.Collections;
[TestFixture]
internal class StackTests
{
[Test]
public void PushAll_ShouldThrowArgumentNullException_GivenNullStack()
{
Stack<int> stack = null!;
Assert.Throws<ArgumentNullException>(() => stack.PushAll([]));
}
[Test]
public void PushAll_ShouldThrowArgumentNullException_GivenNullElements()
{
var stack = new Stack<int>();
Assert.Throws<ArgumentNullException>(() => stack.PushAll(null!));
}
[Test]
public void PopAll_ShouldThrowArgumentNullException_GivenNullStack()
{
Stack<int> stack = null!;
Assert.Throws<ArgumentNullException>(() => _ = stack.PopAll().ToArray());
}
[Test]
public void PushAll_ShouldAddElementsToStack_GivenValidEnumerable()
{
var stack = new Stack<int>();
int[] elements = [1, 2, 3, 4, 5];
Assert.That(stack, Is.Empty);
stack.PushAll(elements);
Assert.That(stack, Is.Not.Empty);
Assert.That(stack, Has.Count.EqualTo(5));
var index = 4;
foreach (int i in stack)
{
Assert.That(i, Is.EqualTo(elements[index]));
index--;
}
}
[Test]
public void PopAll_ShouldRemoveElementsFromStack()
{
var stack = new Stack<int>([1, 2, 3, 4, 5]);
Assert.That(stack, Is.Not.Empty);
Assert.That(stack, Has.Count.EqualTo(5));
var index = 5;
foreach (int i in stack.PopAll())
{
Assert.That(i, Is.EqualTo(index));
index--;
}
Assert.That(stack, Is.Empty);
}
}

View File

@ -0,0 +1,56 @@
namespace X10D.Collections;
/// <summary>
/// Extension methods for <see cref="Queue{T}" />.
/// </summary>
public static class QueueExtensions
{
/// <summary>
/// Adds an enumerable collection of objects to the end of the <see cref="Queue{T}" />, in the order that they were
/// enumerated.
/// </summary>
/// <param name="queue">The queue to which the elements will be added.</param>
/// <param name="values">An enumerable collection of elements to enqueue.</param>
/// <typeparam name="TElement">The type of the element.</typeparam>
/// <exception cref="ArgumentNullException">
/// <para><paramref name="queue" /> is <see langword="null" />.</para>
/// -or-
/// <para><paramref name="values" /> is <see langword="null" />.</para>
/// </exception>
public static void EnqueueAll<TElement>(this Queue<TElement> queue, IEnumerable<TElement> values)
{
if (queue is null)
{
throw new ArgumentNullException(nameof(queue));
}
if (values is null)
{
throw new ArgumentNullException(nameof(values));
}
foreach (TElement element in values)
{
queue.Enqueue(element);
}
}
/// <summary>
/// Removes and returns each element from the queue starting at the beginning, until the queue is empty.
/// </summary>
/// <param name="queue">The queue from which the elements will be removed.</param>
/// <typeparam name="TElement">The type of the element.</typeparam>
/// <exception cref="ArgumentNullException"><paramref name="queue" /> is <see langword="null" />.</exception>
public static IEnumerable<TElement> DequeueAll<TElement>(this Queue<TElement> queue)
{
if (queue is null)
{
throw new ArgumentNullException(nameof(queue));
}
while (queue.Count > 0)
{
yield return queue.Dequeue();
}
}
}

View File

@ -0,0 +1,56 @@
namespace X10D.Collections;
/// <summary>
/// Extension methods for <see cref="Stack{T}" />.
/// </summary>
public static class StackExtensions
{
/// <summary>
/// Adds an enumerable collection of objects to the top of the <see cref="Stack{T}" />, in the order that they were
/// enumerated.
/// </summary>
/// <param name="stack">The stack to which the elements will be added.</param>
/// <param name="values">An enumerable collection of elements to push.</param>
/// <typeparam name="TElement">The type of the element.</typeparam>
/// <exception cref="ArgumentNullException">
/// <para><paramref name="stack" /> is <see langword="null" />.</para>
/// -or-
/// <para><paramref name="values" /> is <see langword="null" />.</para>
/// </exception>
public static void PushAll<TElement>(this Stack<TElement> stack, IEnumerable<TElement> values)
{
if (stack is null)
{
throw new ArgumentNullException(nameof(stack));
}
if (values is null)
{
throw new ArgumentNullException(nameof(values));
}
foreach (TElement element in values)
{
stack.Push(element);
}
}
/// <summary>
/// Removes and returns each element from the stack starting at the top, until the stack is empty.
/// </summary>
/// <param name="stack">The stack from which the elements will be removed.</param>
/// <typeparam name="TElement">The type of the element.</typeparam>
/// <exception cref="ArgumentNullException"><paramref name="stack" /> is <see langword="null" />.</exception>
public static IEnumerable<TElement> PopAll<TElement>(this Stack<TElement> stack)
{
if (stack is null)
{
throw new ArgumentNullException(nameof(stack));
}
while (stack.Count > 0)
{
yield return stack.Pop();
}
}
}