Add iterators for a couple queues.
Some checks failed
Build & Test / Main (push) Failing after 5s

This commit is contained in:
2024-08-22 00:53:48 -07:00
parent d569bb2686
commit 87212466ae
5 changed files with 117 additions and 1 deletions

View File

@@ -6,6 +6,8 @@
// makes determining whether the queue is full or empty trivial.
package queue
import "iter"
// Q is a non-concurrent queue.
type Q[T any] struct {
buf []T
@@ -73,3 +75,32 @@ func (b *Q[T]) PushBack(value T) {
b.tail = 0
}
}
// Iter returns an iterator over all items in the queue.
//
// This does not pop items off the queue.
func (b *Q[T]) Iter() iter.Seq[T] {
return func(yield func(T) bool) {
remaining := b.len
i := b.head
for remaining > 0 {
yield(b.buf[i])
remaining--
i++
if i == b.len {
i = 0
}
}
}
}
// IterPop returns an iterator that pops each item off the queue.
func (b *Q[T]) IterPop() iter.Seq[T] {
return func(yield func(T) bool) {
for b.CanPop() {
if !yield(b.PopFront()) {
break
}
}
}
}

View File

@@ -73,6 +73,51 @@ func TestFullPushPanic(t *testing.T) {
q.PushBack(2)
}
func TestIter(t *testing.T) {
q := queue.Make[int](4)
q.PushBack(1)
q.PushBack(2)
q.PushBack(3)
q.PushBack(4)
i := 0
for v := range q.Iter() {
expected := i + 1
if v != expected {
t.Errorf("iter %d should have value %d, not %d",
i, expected, v)
}
i++
}
if q.Len() != 4 {
t.Errorf("wrong length")
}
}
func TestIterPop(t *testing.T) {
t.Parallel()
q := queue.Make[int](4)
q.PushBack(1)
q.PushBack(2)
q.PushBack(3)
q.PushBack(4)
i := 0
for v := range q.IterPop() {
expected := i + 1
if v != expected {
t.Errorf("iter %d should have value %d, not %d",
i, expected, v)
}
i++
// to test yield() returning false
if i == 4 {
break
}
}
if q.Len() != 0 {
t.Errorf("wrong length")
}
}
func BenchmarkPush(b *testing.B) {
q := queue.Make[int](b.N)
rs := rand.NewSource(0)