authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-05-03 23:15:17-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2018-05-03 23:15:17-04:00
log33fa87a9d8ffb824a0c7d2434849ccfdf482ed83
treef6b98520630e28d19377b7b54024f5db3cd29d28
parentb9e320dd521751663db7b040e65c8ff5420c824a
parente907c5cab971428607f85b6df4b4f7dc555775d3
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #981 from BraedonWooding/ArrayIteratorUnifiedSyntax

ArrayList iterator, unifying API of HashMap and its derivatives

4 files changed, 110 insertions(+), 6 deletions(-)

std/array_list.zig+55-1
......@@ -44,6 +44,10 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type{
4444 return l.toSliceConst()[n];
4545 }
4646
47 pub fn count(self: &const Self) usize {
48 return self.len;
49 }
50
4751 /// ArrayList takes ownership of the passed in slice. The slice must have been
4852 /// allocated with `allocator`.
4953 /// Deinitialize with `deinit` or use `toOwnedSlice`.
......@@ -128,6 +132,27 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type{
128132 return null;
129133 return self.pop();
130134 }
135
136 pub const Iterator = struct {
137 list: &const Self,
138 // how many items have we returned
139 count: usize,
140
141 pub fn next(it: &Iterator) ?T {
142 if (it.count >= it.list.len) return null;
143 const val = it.list.at(it.count);
144 it.count += 1;
145 return val;
146 }
147
148 pub fn reset(it: &Iterator) void {
149 it.count = 0;
150 }
151 };
152
153 pub fn iterator(self: &Self) Iterator {
154 return Iterator { .list = self, .count = 0 };
155 }
131156 };
132157}
133158
......@@ -157,6 +182,35 @@ test "basic ArrayList test" {
157182 assert(list.len == 9);
158183}
159184
185test "iterator ArrayList test" {
186 var list = ArrayList(i32).init(debug.global_allocator);
187 defer list.deinit();
188
189 try list.append(1);
190 try list.append(2);
191 try list.append(3);
192
193 var count : i32 = 0;
194 var it = list.iterator();
195 while (it.next()) |next| {
196 assert(next == count + 1);
197 count += 1;
198 }
199
200 assert(count == 3);
201 assert(it.next() == null);
202 it.reset();
203 count = 0;
204 while (it.next()) |next| {
205 assert(next == count + 1);
206 count += 1;
207 if (count == 2) break;
208 }
209
210 it.reset();
211 assert(?? it.next() == 1);
212}
213
160214test "insert ArrayList test" {
161215 var list = ArrayList(i32).init(debug.global_allocator);
162216 defer list.deinit();
......@@ -174,4 +228,4 @@ test "insert ArrayList test" {
174228 const items = []const i32 { 1 };
175229 try list.insertSlice(0, items[0..0]);
176230 assert(list.items[0] == 5);
177}
231}
\ No newline at end of file
std/buf_map.zig+2-2
......@@ -50,7 +50,7 @@ pub const BufMap = struct {
5050 }
5151
5252 pub fn count(self: &const BufMap) usize {
53 return self.hash_map.size;
53 return self.hash_map.count();
5454 }
5555
5656 pub fn iterator(self: &const BufMap) BufMapHashMap.Iterator {
......@@ -87,4 +87,4 @@ test "BufMap" {
8787
8888 bufmap.delete("x");
8989 assert(0 == bufmap.count());
90}
90}
\ No newline at end of file
std/buf_set.zig+1-2
......@@ -38,7 +38,7 @@ pub const BufSet = struct {
3838 }
3939
4040 pub fn count(self: &const BufSet) usize {
41 return self.hash_map.size;
41 return self.hash_map.count();
4242 }
4343
4444 pub fn iterator(self: &const BufSet) BufSetHashMap.Iterator {
......@@ -59,4 +59,3 @@ pub const BufSet = struct {
5959 return result;
6060 }
6161};
62
std/hash_map.zig+52-1
......@@ -54,6 +54,14 @@ pub fn HashMap(comptime K: type, comptime V: type,
5454 }
5555 unreachable; // no next item
5656 }
57
58 // Reset the iterator to the initial index
59 pub fn reset(it: &Iterator) void {
60 it.count = 0;
61 it.index = 0;
62 // Resetting the modification count too
63 it.initial_modification_count = it.hm.modification_count;
64 }
5765 };
5866
5967 pub fn init(allocator: &Allocator) Self {
......@@ -79,6 +87,10 @@ pub fn HashMap(comptime K: type, comptime V: type,
7987 hm.incrementModificationCount();
8088 }
8189
90 pub fn count(hm: &const Self) usize {
91 return hm.size;
92 }
93
8294 /// Returns the value that was already there.
8395 pub fn put(hm: &Self, key: K, value: &const V) !?V {
8496 if (hm.entries.len == 0) {
......@@ -258,10 +270,49 @@ test "basic hash map usage" {
258270 assert(map.get(2) == null);
259271}
260272
273test "iterator hash map" {
274 var direct_allocator = std.heap.DirectAllocator.init();
275 defer direct_allocator.deinit();
276
277 var reset_map = HashMap(i32, i32, hash_i32, eql_i32).init(&direct_allocator.allocator);
278 defer reset_map.deinit();
279
280 assert((reset_map.put(1, 11) catch unreachable) == null);
281 assert((reset_map.put(2, 22) catch unreachable) == null);
282 assert((reset_map.put(3, 33) catch unreachable) == null);
283
284 var keys = []i32 { 1, 2, 3 };
285 var values = []i32 { 11, 22, 33 };
286
287 var it = reset_map.iterator();
288 var count : usize = 0;
289 while (it.next()) |next| {
290 assert(next.key == keys[count]);
291 assert(next.value == values[count]);
292 count += 1;
293 }
294
295 assert(count == 3);
296 assert(it.next() == null);
297 it.reset();
298 count = 0;
299 while (it.next()) |next| {
300 assert(next.key == keys[count]);
301 assert(next.value == values[count]);
302 count += 1;
303 if (count == 2) break;
304 }
305
306 it.reset();
307 var entry = ?? it.next();
308 assert(entry.key == keys[0]);
309 assert(entry.value == values[0]);
310}
311
261312fn hash_i32(x: i32) u32 {
262313 return @bitCast(u32, x);
263314}
264315
265316fn eql_i32(a: i32, b: i32) bool {
266317 return a == b;
267}
318}
\ No newline at end of file