diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d3d894..29a70fa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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.EnqueueAll` and `Queue.DequeueAll`. +- X10D: Added `Stack.PushAll` and `Stack.PopAll`. - X10D: Added `Span.Replace(T, T)`. - X10D: Added `CountDigits` for integer types. - X10D: Added `IEnumerable.Except(T)`. diff --git a/X10D.Tests/src/Collections/QueueTests.cs b/X10D.Tests/src/Collections/QueueTests.cs new file mode 100644 index 0000000..5395beb --- /dev/null +++ b/X10D.Tests/src/Collections/QueueTests.cs @@ -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 queue = null!; + Assert.Throws(() => queue.EnqueueAll([])); + } + + [Test] + public void EnqueueAll_ShouldThrowArgumentNullException_GivenNullElements() + { + var queue = new Queue(); + Assert.Throws(() => queue.EnqueueAll(null!)); + } + + [Test] + public void DequeueAll_ShouldThrowArgumentNullException_GivenNullQueue() + { + Queue queue = null!; + Assert.Throws(() => _ = queue.DequeueAll().ToArray()); + } + + [Test] + public void EnqueueAll_ShouldAddElementsToQueue_GivenValidEnumerable() + { + var queue = new Queue(); + 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([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); + } +} diff --git a/X10D.Tests/src/Collections/StackTests.cs b/X10D.Tests/src/Collections/StackTests.cs new file mode 100644 index 0000000..ab02fbc --- /dev/null +++ b/X10D.Tests/src/Collections/StackTests.cs @@ -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 stack = null!; + Assert.Throws(() => stack.PushAll([])); + } + + [Test] + public void PushAll_ShouldThrowArgumentNullException_GivenNullElements() + { + var stack = new Stack(); + Assert.Throws(() => stack.PushAll(null!)); + } + + [Test] + public void PopAll_ShouldThrowArgumentNullException_GivenNullStack() + { + Stack stack = null!; + Assert.Throws(() => _ = stack.PopAll().ToArray()); + } + + [Test] + public void PushAll_ShouldAddElementsToStack_GivenValidEnumerable() + { + var stack = new Stack(); + 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([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); + } +} diff --git a/X10D/src/Collections/QueueExtensions.cs b/X10D/src/Collections/QueueExtensions.cs new file mode 100644 index 0000000..f8b2447 --- /dev/null +++ b/X10D/src/Collections/QueueExtensions.cs @@ -0,0 +1,56 @@ +namespace X10D.Collections; + +/// +/// Extension methods for . +/// +public static class QueueExtensions +{ + /// + /// Adds an enumerable collection of objects to the end of the , in the order that they were + /// enumerated. + /// + /// The queue to which the elements will be added. + /// An enumerable collection of elements to enqueue. + /// The type of the element. + /// + /// is . + /// -or- + /// is . + /// + public static void EnqueueAll(this Queue queue, IEnumerable 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); + } + } + + /// + /// Removes and returns each element from the queue starting at the beginning, until the queue is empty. + /// + /// The queue from which the elements will be removed. + /// The type of the element. + /// is . + public static IEnumerable DequeueAll(this Queue queue) + { + if (queue is null) + { + throw new ArgumentNullException(nameof(queue)); + } + + while (queue.Count > 0) + { + yield return queue.Dequeue(); + } + } +} diff --git a/X10D/src/Collections/StackExtensions.cs b/X10D/src/Collections/StackExtensions.cs new file mode 100644 index 0000000..a0d3a9e --- /dev/null +++ b/X10D/src/Collections/StackExtensions.cs @@ -0,0 +1,56 @@ +namespace X10D.Collections; + +/// +/// Extension methods for . +/// +public static class StackExtensions +{ + /// + /// Adds an enumerable collection of objects to the top of the , in the order that they were + /// enumerated. + /// + /// The stack to which the elements will be added. + /// An enumerable collection of elements to push. + /// The type of the element. + /// + /// is . + /// -or- + /// is . + /// + public static void PushAll(this Stack stack, IEnumerable 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); + } + } + + /// + /// Removes and returns each element from the stack starting at the top, until the stack is empty. + /// + /// The stack from which the elements will be removed. + /// The type of the element. + /// is . + public static IEnumerable PopAll(this Stack stack) + { + if (stack is null) + { + throw new ArgumentNullException(nameof(stack)); + } + + while (stack.Count > 0) + { + yield return stack.Pop(); + } + } +}