LEFT | RIGHT |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 package vector | 5 package vector |
6 | 6 |
7 | 7 |
8 // StringVector is a container for string items. | 8 func (p *StringVector) realloc(length, capacity int) (b []string) { |
9 // The zero value for StringVector is an empty string vector ready to use. | 9 » if capacity < initialSize { |
10 type StringVector []string | 10 » » capacity = initialSize |
| 11 » } |
| 12 » b = make(StringVector, length, capacity) |
| 13 » copy(b, *p) |
| 14 » *p = b |
| 15 » return |
| 16 } |
11 | 17 |
12 | 18 |
13 // Insert n elements at position i. | 19 // Insert n elements at position i. |
14 func (p *StringVector) expand(i, n int) { | 20 func (p *StringVector) Expand(i, n int) { |
| 21 » a := *p |
| 22 |
15 // make sure we have enough space | 23 // make sure we have enough space |
16 » len0 := len(*p); | 24 » len0 := len(a) |
17 » len1 := len0 + n; | 25 » len1 := len0 + n |
18 » if len1 <= cap(*p) { | 26 » if len1 <= cap(a) { |
19 // enough space - just expand | 27 // enough space - just expand |
20 » » *p = (*p)[0:len1] | 28 » » a = a[0:len1] |
21 } else { | 29 } else { |
22 // not enough space - double capacity | 30 // not enough space - double capacity |
23 » » capb := cap(*p) * 2; | 31 » » capb := cap(a) * 2 |
24 if capb < len1 { | 32 if capb < len1 { |
25 // still not enough - use required length | 33 // still not enough - use required length |
26 capb = len1 | 34 capb = len1 |
27 } | 35 } |
28 // capb >= len1 | 36 // capb >= len1 |
29 » » a := make([]string, len1, max(bootstrap, capb)); | 37 » » a = p.realloc(len1, capb) |
30 » » copy(a, *p); | |
31 » » *p = a; | |
32 } | 38 } |
33 | 39 |
34 // make a hole | 40 // make a hole |
35 for j := len0 - 1; j >= i; j-- { | 41 for j := len0 - 1; j >= i; j-- { |
36 » » (*p)[j+n] = (*p)[j] | 42 » » a[j+n] = a[j] |
37 » } | 43 » } |
38 } | 44 |
| 45 » *p = a |
| 46 } |
| 47 |
| 48 |
| 49 // Insert n elements at the end of a vector. |
| 50 func (p *StringVector) Extend(n int) { p.Expand(len(*p), n) } |
39 | 51 |
40 | 52 |
41 // Resize changes the length and capacity of a vector. | 53 // Resize changes the length and capacity of a vector. |
42 // If the new length is shorter than the current length, Resize discards | 54 // If the new length is shorter than the current length, Resize discards |
43 // trailing elements. If the new length is longer than the current length, | 55 // trailing elements. If the new length is longer than the current length, |
44 // Resize adds "" elements. The capacity parameter is ignored unless the | 56 // Resize adds the respective zero values for the additional elements. The capac
ity |
45 // new length or capacity is longer that the current capacity. | 57 // parameter is ignored unless the new length or capacity is longer than the cur
rent |
| 58 // capacity. The resized vector's capacity may be larger than the requested capa
city. |
46 func (p *StringVector) Resize(length, capacity int) *StringVector { | 59 func (p *StringVector) Resize(length, capacity int) *StringVector { |
47 » if length > cap(*p) || capacity > cap(*p) { | 60 » a := *p |
| 61 |
| 62 » if length > cap(a) || capacity > cap(a) { |
48 // not enough space or larger capacity requested explicitly | 63 // not enough space or larger capacity requested explicitly |
49 » » a := make([]string, length, max(bootstrap, capacity)); | 64 » » a = p.realloc(length, capacity) |
50 » » copy(a, *p); | 65 » } else if length < len(a) { |
51 » » *p = a; | |
52 » } else if length < len(*p) { | |
53 // clear trailing elements | 66 // clear trailing elements |
54 » » for i := range (*p)[length:] { | 67 » » for i := range a[length:] { |
55 » » » (*p)[length+i] = "" | 68 » » » var zero string |
| 69 » » » a[length+i] = zero |
56 } | 70 } |
57 } | 71 } |
58 » *p = (*p)[0:length]; | 72 |
59 » return p; | 73 » *p = a[0:length] |
| 74 » return p |
60 } | 75 } |
61 | 76 |
62 | 77 |
63 // Len returns the number of elements in the vector. | 78 // Len returns the number of elements in the vector. |
64 func (p *StringVector) Len() int» { return len(*p) } | 79 // Same as len(*p). |
| 80 func (p *StringVector) Len() int { return len(*p) } |
65 | 81 |
66 | 82 |
67 // Cap returns the capacity of the vector; that is, the | 83 // Cap returns the capacity of the vector; that is, the |
68 // maximum length the vector can grow without resizing. | 84 // maximum length the vector can grow without resizing. |
69 func (p *StringVector) Cap() int» { return cap(*p) } | 85 // Same as cap(*p). |
| 86 func (p *StringVector) Cap() int { return cap(*p) } |
70 | 87 |
71 | 88 |
72 // At returns the i'th element of the vector. | 89 // At returns the i'th element of the vector. |
73 func (p *StringVector) At(i int) string»{ return (*p)[i] } | 90 func (p *StringVector) At(i int) string { return (*p)[i] } |
74 | 91 |
75 | 92 |
76 // Set sets the i'th element of the vector to value x. | 93 // Set sets the i'th element of the vector to value x. |
77 func (p *StringVector) Set(i int, x string)» { (*p)[i] = x } | 94 func (p *StringVector) Set(i int, x string) { (*p)[i] = x } |
78 | 95 |
79 | 96 |
80 // Last returns the element in the vector of highest index. | 97 // Last returns the element in the vector of highest index. |
81 func (p *StringVector) Last() string» { return (*p)[len(*p)-1] } | 98 func (p *StringVector) Last() string { return (*p)[len(*p)-1] } |
82 | 99 |
83 | 100 |
84 // Data returns all the elements as a slice. | 101 // Data returns all the elements as a slice. |
85 func (p *StringVector) Data() []string { | 102 func (p *StringVector) Data() []string { |
86 » arr := make([]string, len(*p)); | 103 » arr := make(StringVector, len(*p)) |
87 » copy(arr, *p); | 104 » copy(arr, *p) |
88 » return arr; | 105 » return arr |
89 } | 106 } |
90 | 107 |
91 | 108 |
92 // Insert inserts into the vector an element of value x before | 109 // Insert inserts into the vector an element of value x before |
93 // the current element at index i. | 110 // the current element at index i. |
94 func (p *StringVector) Insert(i int, x string) { | 111 func (p *StringVector) Insert(i int, x string) { |
95 » p.expand(i, 1); | 112 » p.Expand(i, 1) |
96 » (*p)[i] = x; | 113 » (*p)[i] = x |
97 } | 114 } |
98 | 115 |
99 | 116 |
100 // Delete deletes the i'th element of the vector. The gap is closed so the old | 117 // Delete deletes the i'th element of the vector. The gap is closed so the old |
101 // element at index i+1 has index i afterwards. | 118 // element at index i+1 has index i afterwards. |
102 func (p *StringVector) Delete(i int) { | 119 func (p *StringVector) Delete(i int) { |
103 » n := len(*p); | 120 » a := *p |
104 | 121 » n := len(a) |
105 » copy((*p)[i:n-1], (*p)[i+1:n]); | 122 |
106 » *p = (*p)[0 : n-1]; | 123 » copy(a[i:n-1], a[i+1:n]) |
107 } | 124 » var zero string |
108 | 125 » a[n-1] = zero // support GC, zero out entry |
109 | 126 » *p = a[0 : n-1] |
110 // InsertVector inserts into the vector the contents of the Vector | 127 } |
| 128 |
| 129 |
| 130 // InsertVector inserts into the vector the contents of the vector |
111 // x such that the 0th element of x appears at index i after insertion. | 131 // x such that the 0th element of x appears at index i after insertion. |
112 func (p *StringVector) InsertVector(i int, x *StringVector) { | 132 func (p *StringVector) InsertVector(i int, x *StringVector) { |
113 » p.expand(i, len(*x)); | 133 » b := *x |
114 » copy((*p)[i:i+len(*x)], *x); | 134 |
| 135 » p.Expand(i, len(b)) |
| 136 » copy((*p)[i:i+len(b)], b) |
115 } | 137 } |
116 | 138 |
117 | 139 |
118 // Cut deletes elements i through j-1, inclusive. | 140 // Cut deletes elements i through j-1, inclusive. |
119 func (p *StringVector) Cut(i, j int) { | 141 func (p *StringVector) Cut(i, j int) { |
120 » n := len(*p); | 142 » a := *p |
121 » m := n - (j - i); | 143 » n := len(a) |
122 | 144 » m := n - (j - i) |
123 » copy((*p)[i:m], (*p)[j:n]); | 145 |
124 | 146 » copy(a[i:m], a[j:n]) |
125 » *p = (*p)[0:m]; | 147 » for k := m; k < n; k++ { //TODO(bflm) don't zero out the elements unless
it's a Vector. |
126 } | 148 » » var zero string |
127 | 149 » » a[k] = zero // support GC, zero out entries |
128 | 150 » } |
129 // Slice returns a new StringVector by slicing the old one to extract slice [i:j
]. | 151 |
| 152 » *p = a[0:m] |
| 153 } |
| 154 |
| 155 |
| 156 // Slice returns a new sub-vector by slicing the old one to extract slice [i:j]. |
130 // The elements are copied. The original vector is unchanged. | 157 // The elements are copied. The original vector is unchanged. |
131 func (p *StringVector) Slice(i, j int) *StringVector { | 158 func (p *StringVector) Slice(i, j int) *StringVector { |
132 » s := make([]string, j-i);» // will fail in Init() if j < i | 159 » var s StringVector |
133 » copy(s, (*p)[i:j]); | 160 » s.realloc(j-i, 0) // will fail in Init() if j < i |
134 » return &s; | 161 » copy(s, (*p)[i:j]) |
135 } | 162 » return &s |
136 | 163 } |
137 | 164 |
138 // Do calls function f for each element of the vector, in order. | 165 |
139 // The function should not change the indexing of the vector underfoot. | 166 // Convenience wrappers |
140 func (p *StringVector) Do(f func(elem interface{})) { | |
141 » for i := 0; i < len(*p); i++ { | |
142 » » f((*p)[i])» // not too safe if f changes the Vector | |
143 » } | |
144 } | |
145 | |
146 | 167 |
147 // Push appends x to the end of the vector. | 168 // Push appends x to the end of the vector. |
148 func (p *StringVector) Push(x string)» { p.Insert(len(*p), x) } | 169 func (p *StringVector) Push(x string) { p.Insert(len(*p), x) } |
149 | 170 |
150 | 171 |
151 // Pop deletes and returns the last element of the vector. | 172 // Pop deletes the last element of the vector. |
152 func (p *StringVector) Pop() string { | 173 func (p *StringVector) Pop() string { |
153 » i := len(*p) - 1; | 174 » a := *p |
154 » x := (*p)[i]; | 175 |
155 » *p = (*p)[0:i]; | 176 » i := len(a) - 1 |
156 » return x; | 177 » x := a[i] |
157 } | 178 » var zero string |
158 | 179 » a[i] = zero // support GC, zero out entry |
159 | 180 » *p = a[0:i] |
160 // AppendVector appends the entire StringVector x to the end of this vector. | 181 » return x |
| 182 } |
| 183 |
| 184 |
| 185 // AppendVector appends the entire vector x to the end of this vector. |
161 func (p *StringVector) AppendVector(x *StringVector) { | 186 func (p *StringVector) AppendVector(x *StringVector) { |
162 p.InsertVector(len(*p), x) | 187 p.InsertVector(len(*p), x) |
163 } | 188 } |
164 | 189 |
165 | 190 |
166 // sort.Interface support | |
167 // Less returns a boolean denoting whether the i'th element is less than the j't
h element. | |
168 func (p *StringVector) Less(i, j int) bool { return (*p)[i] < (*p)[j] } | |
169 | |
170 | |
171 // Swap exchanges the elements at indexes i and j. | 191 // Swap exchanges the elements at indexes i and j. |
172 func (p *StringVector) Swap(i, j int)» { (*p)[i], (*p)[j] = (*p)[j], (*p)[i] } | 192 func (p *StringVector) Swap(i, j int) { |
| 193 » a := *p |
| 194 » a[i], a[j] = a[j], a[i] |
| 195 } |
173 | 196 |
174 | 197 |
175 // Iterate over all elements; driver for range | 198 // Iterate over all elements; driver for range |
176 func (p *StringVector) iterate(c chan<- string) { | 199 func (p *StringVector) iterate(c chan<- string) { |
177 for _, v := range *p { | 200 for _, v := range *p { |
178 c <- v | 201 c <- v |
179 } | 202 } |
180 » close(c); | 203 » close(c) |
181 } | 204 } |
182 | 205 |
183 | 206 |
184 // Channel iterator for range. | 207 // Channel iterator for range. |
185 func (p *StringVector) Iter() <-chan string { | 208 func (p *StringVector) Iter() <-chan string { |
186 » c := make(chan string); | 209 » c := make(chan string) |
187 » go p.iterate(c); | 210 » go p.iterate(c) |
188 » return c; | 211 » return c |
189 } | 212 } |
LEFT | RIGHT |