mirror of
https://github.com/golang/go
synced 2024-11-26 04:58:00 -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 {};
|
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.
|
// List represents a doubly linked list.
|
||||||
type List struct {
|
type List struct {
|
||||||
front, back *Element;
|
front, back *Element;
|
||||||
@ -181,18 +191,15 @@ func (l *List) Len() int {
|
|||||||
return l.len
|
return l.len
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *List) iterate(c chan <- *Element) {
|
func (l *List) iterate(c chan<- interface {}) {
|
||||||
var next *Element;
|
for e := l.front; e != nil; e = e.next {
|
||||||
for e := l.front; e != nil; e = next {
|
c <- e.Value;
|
||||||
// Save next in case reader of c changes e.
|
|
||||||
next = e.next;
|
|
||||||
c <- e;
|
|
||||||
}
|
}
|
||||||
close(c);
|
close(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *List) Iter() <-chan *Element {
|
func (l *List) Iter() <-chan interface {} {
|
||||||
c := make(chan *Element);
|
c := make(chan interface {});
|
||||||
go l.iterate(c);
|
go l.iterate(c);
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
@ -114,8 +114,21 @@ func TestList(t *testing.T) {
|
|||||||
checkListPointers(t, l, []*Element{ e1, e4, e3, e2 });
|
checkListPointers(t, l, []*Element{ e1, e4, e3, e2 });
|
||||||
l.Remove(e2);
|
l.Remove(e2);
|
||||||
|
|
||||||
// Clear all elements by iterating
|
// Check standard iteration.
|
||||||
|
sum := 0;
|
||||||
for e := range l.Iter() {
|
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);
|
l.Remove(e);
|
||||||
}
|
}
|
||||||
checkListPointers(t, l, []*Element{});
|
checkListPointers(t, l, []*Element{});
|
||||||
|
@ -138,37 +138,16 @@ func (r *Ring) Len() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Forward returns a channel for forward iteration through a ring.
|
func (r *Ring) Iter() <-chan interface {} {
|
||||||
// Iteration is undefined if the ring is changed during iteration.
|
c := make(chan interface {});
|
||||||
//
|
|
||||||
func (r *Ring) Forward() <-chan *Ring {
|
|
||||||
c := make(chan *Ring);
|
|
||||||
go func() {
|
go func() {
|
||||||
if r != nil {
|
if r != nil {
|
||||||
c <- r;
|
c <- r.Value;
|
||||||
for p := r.Next(); p != r; p = p.next {
|
for p := r.Next(); p != r; p = p.next {
|
||||||
c <- p;
|
c <- p.Value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
close(c);
|
close(c);
|
||||||
}();
|
}();
|
||||||
return 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;
|
|
||||||
}
|
}
|
||||||
|
@ -32,13 +32,13 @@ func verify(t *testing.T, r *Ring, N int, sum int) {
|
|||||||
t.Errorf("r.Len() == %d; expected %d", n, N);
|
t.Errorf("r.Len() == %d; expected %d", n, N);
|
||||||
}
|
}
|
||||||
|
|
||||||
// forward iteration
|
// iteration
|
||||||
n = 0;
|
n = 0;
|
||||||
s := 0;
|
s := 0;
|
||||||
for p := range r.Forward() {
|
for p := range r.Iter() {
|
||||||
n++;
|
n++;
|
||||||
if p.Value != nil {
|
if p != nil {
|
||||||
s += p.Value.(int);
|
s += p.(int);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if n != N {
|
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);
|
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 {
|
if r == nil {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -147,8 +131,8 @@ func makeN(n int) *Ring {
|
|||||||
|
|
||||||
func sum(r *Ring) int {
|
func sum(r *Ring) int {
|
||||||
s := 0;
|
s := 0;
|
||||||
for p := range r.Forward() {
|
for p := range r.Iter() {
|
||||||
s += p.Value.(int);
|
s += p.(int);
|
||||||
}
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,7 @@ func (p *IntVector) Less(i, j int) bool {
|
|||||||
|
|
||||||
|
|
||||||
// Iterate over all elements; driver for range
|
// 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 {
|
for i, v := range p.a {
|
||||||
c <- v.(int)
|
c <- v.(int)
|
||||||
}
|
}
|
||||||
@ -110,7 +110,7 @@ func (p *IntVector) iterate(c chan int) {
|
|||||||
|
|
||||||
|
|
||||||
// Channel iterator for range.
|
// Channel iterator for range.
|
||||||
func (p *IntVector) Iter() chan int {
|
func (p *IntVector) Iter() <-chan int {
|
||||||
c := make(chan int);
|
c := make(chan int);
|
||||||
go p.iterate(c);
|
go p.iterate(c);
|
||||||
return c;
|
return c;
|
||||||
|
@ -100,7 +100,7 @@ func (p *StringVector) Less(i, j int) bool {
|
|||||||
|
|
||||||
|
|
||||||
// Iterate over all elements; driver for range
|
// 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 {
|
for i, v := range p.a {
|
||||||
c <- v.(string)
|
c <- v.(string)
|
||||||
}
|
}
|
||||||
@ -109,7 +109,7 @@ func (p *StringVector) iterate(c chan string) {
|
|||||||
|
|
||||||
|
|
||||||
// Channel iterator for range.
|
// Channel iterator for range.
|
||||||
func (p *StringVector) Iter() chan string {
|
func (p *StringVector) Iter() <-chan string {
|
||||||
c := make(chan string);
|
c := make(chan string);
|
||||||
go p.iterate(c);
|
go p.iterate(c);
|
||||||
return c;
|
return c;
|
||||||
|
@ -228,7 +228,7 @@ func (p *Vector) Swap(i, j int) {
|
|||||||
|
|
||||||
|
|
||||||
// Iterate over all elements; driver for range
|
// 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 {
|
for i, v := range p.a {
|
||||||
c <- v
|
c <- v
|
||||||
}
|
}
|
||||||
@ -237,7 +237,7 @@ func (p *Vector) iterate(c chan Element) {
|
|||||||
|
|
||||||
|
|
||||||
// Channel iterator for range.
|
// Channel iterator for range.
|
||||||
func (p *Vector) Iter() chan Element {
|
func (p *Vector) Iter() <-chan Element {
|
||||||
c := make(chan Element);
|
c := make(chan Element);
|
||||||
go p.iterate(c);
|
go p.iterate(c);
|
||||||
return c;
|
return c;
|
||||||
|
Loading…
Reference in New Issue
Block a user