Commit 8d29f7f1 authored by David Symonds's avatar David Symonds

Consistency changes to container/* packages for iteration.

container/list:
  - change Iter to go over the list values

container/ring:
  - add Iter, drop Forward/Backward

container/vector:
  - add channel direction constraints

R=rsc,gri
APPROVED=rsc
DELTA=86  (23 added, 40 deleted, 23 changed)
OCL=33935
CL=34132
parent 5a40a682
......@@ -18,6 +18,16 @@ type Element struct {
Value interface {};
}
// Next returns the next list element or nil.
func (e *Element) Next() *Element {
return e.next
}
// Prev returns the previous list element or nil.
func (e *Element) Prev() *Element {
return e.prev
}
// List represents a doubly linked list.
type List struct {
front, back *Element;
......@@ -181,18 +191,15 @@ func (l *List) Len() int {
return l.len
}
func (l *List) iterate(c chan <- *Element) {
var next *Element;
for e := l.front; e != nil; e = next {
// Save next in case reader of c changes e.
next = e.next;
c <- e;
func (l *List) iterate(c chan<- interface {}) {
for e := l.front; e != nil; e = e.next {
c <- e.Value;
}
close(c);
}
func (l *List) Iter() <-chan *Element {
c := make(chan *Element);
func (l *List) Iter() <-chan interface {} {
c := make(chan interface {});
go l.iterate(c);
return c
}
......@@ -114,8 +114,21 @@ func TestList(t *testing.T) {
checkListPointers(t, l, []*Element{ e1, e4, e3, e2 });
l.Remove(e2);
// Clear all elements by iterating
// Check standard iteration.
sum := 0;
for e := range l.Iter() {
if i, ok := e.(int); ok {
sum += i;
}
}
if sum != 4 {
t.Errorf("sum over l.Iter() = %d, want 4", sum);
}
// Clear all elements by iterating
var next *Element;
for e := l.Front(); e != nil; e = next {
next = e.Next();
l.Remove(e);
}
checkListPointers(t, l, []*Element{});
......
......@@ -138,37 +138,16 @@ func (r *Ring) Len() int {
}
// Forward returns a channel for forward iteration through a ring.
// Iteration is undefined if the ring is changed during iteration.
//
func (r *Ring) Forward() <-chan *Ring {
c := make(chan *Ring);
func (r *Ring) Iter() <-chan interface {} {
c := make(chan interface {});
go func() {
if r != nil {
c <- r;
c <- r.Value;
for p := r.Next(); p != r; p = p.next {
c <- p;
}
}
close(c);
}();
return c;
}
// Backward returns a channel for backward iteration through a ring.
// Iteration is undefined if the ring is changed during iteration.
//
func (r *Ring) Backward() <-chan *Ring {
c := make(chan *Ring);
go func() {
if r != nil {
c <- r;
for p := r.Prev(); p != r; p = p.prev {
c <- p;
c <- p.Value;
}
}
close(c);
}();
return c;
return c
}
......@@ -32,13 +32,13 @@ func verify(t *testing.T, r *Ring, N int, sum int) {
t.Errorf("r.Len() == %d; expected %d", n, N);
}
// forward iteration
// iteration
n = 0;
s := 0;
for p := range r.Forward() {
for p := range r.Iter() {
n++;
if p.Value != nil {
s += p.Value.(int);
if p != nil {
s += p.(int);
}
}
if n != N {
......@@ -48,22 +48,6 @@ func verify(t *testing.T, r *Ring, N int, sum int) {
t.Errorf("forward ring sum = %d; expected %d", s, sum);
}
// backward iteration
n = 0;
s = 0;
for p := range r.Backward() {
n++;
if p.Value != nil {
s += p.Value.(int);
}
}
if n != N {
t.Errorf("number of backward iterations == %d; expected %d", n, N);
}
if sum >= 0 && s != sum {
t.Errorf("backward ring sum = %d; expected %d", s, sum);
}
if r == nil {
return;
}
......@@ -147,8 +131,8 @@ func makeN(n int) *Ring {
func sum(r *Ring) int {
s := 0;
for p := range r.Forward() {
s += p.Value.(int);
for p := range r.Iter() {
s += p.(int);
}
return s;
}
......
......@@ -101,7 +101,7 @@ func (p *IntVector) Less(i, j int) bool {
// Iterate over all elements; driver for range
func (p *IntVector) iterate(c chan int) {
func (p *IntVector) iterate(c chan<- int) {
for i, v := range p.a {
c <- v.(int)
}
......@@ -110,7 +110,7 @@ func (p *IntVector) iterate(c chan int) {
// Channel iterator for range.
func (p *IntVector) Iter() chan int {
func (p *IntVector) Iter() <-chan int {
c := make(chan int);
go p.iterate(c);
return c;
......
......@@ -100,7 +100,7 @@ func (p *StringVector) Less(i, j int) bool {
// Iterate over all elements; driver for range
func (p *StringVector) iterate(c chan string) {
func (p *StringVector) iterate(c chan<- string) {
for i, v := range p.a {
c <- v.(string)
}
......@@ -109,7 +109,7 @@ func (p *StringVector) iterate(c chan string) {
// Channel iterator for range.
func (p *StringVector) Iter() chan string {
func (p *StringVector) Iter() <-chan string {
c := make(chan string);
go p.iterate(c);
return c;
......
......@@ -228,7 +228,7 @@ func (p *Vector) Swap(i, j int) {
// Iterate over all elements; driver for range
func (p *Vector) iterate(c chan Element) {
func (p *Vector) iterate(c chan<- Element) {
for i, v := range p.a {
c <- v
}
......@@ -237,7 +237,7 @@ func (p *Vector) iterate(c chan Element) {
// Channel iterator for range.
func (p *Vector) Iter() chan Element {
func (p *Vector) Iter() <-chan Element {
c := make(chan Element);
go p.iterate(c);
return c;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment