mirror of
https://github.com/golang/go
synced 2024-11-12 10:30:23 -07:00
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
This commit is contained in:
parent
5a40a682e3
commit
8d29f7f1c9
@ -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;
|
||||
c <- p.Value;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user