Skip to content

Commit

Permalink
queue: allow Peek to handle negative offsets
Browse files Browse the repository at this point in the history
  • Loading branch information
creachadair committed Sep 9, 2024
1 parent eb890cc commit db90e81
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 7 deletions.
6 changes: 4 additions & 2 deletions queue/queue.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,12 @@ func (q *Queue[T]) Front() T {

// Peek reports whether q has a value at offset n from the front of the queue,
// and if so returns its value. Peek(0) returns the same value as Front.
// Negative offsets count forward from the end of the queue.
func (q *Queue[T]) Peek(n int) (T, bool) {
if n < 0 {
panic("index out of range")
} else if n >= q.n {
n += q.n
}
if n < 0 || n >= q.n {
var zero T
return zero, false
}
Expand Down
19 changes: 14 additions & 5 deletions queue/queue_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,24 @@ func TestQueue(t *testing.T) {
t.Errorf("Front: got %v, want 1", front)
}

// Make sure we can peek all the locations.
// Make sure we can peek all the locations, both positive and negative.
for i, want := range []int{1, 2, 3} {
if v, ok := q.Peek(i); !ok || v != want {
t.Errorf("Peek(0): got (%v, %v), want (%v, true)", v, ok, want)
t.Errorf("Peek(%d): got (%v, %v), want (%v, true)", i, v, ok, want)
}
}
for i, want := range []int{3, 2, 1} {
pos := -(i + 1)
if v, ok := q.Peek(pos); !ok || v != want {
t.Errorf("Peek(%d): got (%v, %v), want (%v, true)", pos, v, ok, want)
}
}

// Peek off the end should return 0, false.
if v, ok := q.Peek(10); ok || v != 0 {
t.Errorf("Peek(10): got (%v, %v), want (0, false)", v, ok)
// Peek off the end (in either direction) should return 0, false.
for _, pos := range []int{-10, -4, 5, 9} {
if v, ok := q.Peek(pos); ok || v != 0 {
t.Errorf("Peek(%d): got (%v, %v), want (0, false)", pos, v, ok)
}
}

// Pop should work in order.
Expand All @@ -82,6 +90,7 @@ func TestQueue(t *testing.T) {
q.Push(0)
check(0, 1, 2, 3, 4)

// PopLast should work in reverse order.
for _, want := range []int{4, 3, 2} {
if v, ok := q.PopLast(); !ok || v != want {
t.Errorf("PopLast: got (%v, %v), want (%v, true)", v, ok, want)
Expand Down

0 comments on commit db90e81

Please sign in to comment.