diff options
author | Robert Griesemer <gri@golang.org> | 2009-12-22 18:25:27 -0800 |
---|---|---|
committer | Robert Griesemer <gri@golang.org> | 2009-12-22 18:25:27 -0800 |
commit | be2b0efdfb4fa4164d716c44d82bcbf39c99e624 (patch) | |
tree | 965078e4c4cd5aff7916c43bb0bd8679993ca574 | |
parent | 2df67a3676e572d5b33280dde3e6dfa8c2e73f85 (diff) | |
download | golang-be2b0efdfb4fa4164d716c44d82bcbf39c99e624.tar.gz |
Replace container/vector with exp/vector (faster).
Manual changes to the following files:
src/pkg/Makefile
src/pkg/exp/vector/Makefile (now: src/pkg/container/vector/Makefile)
R=rsc, r
CC=golang-dev
http://codereview.appspot.com/181041
17 files changed, 640 insertions, 1397 deletions
diff --git a/src/pkg/Makefile b/src/pkg/Makefile index 70c3c6540..f37502d58 100644 --- a/src/pkg/Makefile +++ b/src/pkg/Makefile @@ -57,7 +57,6 @@ DIRS=\ exp/exception\ exp/iterable\ exp/parser\ - exp/vector\ expvar\ flag\ fmt\ diff --git a/src/pkg/container/vector/Makefile b/src/pkg/container/vector/Makefile index 8ccc34789..9664748d4 100644 --- a/src/pkg/container/vector/Makefile +++ b/src/pkg/container/vector/Makefile @@ -6,8 +6,67 @@ include ../../../Make.$(GOARCH) TARG=container/vector GOFILES=\ + defs.go\ intvector.go\ stringvector.go\ vector.go\ +generate: vector.go vector_test.go + < vector.go cat\ + | gofmt -r='Vector -> IntVector'\ + | gofmt -r='interface{} -> int'\ + > intvector.go\ + + < vector.go cat\ + | gofmt -r='Vector -> StringVector'\ + | gofmt -r='interface{} -> string'\ + > stringvector.go\ + + < vector_test.go cat\ + | gofmt -r='Vector -> IntVector'\ + | gofmt -r='zero -> intzero'\ + | gofmt -r='elem2Value -> elem2IntValue'\ + | gofmt -r='intf2Value -> intf2IntValue'\ + | gofmt -r='int2Value -> int2IntValue'\ + | gofmt -r='TestZeroLenExp -> TestIntZeroLenExp'\ + | gofmt -r='TestResizeExp -> TestIntResizeExp'\ + | gofmt -r='TestResize2Exp -> TestIntResize2Exp'\ + | gofmt -r='checkZeroExp -> checkIntZeroExp'\ + | gofmt -r='TestTrailingElementsExp -> TestIntTrailingElementsExp'\ + | gofmt -r='TestAccessExp -> TestIntAccessExp'\ + | gofmt -r='TestInsertDeleteClearExp -> TestIntInsertDeleteClearExp'\ + | gofmt -r='verify_sliceExp -> verify_sliceIntExp'\ + | gofmt -r='verify_patternExp -> verify_patternIntExp'\ + | gofmt -r='make_vectorExp -> make_vectorIntExp'\ + | gofmt -r='TestInsertVectorExp -> TestIntInsertVectorExp'\ + | gofmt -r='TestDoExp -> TestIntDoExp'\ + | gofmt -r='TestIterExp -> TestIntIterExp'\ + | gofmt -r='TestVectorData -> TestIntVectorData'\ + > intvector_test.go\ + + < vector_test.go cat\ + | gofmt -r='Vector -> StringVector'\ + | gofmt -r='zero -> strzero'\ + | gofmt -r='int2Value -> int2StrValue'\ + | gofmt -r='intf2Value -> intf2StrValue'\ + | gofmt -r='elem2Value -> elem2StrValue'\ + | gofmt -r='TestZeroLenExp -> TestStrZeroLenExp'\ + | gofmt -r='TestResizeExp -> TestStrResizeExp'\ + | gofmt -r='TestResize2Exp -> TestStrResize2Exp'\ + | gofmt -r='checkZeroExp -> checkStrZeroExp'\ + | gofmt -r='TestTrailingElementsExp -> TestStrTrailingElementsExp'\ + | gofmt -r='TestAccessExp -> TestStrAccessExp'\ + | gofmt -r='TestInsertDeleteClearExp -> TestStrInsertDeleteClearExp'\ + | gofmt -r='verify_sliceExp -> verify_sliceStrExp'\ + | gofmt -r='verify_patternExp -> verify_patternStrExp'\ + | gofmt -r='make_vectorExp -> make_vectorStrExp'\ + | gofmt -r='TestInsertVectorExp -> TestStrInsertVectorExp'\ + | gofmt -r='TestDoExp -> TestStrDoExp'\ + | gofmt -r='TestIterExp -> TestStrIterExp'\ + | gofmt -r='TestVectorData -> TestStrVectorData'\ + > stringvector_test.go + +bench: + gotest -v -match Nums -benchmarks Nums + include ../../../Make.pkg diff --git a/src/pkg/exp/vector/defs.go b/src/pkg/container/vector/defs.go index 0607a50c6..0607a50c6 100644 --- a/src/pkg/exp/vector/defs.go +++ b/src/pkg/container/vector/defs.go diff --git a/src/pkg/container/vector/intvector.go b/src/pkg/container/vector/intvector.go index 1ec4b85a9..a1754a94f 100644 --- a/src/pkg/container/vector/intvector.go +++ b/src/pkg/container/vector/intvector.go @@ -2,94 +2,206 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// CAUTION: If this file is not vector.go, it was generated +// automatically from vector.go - DO NOT EDIT in that case! + package vector -// IntVector is a specialization of Vector that hides the wrapping of Elements around ints. -type IntVector struct { - Vector +func (p *IntVector) realloc(length, capacity int) (b []int) { + if capacity < initialSize { + capacity = initialSize + } + b = make(IntVector, length, capacity) + copy(b, *p) + *p = b + return +} + + +// Insert n elements at position i. +func (p *IntVector) Expand(i, n int) { + a := *p + + // make sure we have enough space + len0 := len(a) + len1 := len0 + n + if len1 <= cap(a) { + // enough space - just expand + a = a[0:len1] + } else { + // not enough space - double capacity + capb := cap(a) * 2 + if capb < len1 { + // still not enough - use required length + capb = len1 + } + // capb >= len1 + a = p.realloc(len1, capb) + } + + // make a hole + for j := len0 - 1; j >= i; j-- { + a[j+n] = a[j] + } + + *p = a } +// Insert n elements at the end of a vector. +func (p *IntVector) Extend(n int) { p.Expand(len(*p), n) } + + // Resize changes the length and capacity of a vector. // If the new length is shorter than the current length, Resize discards // trailing elements. If the new length is longer than the current length, -// Resize adds 0 elements. The capacity parameter is ignored unless the -// new length or capacity is longer that the current capacity. +// Resize adds the respective zero values for the additional elements. The capacity +// parameter is ignored unless the new length or capacity is longer than the current +// capacity. The resized vector's capacity may be larger than the requested capacity. func (p *IntVector) Resize(length, capacity int) *IntVector { - i := p.Len() - p.Vector.Resize(length, capacity) - for a := p.a; i < len(a); i++ { - a[i] = 0 + a := *p + + if length > cap(a) || capacity > cap(a) { + // not enough space or larger capacity requested explicitly + a = p.realloc(length, capacity) + } else if length < len(a) { + // clear trailing elements + for i := range a[length:] { + var zero int + a[length+i] = zero + } } + + *p = a[0:length] return p } +// Len returns the number of elements in the vector. +// Same as len(*p). +func (p *IntVector) Len() int { return len(*p) } + + +// Cap returns the capacity of the vector; that is, the +// maximum length the vector can grow without resizing. +// Same as cap(*p). +func (p *IntVector) Cap() int { return cap(*p) } + + // At returns the i'th element of the vector. -func (p *IntVector) At(i int) int { return p.Vector.At(i).(int) } +func (p *IntVector) At(i int) int { return (*p)[i] } // Set sets the i'th element of the vector to value x. -func (p *IntVector) Set(i int, x int) { p.a[i] = x } +func (p *IntVector) Set(i int, x int) { (*p)[i] = x } // Last returns the element in the vector of highest index. -func (p *IntVector) Last() int { return p.Vector.Last().(int) } +func (p *IntVector) Last() int { return (*p)[len(*p)-1] } // Data returns all the elements as a slice. func (p *IntVector) Data() []int { - arr := make([]int, p.Len()) - for i, v := range p.a { - arr[i] = v.(int) - } + arr := make(IntVector, len(*p)) + copy(arr, *p) return arr } // Insert inserts into the vector an element of value x before // the current element at index i. -func (p *IntVector) Insert(i int, x int) { p.Vector.Insert(i, x) } +func (p *IntVector) Insert(i int, x int) { + p.Expand(i, 1) + (*p)[i] = x +} + + +// Delete deletes the i'th element of the vector. The gap is closed so the old +// element at index i+1 has index i afterwards. +func (p *IntVector) Delete(i int) { + a := *p + n := len(a) + + copy(a[i:n-1], a[i+1:n]) + var zero int + a[n-1] = zero // support GC, zero out entry + *p = a[0 : n-1] +} -// InsertVector inserts into the vector the contents of the Vector +// InsertVector inserts into the vector the contents of the vector // x such that the 0th element of x appears at index i after insertion. func (p *IntVector) InsertVector(i int, x *IntVector) { - p.Vector.InsertVector(i, &x.Vector) + b := *x + + p.Expand(i, len(b)) + copy((*p)[i:i+len(b)], b) +} + + +// Cut deletes elements i through j-1, inclusive. +func (p *IntVector) Cut(i, j int) { + a := *p + n := len(a) + m := n - (j - i) + + copy(a[i:m], a[j:n]) + for k := m; k < n; k++ { //TODO(bflm) don't zero out the elements unless it's a Vector. + var zero int + a[k] = zero // support GC, zero out entries + } + + *p = a[0:m] } -// Slice returns a new IntVector by slicing the old one to extract slice [i:j]. +// Slice returns a new sub-vector by slicing the old one to extract slice [i:j]. // The elements are copied. The original vector is unchanged. func (p *IntVector) Slice(i, j int) *IntVector { - return &IntVector{*p.Vector.Slice(i, j)} + var s IntVector + s.realloc(j-i, 0) // will fail in Init() if j < i + copy(s, (*p)[i:j]) + return &s } +// Convenience wrappers + // Push appends x to the end of the vector. -func (p *IntVector) Push(x int) { p.Vector.Push(x) } +func (p *IntVector) Push(x int) { p.Insert(len(*p), x) } + +// Pop deletes the last element of the vector. +func (p *IntVector) Pop() int { + a := *p -// Pop deletes and returns the last element of the vector. -func (p *IntVector) Pop() int { return p.Vector.Pop().(int) } + i := len(a) - 1 + x := a[i] + var zero int + a[i] = zero // support GC, zero out entry + *p = a[0:i] + return x +} -// AppendVector appends the entire IntVector x to the end of this vector. +// AppendVector appends the entire vector x to the end of this vector. func (p *IntVector) AppendVector(x *IntVector) { - p.Vector.InsertVector(len(p.a), &x.Vector) + p.InsertVector(len(*p), x) } -// sort.Interface support -// Less returns a boolean denoting whether the i'th element is less than the j'th element. -func (p *IntVector) Less(i, j int) bool { return p.At(i) < p.At(j) } +// Swap exchanges the elements at indexes i and j. +func (p *IntVector) Swap(i, j int) { + a := *p + a[i], a[j] = a[j], a[i] +} // Iterate over all elements; driver for range func (p *IntVector) iterate(c chan<- int) { - for _, v := range p.a { - c <- v.(int) + for _, v := range *p { + c <- v } close(c) } diff --git a/src/pkg/exp/vector/intvector_test.go b/src/pkg/container/vector/intvector_test.go index 51dd766db..51dd766db 100644 --- a/src/pkg/exp/vector/intvector_test.go +++ b/src/pkg/container/vector/intvector_test.go diff --git a/src/pkg/exp/vector/nogen_test.go b/src/pkg/container/vector/nogen_test.go index e0399f781..e0399f781 100644 --- a/src/pkg/exp/vector/nogen_test.go +++ b/src/pkg/container/vector/nogen_test.go diff --git a/src/pkg/exp/vector/numbers_test.go b/src/pkg/container/vector/numbers_test.go index 9a7e2780e..9a7e2780e 100644 --- a/src/pkg/exp/vector/numbers_test.go +++ b/src/pkg/container/vector/numbers_test.go diff --git a/src/pkg/exp/vector/nums.sh b/src/pkg/container/vector/nums.sh index 22bf4dca5..22bf4dca5 100755 --- a/src/pkg/exp/vector/nums.sh +++ b/src/pkg/container/vector/nums.sh diff --git a/src/pkg/container/vector/stringvector.go b/src/pkg/container/vector/stringvector.go index 821a7a101..fad20f58a 100644 --- a/src/pkg/container/vector/stringvector.go +++ b/src/pkg/container/vector/stringvector.go @@ -2,47 +2,109 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// CAUTION: If this file is not vector.go, it was generated +// automatically from vector.go - DO NOT EDIT in that case! + package vector -// StringVector is a specialization of Vector that hides the wrapping of Elements around strings. -type StringVector struct { - Vector + +func (p *StringVector) realloc(length, capacity int) (b []string) { + if capacity < initialSize { + capacity = initialSize + } + b = make(StringVector, length, capacity) + copy(b, *p) + *p = b + return } +// Insert n elements at position i. +func (p *StringVector) Expand(i, n int) { + a := *p + + // make sure we have enough space + len0 := len(a) + len1 := len0 + n + if len1 <= cap(a) { + // enough space - just expand + a = a[0:len1] + } else { + // not enough space - double capacity + capb := cap(a) * 2 + if capb < len1 { + // still not enough - use required length + capb = len1 + } + // capb >= len1 + a = p.realloc(len1, capb) + } + + // make a hole + for j := len0 - 1; j >= i; j-- { + a[j+n] = a[j] + } + + *p = a +} + + +// Insert n elements at the end of a vector. +func (p *StringVector) Extend(n int) { p.Expand(len(*p), n) } + + // Resize changes the length and capacity of a vector. // If the new length is shorter than the current length, Resize discards // trailing elements. If the new length is longer than the current length, -// Resize adds "" elements. The capacity parameter is ignored unless the -// new length or capacity is longer that the current capacity. +// Resize adds the respective zero values for the additional elements. The capacity +// parameter is ignored unless the new length or capacity is longer than the current +// capacity. The resized vector's capacity may be larger than the requested capacity. func (p *StringVector) Resize(length, capacity int) *StringVector { - i := p.Len() - p.Vector.Resize(length, capacity) - for a := p.a; i < len(a); i++ { - a[i] = "" + a := *p + + if length > cap(a) || capacity > cap(a) { + // not enough space or larger capacity requested explicitly + a = p.realloc(length, capacity) + } else if length < len(a) { + // clear trailing elements + for i := range a[length:] { + var zero string + a[length+i] = zero + } } + + *p = a[0:length] return p } +// Len returns the number of elements in the vector. +// Same as len(*p). +func (p *StringVector) Len() int { return len(*p) } + + +// Cap returns the capacity of the vector; that is, the +// maximum length the vector can grow without resizing. +// Same as cap(*p). +func (p *StringVector) Cap() int { return cap(*p) } + + // At returns the i'th element of the vector. -func (p *StringVector) At(i int) string { return p.Vector.At(i).(string) } +func (p *StringVector) At(i int) string { return (*p)[i] } // Set sets the i'th element of the vector to value x. -func (p *StringVector) Set(i int, x string) { p.a[i] = x } +func (p *StringVector) Set(i int, x string) { (*p)[i] = x } // Last returns the element in the vector of highest index. -func (p *StringVector) Last() string { return p.Vector.Last().(string) } +func (p *StringVector) Last() string { return (*p)[len(*p)-1] } // Data returns all the elements as a slice. func (p *StringVector) Data() []string { - arr := make([]string, p.Len()) - for i, v := range p.a { - arr[i] = v.(string) - } + arr := make(StringVector, len(*p)) + copy(arr, *p) return arr } @@ -50,47 +112,96 @@ func (p *StringVector) Data() []string { // Insert inserts into the vector an element of value x before // the current element at index i. func (p *StringVector) Insert(i int, x string) { - p.Vector.Insert(i, x) + p.Expand(i, 1) + (*p)[i] = x +} + + +// Delete deletes the i'th element of the vector. The gap is closed so the old +// element at index i+1 has index i afterwards. +func (p *StringVector) Delete(i int) { + a := *p + n := len(a) + + copy(a[i:n-1], a[i+1:n]) + var zero string + a[n-1] = zero // support GC, zero out entry + *p = a[0 : n-1] } -// InsertVector inserts into the vector the contents of the Vector +// InsertVector inserts into the vector the contents of the vector // x such that the 0th element of x appears at index i after insertion. func (p *StringVector) InsertVector(i int, x *StringVector) { - p.Vector.InsertVector(i, &x.Vector) + b := *x + + p.Expand(i, len(b)) + copy((*p)[i:i+len(b)], b) +} + + +// Cut deletes elements i through j-1, inclusive. +func (p *StringVector) Cut(i, j int) { + a := *p + n := len(a) + m := n - (j - i) + + copy(a[i:m], a[j:n]) + for k := m; k < n; k++ { //TODO(bflm) don't zero out the elements unless it's a Vector. + var zero string + a[k] = zero // support GC, zero out entries + } + + *p = a[0:m] } -// Slice returns a new StringVector by slicing the old one to extract slice [i:j]. +// Slice returns a new sub-vector by slicing the old one to extract slice [i:j]. // The elements are copied. The original vector is unchanged. func (p *StringVector) Slice(i, j int) *StringVector { - return &StringVector{*p.Vector.Slice(i, j)} + var s StringVector + s.realloc(j-i, 0) // will fail in Init() if j < i + copy(s, (*p)[i:j]) + return &s } +// Convenience wrappers + // Push appends x to the end of the vector. -func (p *StringVector) Push(x string) { p.Vector.Push(x) } +func (p *StringVector) Push(x string) { p.Insert(len(*p), x) } + +// Pop deletes the last element of the vector. +func (p *StringVector) Pop() string { + a := *p -// Pop deletes and returns the last element of the vector. -func (p *StringVector) Pop() string { return p.Vector.Pop().(string) } + i := len(a) - 1 + x := a[i] + var zero string + a[i] = zero // support GC, zero out entry + *p = a[0:i] + return x +} -// AppendVector appends the entire StringVector x to the end of this vector. +// AppendVector appends the entire vector x to the end of this vector. func (p *StringVector) AppendVector(x *StringVector) { - p.Vector.InsertVector(len(p.a), &x.Vector) + p.InsertVector(len(*p), x) } -// sort.Interface support -// Less returns a boolean denoting whether the i'th element is less than the j'th element. -func (p *StringVector) Less(i, j int) bool { return p.At(i) < p.At(j) } +// Swap exchanges the elements at indexes i and j. +func (p *StringVector) Swap(i, j int) { + a := *p + a[i], a[j] = a[j], a[i] +} // Iterate over all elements; driver for range func (p *StringVector) iterate(c chan<- string) { - for _, v := range p.a { - c <- v.(string) + for _, v := range *p { + c <- v } close(c) } diff --git a/src/pkg/exp/vector/stringvector_test.go b/src/pkg/container/vector/stringvector_test.go index ed65a157c..ed65a157c 100644 --- a/src/pkg/exp/vector/stringvector_test.go +++ b/src/pkg/container/vector/stringvector_test.go diff --git a/src/pkg/container/vector/vector.go b/src/pkg/container/vector/vector.go index ed1845b27..99c7753da 100644 --- a/src/pkg/container/vector/vector.go +++ b/src/pkg/container/vector/vector.go @@ -2,34 +2,26 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// The vector package implements a container for managing sequences -// of elements. Vectors grow and shrink dynamically as necessary. -package vector +// CAUTION: If this file is not vector.go, it was generated +// automatically from vector.go - DO NOT EDIT in that case! -// Vector is the container itself. -// The zero value for Vector is an empty vector ready to use. -type Vector struct { - a []interface{} - bootstrap [8]interface{} -} +package vector func (p *Vector) realloc(length, capacity int) (b []interface{}) { - if length <= cap(p.bootstrap) && capacity <= cap(p.bootstrap) { - // don't allocate; use pre-allocated bootstrap array - b = p.bootstrap[0:length] - } else { - b = make([]interface{}, length, capacity) + if capacity < initialSize { + capacity = initialSize } - copy(b, p.a) - p.a = b + b = make(Vector, length, capacity) + copy(b, *p) + *p = b return } // Insert n elements at position i. -func (p *Vector) expand(i, n int) { - a := p.a +func (p *Vector) Expand(i, n int) { + a := *p // make sure we have enough space len0 := len(a) @@ -53,18 +45,22 @@ func (p *Vector) expand(i, n int) { a[j+n] = a[j] } - p.a = a + *p = a } +// Insert n elements at the end of a vector. +func (p *Vector) Extend(n int) { p.Expand(len(*p), n) } + + // Resize changes the length and capacity of a vector. // If the new length is shorter than the current length, Resize discards // trailing elements. If the new length is longer than the current length, -// Resize adds nil elements. The capacity parameter is ignored unless the -// new length or capacity is longer that the current capacity. The resized -// vector's capacity may be larger than the requested capacity. +// Resize adds the respective zero values for the additional elements. The capacity +// parameter is ignored unless the new length or capacity is longer than the current +// capacity. The resized vector's capacity may be larger than the requested capacity. func (p *Vector) Resize(length, capacity int) *Vector { - a := p.a + a := *p if length > cap(a) || capacity > cap(a) { // not enough space or larger capacity requested explicitly @@ -72,42 +68,43 @@ func (p *Vector) Resize(length, capacity int) *Vector { } else if length < len(a) { // clear trailing elements for i := range a[length:] { - a[length+i] = nil + var zero interface{} + a[length+i] = zero } } - p.a = a[0:length] + *p = a[0:length] return p } // Len returns the number of elements in the vector. -func (p *Vector) Len() int { return len(p.a) } +// Same as len(*p). +func (p *Vector) Len() int { return len(*p) } // Cap returns the capacity of the vector; that is, the // maximum length the vector can grow without resizing. -func (p *Vector) Cap() int { return cap(p.a) } +// Same as cap(*p). +func (p *Vector) Cap() int { return cap(*p) } // At returns the i'th element of the vector. -func (p *Vector) At(i int) interface{} { return p.a[i] } +func (p *Vector) At(i int) interface{} { return (*p)[i] } // Set sets the i'th element of the vector to value x. -func (p *Vector) Set(i int, x interface{}) { p.a[i] = x } +func (p *Vector) Set(i int, x interface{}) { (*p)[i] = x } // Last returns the element in the vector of highest index. -func (p *Vector) Last() interface{} { return p.a[len(p.a)-1] } +func (p *Vector) Last() interface{} { return (*p)[len(*p)-1] } // Data returns all the elements as a slice. func (p *Vector) Data() []interface{} { - arr := make([]interface{}, p.Len()) - for i, v := range p.a { - arr[i] = v - } + arr := make(Vector, len(*p)) + copy(arr, *p) return arr } @@ -115,106 +112,93 @@ func (p *Vector) Data() []interface{} { // Insert inserts into the vector an element of value x before // the current element at index i. func (p *Vector) Insert(i int, x interface{}) { - p.expand(i, 1) - p.a[i] = x + p.Expand(i, 1) + (*p)[i] = x } // Delete deletes the i'th element of the vector. The gap is closed so the old // element at index i+1 has index i afterwards. func (p *Vector) Delete(i int) { - a := p.a + a := *p n := len(a) copy(a[i:n-1], a[i+1:n]) - a[n-1] = nil // support GC, nil out entry - p.a = a[0 : n-1] + var zero interface{} + a[n-1] = zero // support GC, zero out entry + *p = a[0 : n-1] } -// InsertVector inserts into the vector the contents of the Vector +// InsertVector inserts into the vector the contents of the vector // x such that the 0th element of x appears at index i after insertion. func (p *Vector) InsertVector(i int, x *Vector) { - p.expand(i, len(x.a)) - copy(p.a[i:i+len(x.a)], x.a) + b := *x + + p.Expand(i, len(b)) + copy((*p)[i:i+len(b)], b) } // Cut deletes elements i through j-1, inclusive. func (p *Vector) Cut(i, j int) { - a := p.a + a := *p n := len(a) m := n - (j - i) copy(a[i:m], a[j:n]) - for k := m; k < n; k++ { - a[k] = nil // support GC, nil out entries + for k := m; k < n; k++ { //TODO(bflm) don't zero out the elements unless it's a Vector. + var zero interface{} + a[k] = zero // support GC, zero out entries } - p.a = a[0:m] + *p = a[0:m] } -// Slice returns a new Vector by slicing the old one to extract slice [i:j]. +// Slice returns a new sub-vector by slicing the old one to extract slice [i:j]. // The elements are copied. The original vector is unchanged. func (p *Vector) Slice(i, j int) *Vector { - s := new(Vector).Resize(j-i, 0) // will fail in Init() if j < i - copy(s.a, p.a[i:j]) - return s -} - - -// Do calls function f for each element of the vector, in order. -// The function should not change the indexing of the vector underfoot. -func (p *Vector) Do(f func(elem interface{})) { - for i := 0; i < len(p.a); i++ { - f(p.a[i]) // not too safe if f changes the Vector - } + var s Vector + s.realloc(j-i, 0) // will fail in Init() if j < i + copy(s, (*p)[i:j]) + return &s } // Convenience wrappers // Push appends x to the end of the vector. -func (p *Vector) Push(x interface{}) { p.Insert(len(p.a), x) } +func (p *Vector) Push(x interface{}) { p.Insert(len(*p), x) } // Pop deletes the last element of the vector. func (p *Vector) Pop() interface{} { - i := len(p.a) - 1 - x := p.a[i] - p.a[i] = nil // support GC, nil out entry - p.a = p.a[0:i] - return x -} - + a := *p -// AppendVector appends the entire Vector x to the end of this vector. -func (p *Vector) AppendVector(x *Vector) { p.InsertVector(len(p.a), x) } - - -// Partial sort.Interface support - -// LessInterface provides partial support of the sort.Interface. -type LessInterface interface { - Less(y interface{}) bool + i := len(a) - 1 + x := a[i] + var zero interface{} + a[i] = zero // support GC, zero out entry + *p = a[0:i] + return x } -// Less returns a boolean denoting whether the i'th element is less than the j'th element. -func (p *Vector) Less(i, j int) bool { return p.a[i].(LessInterface).Less(p.a[j]) } +// AppendVector appends the entire vector x to the end of this vector. +func (p *Vector) AppendVector(x *Vector) { p.InsertVector(len(*p), x) } // Swap exchanges the elements at indexes i and j. func (p *Vector) Swap(i, j int) { - a := p.a + a := *p a[i], a[j] = a[j], a[i] } // Iterate over all elements; driver for range func (p *Vector) iterate(c chan<- interface{}) { - for _, v := range p.a { + for _, v := range *p { c <- v } close(c) diff --git a/src/pkg/container/vector/vector_test.go b/src/pkg/container/vector/vector_test.go index 755ba7cad..3206c7fce 100644 --- a/src/pkg/container/vector/vector_test.go +++ b/src/pkg/container/vector/vector_test.go @@ -2,309 +2,390 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +// CAUTION: If this file is not vector_test.go, it was generated +// automatically from vector_test.go - DO NOT EDIT in that case! + package vector import "testing" -import "sort" -import "fmt" -func TestZeroLen(t *testing.T) { +func TestZeroLenExp(t *testing.T) { a := new(Vector) if a.Len() != 0 { - t.Errorf("B) expected 0, got %d", a.Len()) + t.Errorf("%T: B1) expected 0, got %d", a, a.Len()) } -} - - -type VectorInterface interface { - Len() int - Cap() int -} - - -func checkSize(t *testing.T, v VectorInterface, len, cap int) { - if v.Len() != len { - t.Errorf("expected len = %d; found %d", len, v.Len()) + if len(*a) != 0 { + t.Errorf("%T: B2) expected 0, got %d", a, len(*a)) + } + var b Vector + if b.Len() != 0 { + t.Errorf("%T: B3) expected 0, got %d", b, b.Len()) } - if v.Cap() < cap { - t.Errorf("expected cap >= %d; found %d", cap, v.Cap()) + if len(b) != 0 { + t.Errorf("%T: B4) expected 0, got %d", b, len(b)) } } -func TestResize(t *testing.T) { +func TestResizeExp(t *testing.T) { var a Vector - checkSize(t, &a, 0, 0) - checkSize(t, a.Resize(0, 5), 0, 5) - checkSize(t, a.Resize(1, 0), 1, 5) - checkSize(t, a.Resize(10, 0), 10, 10) - checkSize(t, a.Resize(5, 0), 5, 10) - checkSize(t, a.Resize(3, 8), 3, 10) - checkSize(t, a.Resize(0, 100), 0, 100) - checkSize(t, a.Resize(11, 100), 11, 100) + checkSizeExp(t, &a, 0, 0) + checkSizeExp(t, a.Resize(0, 5), 0, 5) + checkSizeExp(t, a.Resize(1, 0), 1, 5) + checkSizeExp(t, a.Resize(10, 0), 10, 10) + checkSizeExp(t, a.Resize(5, 0), 5, 10) + checkSizeExp(t, a.Resize(3, 8), 3, 10) + checkSizeExp(t, a.Resize(0, 100), 0, 100) + checkSizeExp(t, a.Resize(11, 100), 11, 100) } -func TestIntResize(t *testing.T) { - var a IntVector - checkSize(t, &a, 0, 0) - a.Push(1) - a.Push(2) - a.Push(3) - a.Push(4) - checkSize(t, &a, 4, 4) - checkSize(t, a.Resize(10, 0), 10, 10) +func TestResize2Exp(t *testing.T) { + var a Vector + checkSizeExp(t, &a, 0, 0) + a.Push(int2Value(1)) + a.Push(int2Value(2)) + a.Push(int2Value(3)) + a.Push(int2Value(4)) + checkSizeExp(t, &a, 4, 4) + checkSizeExp(t, a.Resize(10, 0), 10, 10) for i := 4; i < a.Len(); i++ { - if a.At(i) != 0 { - t.Errorf("expected a.At(%d) == 0; found %d", i, a.At(i)) + if a.At(i) != zero { + t.Errorf("%T: expected a.At(%d) == %v; found %v!", a, i, zero, a.At(i)) } } -} - - -func TestStringResize(t *testing.T) { - var a StringVector - checkSize(t, &a, 0, 0) - a.Push("1") - a.Push("2") - a.Push("3") - a.Push("4") - checkSize(t, &a, 4, 4) - checkSize(t, a.Resize(10, 0), 10, 10) - for i := 4; i < a.Len(); i++ { - if a.At(i) != "" { - t.Errorf("expected a.At(%d) == "+"; found %s", i, a.At(i)) + for i := 4; i < len(a); i++ { + if a[i] != zero { + t.Errorf("%T: expected a[%d] == %v; found %v", a, i, zero, a[i]) } } } -func checkNil(t *testing.T, a *Vector, i int) { +func checkZeroExp(t *testing.T, a *Vector, i int) { for j := 0; j < i; j++ { - if a.At(j) == nil { - t.Errorf("expected a.At(%d) == %d; found %v", j, j, a.At(j)) + if a.At(j) == zero { + t.Errorf("%T: 1 expected a.At(%d) == %d; found %v", a, j, j, a.At(j)) + } + if (*a)[j] == zero { + t.Errorf("%T: 2 expected (*a)[%d] == %d; found %v", a, j, j, (*a)[j]) } } for ; i < a.Len(); i++ { - if a.At(i) != nil { - t.Errorf("expected a.At(%d) == nil; found %v", i, a.At(i)) + if a.At(i) != zero { + t.Errorf("%T: 3 expected a.At(%d) == %v; found %v", a, i, zero, a.At(i)) + } + if (*a)[i] != zero { + t.Errorf("%T: 4 expected (*a)[%d] == %v; found %v", a, i, zero, (*a)[i]) } } } -func TestTrailingElements(t *testing.T) { +func TestTrailingElementsExp(t *testing.T) { var a Vector for i := 0; i < 10; i++ { - a.Push(i) + a.Push(int2Value(i + 1)) } - checkNil(t, &a, 10) - checkSize(t, &a, 10, 16) - checkSize(t, a.Resize(5, 0), 5, 16) - checkSize(t, a.Resize(10, 0), 10, 16) - checkNil(t, &a, 5) + checkZeroExp(t, &a, 10) + checkSizeExp(t, &a, 10, 16) + checkSizeExp(t, a.Resize(5, 0), 5, 16) + checkSizeExp(t, a.Resize(10, 0), 10, 16) + checkZeroExp(t, &a, 5) } -func val(i int) int { return i*991 - 1234 } - - -func TestAccess(t *testing.T) { +func TestAccessExp(t *testing.T) { const n = 100 var a Vector a.Resize(n, 0) for i := 0; i < n; i++ { - a.Set(i, val(i)) + a.Set(i, int2Value(valExp(i))) } for i := 0; i < n; i++ { - if a.At(i).(int) != val(i) { + if elem2Value(a.At(i)) != int2Value(valExp(i)) { + t.Error(i) + } + } + var b Vector + b.Resize(n, 0) + for i := 0; i < n; i++ { + b[i] = int2Value(valExp(i)) + } + for i := 0; i < n; i++ { + if elem2Value(b[i]) != int2Value(valExp(i)) { t.Error(i) } } } -func TestInsertDeleteClear(t *testing.T) { +func TestInsertDeleteClearExp(t *testing.T) { const n = 100 var a Vector for i := 0; i < n; i++ { if a.Len() != i { - t.Errorf("A) wrong len %d (expected %d)", a.Len(), i) + t.Errorf("T%: A) wrong Len() %d (expected %d)", a, a.Len(), i) } - a.Insert(0, val(i)) - if a.Last().(int) != val(0) { - t.Error("B") + if len(a) != i { + t.Errorf("T%: A) wrong len() %d (expected %d)", a, len(a), i) + } + a.Insert(0, int2Value(valExp(i))) + if elem2Value(a.Last()) != int2Value(valExp(0)) { + t.Error("T%: B", a) } } for i := n - 1; i >= 0; i-- { - if a.Last().(int) != val(0) { - t.Error("C") + if elem2Value(a.Last()) != int2Value(valExp(0)) { + t.Error("T%: C", a) + } + if elem2Value(a.At(0)) != int2Value(valExp(i)) { + t.Error("T%: D", a) } - if a.At(0).(int) != val(i) { - t.Error("D") + if elem2Value(a[0]) != int2Value(valExp(i)) { + t.Error("T%: D2", a) } a.Delete(0) if a.Len() != i { - t.Errorf("E) wrong len %d (expected %d)", a.Len(), i) + t.Errorf("T%: E) wrong Len() %d (expected %d)", a, a.Len(), i) + } + if len(a) != i { + t.Errorf("T%: E) wrong len() %d (expected %d)", a, len(a), i) } } if a.Len() != 0 { - t.Errorf("F) wrong len %d (expected 0)", a.Len()) + t.Errorf("T%: F) wrong Len() %d (expected 0)", a, a.Len()) + } + if len(a) != 0 { + t.Errorf("T%: F) wrong len() %d (expected 0)", a, len(a)) } for i := 0; i < n; i++ { - a.Push(val(i)) + a.Push(int2Value(valExp(i))) if a.Len() != i+1 { - t.Errorf("G) wrong len %d (expected %d)", a.Len(), i+1) + t.Errorf("T%: G) wrong Len() %d (expected %d)", a, a.Len(), i+1) + } + if len(a) != i+1 { + t.Errorf("T%: G) wrong len() %d (expected %d)", a, len(a), i+1) } - if a.Last().(int) != val(i) { - t.Error("H") + if elem2Value(a.Last()) != int2Value(valExp(i)) { + t.Error("T%: H", a) } } a.Resize(0, 0) if a.Len() != 0 { - t.Errorf("I wrong len %d (expected 0)", a.Len()) + t.Errorf("T%: I wrong Len() %d (expected 0)", a, a.Len()) + } + if len(a) != 0 { + t.Errorf("T%: I wrong len() %d (expected 0)", a, len(a)) } const m = 5 for j := 0; j < m; j++ { - a.Push(j) + a.Push(int2Value(j)) for i := 0; i < n; i++ { - x := val(i) - a.Push(x) - if a.Pop().(int) != x { - t.Error("J") + x := valExp(i) + a.Push(int2Value(x)) + if elem2Value(a.Pop()) != int2Value(x) { + t.Error("T%: J", a) } if a.Len() != j+1 { - t.Errorf("K) wrong len %d (expected %d)", a.Len(), j+1) + t.Errorf("T%: K) wrong Len() %d (expected %d)", a, a.Len(), j+1) + } + if len(a) != j+1 { + t.Errorf("T%: K) wrong len() %d (expected %d)", a, len(a), j+1) } } } if a.Len() != m { - t.Errorf("L) wrong len %d (expected %d)", a.Len(), m) + t.Errorf("T%: L) wrong Len() %d (expected %d)", a, a.Len(), m) + } + if len(a) != m { + t.Errorf("T%: L) wrong len() %d (expected %d)", a, len(a), m) } } -func verify_slice(t *testing.T, x *Vector, elt, i, j int) { +func verify_sliceExp(t *testing.T, x *Vector, elt, i, j int) { for k := i; k < j; k++ { - if x.At(k).(int) != elt { - t.Errorf("M) wrong [%d] element %d (expected %d)", k, x.At(k).(int), elt) + if elem2Value(x.At(k)) != int2Value(elt) { + t.Errorf("T%: M) wrong [%d] element %v (expected %v)", x, k, elem2Value(x.At(k)), int2Value(elt)) } } s := x.Slice(i, j) for k, n := 0, j-i; k < n; k++ { - if s.At(k).(int) != elt { - t.Errorf("N) wrong [%d] element %d (expected %d)", k, x.At(k).(int), elt) + if elem2Value(s.At(k)) != int2Value(elt) { + t.Errorf("T%: N) wrong [%d] element %v (expected %v)", x, k, elem2Value(x.At(k)), int2Value(elt)) } } } -func verify_pattern(t *testing.T, x *Vector, a, b, c int) { +func verify_patternExp(t *testing.T, x *Vector, a, b, c int) { n := a + b + c if x.Len() != n { - t.Errorf("O) wrong len %d (expected %d)", x.Len(), n) + t.Errorf("T%: O) wrong Len() %d (expected %d)", x, x.Len(), n) + } + if len(*x) != n { + t.Errorf("T%: O) wrong len() %d (expected %d)", x, len(*x), n) } - verify_slice(t, x, 0, 0, a) - verify_slice(t, x, 1, a, a+b) - verify_slice(t, x, 0, a+b, n) + verify_sliceExp(t, x, 0, 0, a) + verify_sliceExp(t, x, 1, a, a+b) + verify_sliceExp(t, x, 0, a+b, n) } -func make_vector(elt, len int) *Vector { +func make_vectorExp(elt, len int) *Vector { x := new(Vector).Resize(len, 0) for i := 0; i < len; i++ { - x.Set(i, elt) + x.Set(i, int2Value(elt)) } return x } -func TestInsertVector(t *testing.T) { +func TestInsertVectorExp(t *testing.T) { // 1 - a := make_vector(0, 0) - b := make_vector(1, 10) + a := make_vectorExp(0, 0) + b := make_vectorExp(1, 10) a.InsertVector(0, b) - verify_pattern(t, a, 0, 10, 0) + verify_patternExp(t, a, 0, 10, 0) // 2 - a = make_vector(0, 10) - b = make_vector(1, 0) + a = make_vectorExp(0, 10) + b = make_vectorExp(1, 0) a.InsertVector(5, b) - verify_pattern(t, a, 5, 0, 5) + verify_patternExp(t, a, 5, 0, 5) // 3 - a = make_vector(0, 10) - b = make_vector(1, 3) + a = make_vectorExp(0, 10) + b = make_vectorExp(1, 3) a.InsertVector(3, b) - verify_pattern(t, a, 3, 3, 7) + verify_patternExp(t, a, 3, 3, 7) // 4 - a = make_vector(0, 10) - b = make_vector(1, 1000) + a = make_vectorExp(0, 10) + b = make_vectorExp(1, 1000) a.InsertVector(8, b) - verify_pattern(t, a, 8, 1000, 2) + verify_patternExp(t, a, 8, 1000, 2) } -// This also tests IntVector and StringVector -func TestSorting(t *testing.T) { - const n = 100 - - a := new(IntVector).Resize(n, 0) - for i := n - 1; i >= 0; i-- { - a.Set(i, n-1-i) +func TestDoExp(t *testing.T) { + const n = 25 + const salt = 17 + a := new(Vector).Resize(n, 0) + for i := 0; i < n; i++ { + a.Set(i, int2Value(salt*i)) } - if sort.IsSorted(a) { - t.Error("int vector not sorted") + count := 0 + a.Do(func(e interface{}) { + i := intf2Value(e) + if i != int2Value(count*salt) { + t.Error(tname(a), "value at", count, "should be", count*salt, "not", i) + } + count++ + }) + if count != n { + t.Error(tname(a), "should visit", n, "values; did visit", count) } - b := new(StringVector).Resize(n, 0) - for i := n - 1; i >= 0; i-- { - b.Set(i, fmt.Sprint(n-1-i)) + b := new(Vector).Resize(n, 0) + for i := 0; i < n; i++ { + (*b)[i] = int2Value(salt * i) } - if sort.IsSorted(b) { - t.Error("string vector not sorted") + count = 0 + b.Do(func(e interface{}) { + i := intf2Value(e) + if i != int2Value(count*salt) { + t.Error(tname(b), "b) value at", count, "should be", count*salt, "not", i) + } + count++ + }) + if count != n { + t.Error(tname(b), "b) should visit", n, "values; did visit", count) } -} - -func TestDo(t *testing.T) { - const n = 25 - const salt = 17 - a := new(IntVector).Resize(n, 0) + var c Vector + c.Resize(n, 0) for i := 0; i < n; i++ { - a.Set(i, salt*i) + c[i] = int2Value(salt * i) } - count := 0 - a.Do(func(e interface{}) { - i := e.(int) - if i != count*salt { - t.Error("value at", count, "should be", count*salt, "not", i) + count = 0 + c.Do(func(e interface{}) { + i := intf2Value(e) + if i != int2Value(count*salt) { + t.Error(tname(c), "c) value at", count, "should be", count*salt, "not", i) } count++ }) if count != n { - t.Error("should visit", n, "values; did visit", count) + t.Error(tname(c), "c) should visit", n, "values; did visit", count) } + } -func TestIter(t *testing.T) { +func TestIterExp(t *testing.T) { const Len = 100 x := new(Vector).Resize(Len, 0) for i := 0; i < Len; i++ { - x.Set(i, i*i) + x.Set(i, int2Value(i*i)) } i := 0 for v := range x.Iter() { - if v.(int) != i*i { - t.Error("Iter expected", i*i, "got", v.(int)) + if elem2Value(v) != int2Value(i*i) { + t.Error(tname(x), "Iter expected", i*i, "got", elem2Value(v)) } i++ } if i != Len { - t.Error("Iter stopped at", i, "not", Len) + t.Error(tname(x), "Iter stopped at", i, "not", Len) + } + y := new(Vector).Resize(Len, 0) + for i := 0; i < Len; i++ { + (*y)[i] = int2Value(i * i) + } + i = 0 + for v := range y.Iter() { + if elem2Value(v) != int2Value(i*i) { + t.Error(tname(y), "y, Iter expected", i*i, "got", elem2Value(v)) + } + i++ + } + if i != Len { + t.Error(tname(y), "y, Iter stopped at", i, "not", Len) + } + var z Vector + z.Resize(Len, 0) + for i := 0; i < Len; i++ { + z[i] = int2Value(i * i) + } + i = 0 + for v := range z.Iter() { + if elem2Value(v) != int2Value(i*i) { + t.Error(tname(z), "z, Iter expected", i*i, "got", elem2Value(v)) + } + i++ + } + if i != Len { + t.Error(tname(z), "z, Iter stopped at", i, "not", Len) + } +} + +func TestVectorData(t *testing.T) { + // verify Data() returns a slice of a copy, not a slice of the original vector + const Len = 10 + var src Vector + for i := 0; i < Len; i++ { + src.Push(int2Value(i * i)) + } + dest := src.Data() + for i := 0; i < Len; i++ { + src[i] = int2Value(-1) + v := elem2Value(dest[i]) + if v != int2Value(i*i) { + t.Error(tname(src), "expected", i*i, "got", v) + } } } diff --git a/src/pkg/exp/vector/Makefile b/src/pkg/exp/vector/Makefile deleted file mode 100644 index a9a5715b0..000000000 --- a/src/pkg/exp/vector/Makefile +++ /dev/null @@ -1,69 +0,0 @@ -# Copyright 2009 The Go Authors. All rights reserved. -# Use of this source code is governed by a BSD-style -# license that can be found in the LICENSE file. - -include ../../../Make.$(GOARCH) - -TARG=exp/vector -GOFILES=\ - defs.go\ - intvector.go\ - stringvector.go\ - vector.go\ - -generate: vector.go vector_test.go - < vector.go cat\ - | gofmt -r='Vector -> IntVector'\ - | gofmt -r='interface{} -> int'\ - > intvector.go\ - - < vector.go cat\ - | gofmt -r='Vector -> StringVector'\ - | gofmt -r='interface{} -> string'\ - > stringvector.go\ - - < vector_test.go cat\ - | gofmt -r='Vector -> IntVector'\ - | gofmt -r='zero -> intzero'\ - | gofmt -r='elem2Value -> elem2IntValue'\ - | gofmt -r='intf2Value -> intf2IntValue'\ - | gofmt -r='int2Value -> int2IntValue'\ - | gofmt -r='TestZeroLenExp -> TestIntZeroLenExp'\ - | gofmt -r='TestResizeExp -> TestIntResizeExp'\ - | gofmt -r='TestResize2Exp -> TestIntResize2Exp'\ - | gofmt -r='checkZeroExp -> checkIntZeroExp'\ - | gofmt -r='TestTrailingElementsExp -> TestIntTrailingElementsExp'\ - | gofmt -r='TestAccessExp -> TestIntAccessExp'\ - | gofmt -r='TestInsertDeleteClearExp -> TestIntInsertDeleteClearExp'\ - | gofmt -r='verify_sliceExp -> verify_sliceIntExp'\ - | gofmt -r='verify_patternExp -> verify_patternIntExp'\ - | gofmt -r='make_vectorExp -> make_vectorIntExp'\ - | gofmt -r='TestInsertVectorExp -> TestIntInsertVectorExp'\ - | gofmt -r='TestDoExp -> TestIntDoExp'\ - | gofmt -r='TestIterExp -> TestIntIterExp'\ - | gofmt -r='TestVectorData -> TestIntVectorData'\ - > intvector_test.go\ - - < vector_test.go cat\ - | gofmt -r='Vector -> StringVector'\ - | gofmt -r='zero -> strzero'\ - | gofmt -r='int2Value -> int2StrValue'\ - | gofmt -r='intf2Value -> intf2StrValue'\ - | gofmt -r='elem2Value -> elem2StrValue'\ - | gofmt -r='TestZeroLenExp -> TestStrZeroLenExp'\ - | gofmt -r='TestResizeExp -> TestStrResizeExp'\ - | gofmt -r='TestResize2Exp -> TestStrResize2Exp'\ - | gofmt -r='checkZeroExp -> checkStrZeroExp'\ - | gofmt -r='TestTrailingElementsExp -> TestStrTrailingElementsExp'\ - | gofmt -r='TestAccessExp -> TestStrAccessExp'\ - | gofmt -r='TestInsertDeleteClearExp -> TestStrInsertDeleteClearExp'\ - | gofmt -r='verify_sliceExp -> verify_sliceStrExp'\ - | gofmt -r='verify_patternExp -> verify_patternStrExp'\ - | gofmt -r='make_vectorExp -> make_vectorStrExp'\ - | gofmt -r='TestInsertVectorExp -> TestStrInsertVectorExp'\ - | gofmt -r='TestDoExp -> TestStrDoExp'\ - | gofmt -r='TestIterExp -> TestStrIterExp'\ - | gofmt -r='TestVectorData -> TestStrVectorData'\ - > stringvector_test.go - -include ../../../Make.pkg diff --git a/src/pkg/exp/vector/intvector.go b/src/pkg/exp/vector/intvector.go deleted file mode 100644 index a1754a94f..000000000 --- a/src/pkg/exp/vector/intvector.go +++ /dev/null @@ -1,215 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// CAUTION: If this file is not vector.go, it was generated -// automatically from vector.go - DO NOT EDIT in that case! - -package vector - - -func (p *IntVector) realloc(length, capacity int) (b []int) { - if capacity < initialSize { - capacity = initialSize - } - b = make(IntVector, length, capacity) - copy(b, *p) - *p = b - return -} - - -// Insert n elements at position i. -func (p *IntVector) Expand(i, n int) { - a := *p - - // make sure we have enough space - len0 := len(a) - len1 := len0 + n - if len1 <= cap(a) { - // enough space - just expand - a = a[0:len1] - } else { - // not enough space - double capacity - capb := cap(a) * 2 - if capb < len1 { - // still not enough - use required length - capb = len1 - } - // capb >= len1 - a = p.realloc(len1, capb) - } - - // make a hole - for j := len0 - 1; j >= i; j-- { - a[j+n] = a[j] - } - - *p = a -} - - -// Insert n elements at the end of a vector. -func (p *IntVector) Extend(n int) { p.Expand(len(*p), n) } - - -// Resize changes the length and capacity of a vector. -// If the new length is shorter than the current length, Resize discards -// trailing elements. If the new length is longer than the current length, -// Resize adds the respective zero values for the additional elements. The capacity -// parameter is ignored unless the new length or capacity is longer than the current -// capacity. The resized vector's capacity may be larger than the requested capacity. -func (p *IntVector) Resize(length, capacity int) *IntVector { - a := *p - - if length > cap(a) || capacity > cap(a) { - // not enough space or larger capacity requested explicitly - a = p.realloc(length, capacity) - } else if length < len(a) { - // clear trailing elements - for i := range a[length:] { - var zero int - a[length+i] = zero - } - } - - *p = a[0:length] - return p -} - - -// Len returns the number of elements in the vector. -// Same as len(*p). -func (p *IntVector) Len() int { return len(*p) } - - -// Cap returns the capacity of the vector; that is, the -// maximum length the vector can grow without resizing. -// Same as cap(*p). -func (p *IntVector) Cap() int { return cap(*p) } - - -// At returns the i'th element of the vector. -func (p *IntVector) At(i int) int { return (*p)[i] } - - -// Set sets the i'th element of the vector to value x. -func (p *IntVector) Set(i int, x int) { (*p)[i] = x } - - -// Last returns the element in the vector of highest index. -func (p *IntVector) Last() int { return (*p)[len(*p)-1] } - - -// Data returns all the elements as a slice. -func (p *IntVector) Data() []int { - arr := make(IntVector, len(*p)) - copy(arr, *p) - return arr -} - - -// Insert inserts into the vector an element of value x before -// the current element at index i. -func (p *IntVector) Insert(i int, x int) { - p.Expand(i, 1) - (*p)[i] = x -} - - -// Delete deletes the i'th element of the vector. The gap is closed so the old -// element at index i+1 has index i afterwards. -func (p *IntVector) Delete(i int) { - a := *p - n := len(a) - - copy(a[i:n-1], a[i+1:n]) - var zero int - a[n-1] = zero // support GC, zero out entry - *p = a[0 : n-1] -} - - -// InsertVector inserts into the vector the contents of the vector -// x such that the 0th element of x appears at index i after insertion. -func (p *IntVector) InsertVector(i int, x *IntVector) { - b := *x - - p.Expand(i, len(b)) - copy((*p)[i:i+len(b)], b) -} - - -// Cut deletes elements i through j-1, inclusive. -func (p *IntVector) Cut(i, j int) { - a := *p - n := len(a) - m := n - (j - i) - - copy(a[i:m], a[j:n]) - for k := m; k < n; k++ { //TODO(bflm) don't zero out the elements unless it's a Vector. - var zero int - a[k] = zero // support GC, zero out entries - } - - *p = a[0:m] -} - - -// Slice returns a new sub-vector by slicing the old one to extract slice [i:j]. -// The elements are copied. The original vector is unchanged. -func (p *IntVector) Slice(i, j int) *IntVector { - var s IntVector - s.realloc(j-i, 0) // will fail in Init() if j < i - copy(s, (*p)[i:j]) - return &s -} - - -// Convenience wrappers - -// Push appends x to the end of the vector. -func (p *IntVector) Push(x int) { p.Insert(len(*p), x) } - - -// Pop deletes the last element of the vector. -func (p *IntVector) Pop() int { - a := *p - - i := len(a) - 1 - x := a[i] - var zero int - a[i] = zero // support GC, zero out entry - *p = a[0:i] - return x -} - - -// AppendVector appends the entire vector x to the end of this vector. -func (p *IntVector) AppendVector(x *IntVector) { - p.InsertVector(len(*p), x) -} - - -// Swap exchanges the elements at indexes i and j. -func (p *IntVector) Swap(i, j int) { - a := *p - a[i], a[j] = a[j], a[i] -} - - -// Iterate over all elements; driver for range -func (p *IntVector) iterate(c chan<- int) { - for _, v := range *p { - c <- v - } - close(c) -} - - -// Channel iterator for range. -func (p *IntVector) Iter() <-chan int { - c := make(chan int) - go p.iterate(c) - return c -} diff --git a/src/pkg/exp/vector/stringvector.go b/src/pkg/exp/vector/stringvector.go deleted file mode 100644 index fad20f58a..000000000 --- a/src/pkg/exp/vector/stringvector.go +++ /dev/null @@ -1,215 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// CAUTION: If this file is not vector.go, it was generated -// automatically from vector.go - DO NOT EDIT in that case! - -package vector - - -func (p *StringVector) realloc(length, capacity int) (b []string) { - if capacity < initialSize { - capacity = initialSize - } - b = make(StringVector, length, capacity) - copy(b, *p) - *p = b - return -} - - -// Insert n elements at position i. -func (p *StringVector) Expand(i, n int) { - a := *p - - // make sure we have enough space - len0 := len(a) - len1 := len0 + n - if len1 <= cap(a) { - // enough space - just expand - a = a[0:len1] - } else { - // not enough space - double capacity - capb := cap(a) * 2 - if capb < len1 { - // still not enough - use required length - capb = len1 - } - // capb >= len1 - a = p.realloc(len1, capb) - } - - // make a hole - for j := len0 - 1; j >= i; j-- { - a[j+n] = a[j] - } - - *p = a -} - - -// Insert n elements at the end of a vector. -func (p *StringVector) Extend(n int) { p.Expand(len(*p), n) } - - -// Resize changes the length and capacity of a vector. -// If the new length is shorter than the current length, Resize discards -// trailing elements. If the new length is longer than the current length, -// Resize adds the respective zero values for the additional elements. The capacity -// parameter is ignored unless the new length or capacity is longer than the current -// capacity. The resized vector's capacity may be larger than the requested capacity. -func (p *StringVector) Resize(length, capacity int) *StringVector { - a := *p - - if length > cap(a) || capacity > cap(a) { - // not enough space or larger capacity requested explicitly - a = p.realloc(length, capacity) - } else if length < len(a) { - // clear trailing elements - for i := range a[length:] { - var zero string - a[length+i] = zero - } - } - - *p = a[0:length] - return p -} - - -// Len returns the number of elements in the vector. -// Same as len(*p). -func (p *StringVector) Len() int { return len(*p) } - - -// Cap returns the capacity of the vector; that is, the -// maximum length the vector can grow without resizing. -// Same as cap(*p). -func (p *StringVector) Cap() int { return cap(*p) } - - -// At returns the i'th element of the vector. -func (p *StringVector) At(i int) string { return (*p)[i] } - - -// Set sets the i'th element of the vector to value x. -func (p *StringVector) Set(i int, x string) { (*p)[i] = x } - - -// Last returns the element in the vector of highest index. -func (p *StringVector) Last() string { return (*p)[len(*p)-1] } - - -// Data returns all the elements as a slice. -func (p *StringVector) Data() []string { - arr := make(StringVector, len(*p)) - copy(arr, *p) - return arr -} - - -// Insert inserts into the vector an element of value x before -// the current element at index i. -func (p *StringVector) Insert(i int, x string) { - p.Expand(i, 1) - (*p)[i] = x -} - - -// Delete deletes the i'th element of the vector. The gap is closed so the old -// element at index i+1 has index i afterwards. -func (p *StringVector) Delete(i int) { - a := *p - n := len(a) - - copy(a[i:n-1], a[i+1:n]) - var zero string - a[n-1] = zero // support GC, zero out entry - *p = a[0 : n-1] -} - - -// InsertVector inserts into the vector the contents of the vector -// x such that the 0th element of x appears at index i after insertion. -func (p *StringVector) InsertVector(i int, x *StringVector) { - b := *x - - p.Expand(i, len(b)) - copy((*p)[i:i+len(b)], b) -} - - -// Cut deletes elements i through j-1, inclusive. -func (p *StringVector) Cut(i, j int) { - a := *p - n := len(a) - m := n - (j - i) - - copy(a[i:m], a[j:n]) - for k := m; k < n; k++ { //TODO(bflm) don't zero out the elements unless it's a Vector. - var zero string - a[k] = zero // support GC, zero out entries - } - - *p = a[0:m] -} - - -// Slice returns a new sub-vector by slicing the old one to extract slice [i:j]. -// The elements are copied. The original vector is unchanged. -func (p *StringVector) Slice(i, j int) *StringVector { - var s StringVector - s.realloc(j-i, 0) // will fail in Init() if j < i - copy(s, (*p)[i:j]) - return &s -} - - -// Convenience wrappers - -// Push appends x to the end of the vector. -func (p *StringVector) Push(x string) { p.Insert(len(*p), x) } - - -// Pop deletes the last element of the vector. -func (p *StringVector) Pop() string { - a := *p - - i := len(a) - 1 - x := a[i] - var zero string - a[i] = zero // support GC, zero out entry - *p = a[0:i] - return x -} - - -// AppendVector appends the entire vector x to the end of this vector. -func (p *StringVector) AppendVector(x *StringVector) { - p.InsertVector(len(*p), x) -} - - -// Swap exchanges the elements at indexes i and j. -func (p *StringVector) Swap(i, j int) { - a := *p - a[i], a[j] = a[j], a[i] -} - - -// Iterate over all elements; driver for range -func (p *StringVector) iterate(c chan<- string) { - for _, v := range *p { - c <- v - } - close(c) -} - - -// Channel iterator for range. -func (p *StringVector) Iter() <-chan string { - c := make(chan string) - go p.iterate(c) - return c -} diff --git a/src/pkg/exp/vector/vector.go b/src/pkg/exp/vector/vector.go deleted file mode 100644 index 99c7753da..000000000 --- a/src/pkg/exp/vector/vector.go +++ /dev/null @@ -1,213 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// CAUTION: If this file is not vector.go, it was generated -// automatically from vector.go - DO NOT EDIT in that case! - -package vector - - -func (p *Vector) realloc(length, capacity int) (b []interface{}) { - if capacity < initialSize { - capacity = initialSize - } - b = make(Vector, length, capacity) - copy(b, *p) - *p = b - return -} - - -// Insert n elements at position i. -func (p *Vector) Expand(i, n int) { - a := *p - - // make sure we have enough space - len0 := len(a) - len1 := len0 + n - if len1 <= cap(a) { - // enough space - just expand - a = a[0:len1] - } else { - // not enough space - double capacity - capb := cap(a) * 2 - if capb < len1 { - // still not enough - use required length - capb = len1 - } - // capb >= len1 - a = p.realloc(len1, capb) - } - - // make a hole - for j := len0 - 1; j >= i; j-- { - a[j+n] = a[j] - } - - *p = a -} - - -// Insert n elements at the end of a vector. -func (p *Vector) Extend(n int) { p.Expand(len(*p), n) } - - -// Resize changes the length and capacity of a vector. -// If the new length is shorter than the current length, Resize discards -// trailing elements. If the new length is longer than the current length, -// Resize adds the respective zero values for the additional elements. The capacity -// parameter is ignored unless the new length or capacity is longer than the current -// capacity. The resized vector's capacity may be larger than the requested capacity. -func (p *Vector) Resize(length, capacity int) *Vector { - a := *p - - if length > cap(a) || capacity > cap(a) { - // not enough space or larger capacity requested explicitly - a = p.realloc(length, capacity) - } else if length < len(a) { - // clear trailing elements - for i := range a[length:] { - var zero interface{} - a[length+i] = zero - } - } - - *p = a[0:length] - return p -} - - -// Len returns the number of elements in the vector. -// Same as len(*p). -func (p *Vector) Len() int { return len(*p) } - - -// Cap returns the capacity of the vector; that is, the -// maximum length the vector can grow without resizing. -// Same as cap(*p). -func (p *Vector) Cap() int { return cap(*p) } - - -// At returns the i'th element of the vector. -func (p *Vector) At(i int) interface{} { return (*p)[i] } - - -// Set sets the i'th element of the vector to value x. -func (p *Vector) Set(i int, x interface{}) { (*p)[i] = x } - - -// Last returns the element in the vector of highest index. -func (p *Vector) Last() interface{} { return (*p)[len(*p)-1] } - - -// Data returns all the elements as a slice. -func (p *Vector) Data() []interface{} { - arr := make(Vector, len(*p)) - copy(arr, *p) - return arr -} - - -// Insert inserts into the vector an element of value x before -// the current element at index i. -func (p *Vector) Insert(i int, x interface{}) { - p.Expand(i, 1) - (*p)[i] = x -} - - -// Delete deletes the i'th element of the vector. The gap is closed so the old -// element at index i+1 has index i afterwards. -func (p *Vector) Delete(i int) { - a := *p - n := len(a) - - copy(a[i:n-1], a[i+1:n]) - var zero interface{} - a[n-1] = zero // support GC, zero out entry - *p = a[0 : n-1] -} - - -// InsertVector inserts into the vector the contents of the vector -// x such that the 0th element of x appears at index i after insertion. -func (p *Vector) InsertVector(i int, x *Vector) { - b := *x - - p.Expand(i, len(b)) - copy((*p)[i:i+len(b)], b) -} - - -// Cut deletes elements i through j-1, inclusive. -func (p *Vector) Cut(i, j int) { - a := *p - n := len(a) - m := n - (j - i) - - copy(a[i:m], a[j:n]) - for k := m; k < n; k++ { //TODO(bflm) don't zero out the elements unless it's a Vector. - var zero interface{} - a[k] = zero // support GC, zero out entries - } - - *p = a[0:m] -} - - -// Slice returns a new sub-vector by slicing the old one to extract slice [i:j]. -// The elements are copied. The original vector is unchanged. -func (p *Vector) Slice(i, j int) *Vector { - var s Vector - s.realloc(j-i, 0) // will fail in Init() if j < i - copy(s, (*p)[i:j]) - return &s -} - - -// Convenience wrappers - -// Push appends x to the end of the vector. -func (p *Vector) Push(x interface{}) { p.Insert(len(*p), x) } - - -// Pop deletes the last element of the vector. -func (p *Vector) Pop() interface{} { - a := *p - - i := len(a) - 1 - x := a[i] - var zero interface{} - a[i] = zero // support GC, zero out entry - *p = a[0:i] - return x -} - - -// AppendVector appends the entire vector x to the end of this vector. -func (p *Vector) AppendVector(x *Vector) { p.InsertVector(len(*p), x) } - - -// Swap exchanges the elements at indexes i and j. -func (p *Vector) Swap(i, j int) { - a := *p - a[i], a[j] = a[j], a[i] -} - - -// Iterate over all elements; driver for range -func (p *Vector) iterate(c chan<- interface{}) { - for _, v := range *p { - c <- v - } - close(c) -} - - -// Channel iterator for range. -func (p *Vector) Iter() <-chan interface{} { - c := make(chan interface{}) - go p.iterate(c) - return c -} diff --git a/src/pkg/exp/vector/vector_test.go b/src/pkg/exp/vector/vector_test.go deleted file mode 100644 index 3206c7fce..000000000 --- a/src/pkg/exp/vector/vector_test.go +++ /dev/null @@ -1,391 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// CAUTION: If this file is not vector_test.go, it was generated -// automatically from vector_test.go - DO NOT EDIT in that case! - -package vector - -import "testing" - - -func TestZeroLenExp(t *testing.T) { - a := new(Vector) - if a.Len() != 0 { - t.Errorf("%T: B1) expected 0, got %d", a, a.Len()) - } - if len(*a) != 0 { - t.Errorf("%T: B2) expected 0, got %d", a, len(*a)) - } - var b Vector - if b.Len() != 0 { - t.Errorf("%T: B3) expected 0, got %d", b, b.Len()) - } - if len(b) != 0 { - t.Errorf("%T: B4) expected 0, got %d", b, len(b)) - } -} - - -func TestResizeExp(t *testing.T) { - var a Vector - checkSizeExp(t, &a, 0, 0) - checkSizeExp(t, a.Resize(0, 5), 0, 5) - checkSizeExp(t, a.Resize(1, 0), 1, 5) - checkSizeExp(t, a.Resize(10, 0), 10, 10) - checkSizeExp(t, a.Resize(5, 0), 5, 10) - checkSizeExp(t, a.Resize(3, 8), 3, 10) - checkSizeExp(t, a.Resize(0, 100), 0, 100) - checkSizeExp(t, a.Resize(11, 100), 11, 100) -} - - -func TestResize2Exp(t *testing.T) { - var a Vector - checkSizeExp(t, &a, 0, 0) - a.Push(int2Value(1)) - a.Push(int2Value(2)) - a.Push(int2Value(3)) - a.Push(int2Value(4)) - checkSizeExp(t, &a, 4, 4) - checkSizeExp(t, a.Resize(10, 0), 10, 10) - for i := 4; i < a.Len(); i++ { - if a.At(i) != zero { - t.Errorf("%T: expected a.At(%d) == %v; found %v!", a, i, zero, a.At(i)) - } - } - for i := 4; i < len(a); i++ { - if a[i] != zero { - t.Errorf("%T: expected a[%d] == %v; found %v", a, i, zero, a[i]) - } - } -} - - -func checkZeroExp(t *testing.T, a *Vector, i int) { - for j := 0; j < i; j++ { - if a.At(j) == zero { - t.Errorf("%T: 1 expected a.At(%d) == %d; found %v", a, j, j, a.At(j)) - } - if (*a)[j] == zero { - t.Errorf("%T: 2 expected (*a)[%d] == %d; found %v", a, j, j, (*a)[j]) - } - } - for ; i < a.Len(); i++ { - if a.At(i) != zero { - t.Errorf("%T: 3 expected a.At(%d) == %v; found %v", a, i, zero, a.At(i)) - } - if (*a)[i] != zero { - t.Errorf("%T: 4 expected (*a)[%d] == %v; found %v", a, i, zero, (*a)[i]) - } - } -} - - -func TestTrailingElementsExp(t *testing.T) { - var a Vector - for i := 0; i < 10; i++ { - a.Push(int2Value(i + 1)) - } - checkZeroExp(t, &a, 10) - checkSizeExp(t, &a, 10, 16) - checkSizeExp(t, a.Resize(5, 0), 5, 16) - checkSizeExp(t, a.Resize(10, 0), 10, 16) - checkZeroExp(t, &a, 5) -} - - -func TestAccessExp(t *testing.T) { - const n = 100 - var a Vector - a.Resize(n, 0) - for i := 0; i < n; i++ { - a.Set(i, int2Value(valExp(i))) - } - for i := 0; i < n; i++ { - if elem2Value(a.At(i)) != int2Value(valExp(i)) { - t.Error(i) - } - } - var b Vector - b.Resize(n, 0) - for i := 0; i < n; i++ { - b[i] = int2Value(valExp(i)) - } - for i := 0; i < n; i++ { - if elem2Value(b[i]) != int2Value(valExp(i)) { - t.Error(i) - } - } -} - - -func TestInsertDeleteClearExp(t *testing.T) { - const n = 100 - var a Vector - - for i := 0; i < n; i++ { - if a.Len() != i { - t.Errorf("T%: A) wrong Len() %d (expected %d)", a, a.Len(), i) - } - if len(a) != i { - t.Errorf("T%: A) wrong len() %d (expected %d)", a, len(a), i) - } - a.Insert(0, int2Value(valExp(i))) - if elem2Value(a.Last()) != int2Value(valExp(0)) { - t.Error("T%: B", a) - } - } - for i := n - 1; i >= 0; i-- { - if elem2Value(a.Last()) != int2Value(valExp(0)) { - t.Error("T%: C", a) - } - if elem2Value(a.At(0)) != int2Value(valExp(i)) { - t.Error("T%: D", a) - } - if elem2Value(a[0]) != int2Value(valExp(i)) { - t.Error("T%: D2", a) - } - a.Delete(0) - if a.Len() != i { - t.Errorf("T%: E) wrong Len() %d (expected %d)", a, a.Len(), i) - } - if len(a) != i { - t.Errorf("T%: E) wrong len() %d (expected %d)", a, len(a), i) - } - } - - if a.Len() != 0 { - t.Errorf("T%: F) wrong Len() %d (expected 0)", a, a.Len()) - } - if len(a) != 0 { - t.Errorf("T%: F) wrong len() %d (expected 0)", a, len(a)) - } - for i := 0; i < n; i++ { - a.Push(int2Value(valExp(i))) - if a.Len() != i+1 { - t.Errorf("T%: G) wrong Len() %d (expected %d)", a, a.Len(), i+1) - } - if len(a) != i+1 { - t.Errorf("T%: G) wrong len() %d (expected %d)", a, len(a), i+1) - } - if elem2Value(a.Last()) != int2Value(valExp(i)) { - t.Error("T%: H", a) - } - } - a.Resize(0, 0) - if a.Len() != 0 { - t.Errorf("T%: I wrong Len() %d (expected 0)", a, a.Len()) - } - if len(a) != 0 { - t.Errorf("T%: I wrong len() %d (expected 0)", a, len(a)) - } - - const m = 5 - for j := 0; j < m; j++ { - a.Push(int2Value(j)) - for i := 0; i < n; i++ { - x := valExp(i) - a.Push(int2Value(x)) - if elem2Value(a.Pop()) != int2Value(x) { - t.Error("T%: J", a) - } - if a.Len() != j+1 { - t.Errorf("T%: K) wrong Len() %d (expected %d)", a, a.Len(), j+1) - } - if len(a) != j+1 { - t.Errorf("T%: K) wrong len() %d (expected %d)", a, len(a), j+1) - } - } - } - if a.Len() != m { - t.Errorf("T%: L) wrong Len() %d (expected %d)", a, a.Len(), m) - } - if len(a) != m { - t.Errorf("T%: L) wrong len() %d (expected %d)", a, len(a), m) - } -} - - -func verify_sliceExp(t *testing.T, x *Vector, elt, i, j int) { - for k := i; k < j; k++ { - if elem2Value(x.At(k)) != int2Value(elt) { - t.Errorf("T%: M) wrong [%d] element %v (expected %v)", x, k, elem2Value(x.At(k)), int2Value(elt)) - } - } - - s := x.Slice(i, j) - for k, n := 0, j-i; k < n; k++ { - if elem2Value(s.At(k)) != int2Value(elt) { - t.Errorf("T%: N) wrong [%d] element %v (expected %v)", x, k, elem2Value(x.At(k)), int2Value(elt)) - } - } -} - - -func verify_patternExp(t *testing.T, x *Vector, a, b, c int) { - n := a + b + c - if x.Len() != n { - t.Errorf("T%: O) wrong Len() %d (expected %d)", x, x.Len(), n) - } - if len(*x) != n { - t.Errorf("T%: O) wrong len() %d (expected %d)", x, len(*x), n) - } - verify_sliceExp(t, x, 0, 0, a) - verify_sliceExp(t, x, 1, a, a+b) - verify_sliceExp(t, x, 0, a+b, n) -} - - -func make_vectorExp(elt, len int) *Vector { - x := new(Vector).Resize(len, 0) - for i := 0; i < len; i++ { - x.Set(i, int2Value(elt)) - } - return x -} - - -func TestInsertVectorExp(t *testing.T) { - // 1 - a := make_vectorExp(0, 0) - b := make_vectorExp(1, 10) - a.InsertVector(0, b) - verify_patternExp(t, a, 0, 10, 0) - // 2 - a = make_vectorExp(0, 10) - b = make_vectorExp(1, 0) - a.InsertVector(5, b) - verify_patternExp(t, a, 5, 0, 5) - // 3 - a = make_vectorExp(0, 10) - b = make_vectorExp(1, 3) - a.InsertVector(3, b) - verify_patternExp(t, a, 3, 3, 7) - // 4 - a = make_vectorExp(0, 10) - b = make_vectorExp(1, 1000) - a.InsertVector(8, b) - verify_patternExp(t, a, 8, 1000, 2) -} - - -func TestDoExp(t *testing.T) { - const n = 25 - const salt = 17 - a := new(Vector).Resize(n, 0) - for i := 0; i < n; i++ { - a.Set(i, int2Value(salt*i)) - } - count := 0 - a.Do(func(e interface{}) { - i := intf2Value(e) - if i != int2Value(count*salt) { - t.Error(tname(a), "value at", count, "should be", count*salt, "not", i) - } - count++ - }) - if count != n { - t.Error(tname(a), "should visit", n, "values; did visit", count) - } - - b := new(Vector).Resize(n, 0) - for i := 0; i < n; i++ { - (*b)[i] = int2Value(salt * i) - } - count = 0 - b.Do(func(e interface{}) { - i := intf2Value(e) - if i != int2Value(count*salt) { - t.Error(tname(b), "b) value at", count, "should be", count*salt, "not", i) - } - count++ - }) - if count != n { - t.Error(tname(b), "b) should visit", n, "values; did visit", count) - } - - var c Vector - c.Resize(n, 0) - for i := 0; i < n; i++ { - c[i] = int2Value(salt * i) - } - count = 0 - c.Do(func(e interface{}) { - i := intf2Value(e) - if i != int2Value(count*salt) { - t.Error(tname(c), "c) value at", count, "should be", count*salt, "not", i) - } - count++ - }) - if count != n { - t.Error(tname(c), "c) should visit", n, "values; did visit", count) - } - -} - - -func TestIterExp(t *testing.T) { - const Len = 100 - x := new(Vector).Resize(Len, 0) - for i := 0; i < Len; i++ { - x.Set(i, int2Value(i*i)) - } - i := 0 - for v := range x.Iter() { - if elem2Value(v) != int2Value(i*i) { - t.Error(tname(x), "Iter expected", i*i, "got", elem2Value(v)) - } - i++ - } - if i != Len { - t.Error(tname(x), "Iter stopped at", i, "not", Len) - } - y := new(Vector).Resize(Len, 0) - for i := 0; i < Len; i++ { - (*y)[i] = int2Value(i * i) - } - i = 0 - for v := range y.Iter() { - if elem2Value(v) != int2Value(i*i) { - t.Error(tname(y), "y, Iter expected", i*i, "got", elem2Value(v)) - } - i++ - } - if i != Len { - t.Error(tname(y), "y, Iter stopped at", i, "not", Len) - } - var z Vector - z.Resize(Len, 0) - for i := 0; i < Len; i++ { - z[i] = int2Value(i * i) - } - i = 0 - for v := range z.Iter() { - if elem2Value(v) != int2Value(i*i) { - t.Error(tname(z), "z, Iter expected", i*i, "got", elem2Value(v)) - } - i++ - } - if i != Len { - t.Error(tname(z), "z, Iter stopped at", i, "not", Len) - } -} - -func TestVectorData(t *testing.T) { - // verify Data() returns a slice of a copy, not a slice of the original vector - const Len = 10 - var src Vector - for i := 0; i < Len; i++ { - src.Push(int2Value(i * i)) - } - dest := src.Data() - for i := 0; i < Len; i++ { - src[i] = int2Value(-1) - v := elem2Value(dest[i]) - if v != int2Value(i*i) { - t.Error(tname(src), "expected", i*i, "got", v) - } - } -} |