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{...@@ -44,6 +44,10 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type{
44 return l.toSliceConst()[n];44 return l.toSliceConst()[n];
45 }45 }
4646
47 pub fn count(self: &const Self) usize {
48 return self.len;
49 }
50
47 /// ArrayList takes ownership of the passed in slice. The slice must have been51 /// ArrayList takes ownership of the passed in slice. The slice must have been
48 /// allocated with `allocator`.52 /// allocated with `allocator`.
49 /// Deinitialize with `deinit` or use `toOwnedSlice`.53 /// Deinitialize with `deinit` or use `toOwnedSlice`.
...@@ -128,6 +132,27 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type{...@@ -128,6 +132,27 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type{
128 return null;132 return null;
129 return self.pop();133 return self.pop();
130 }134 }
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 }
131 };156 };
132}157}
133158
...@@ -157,6 +182,35 @@ test "basic ArrayList test" {...@@ -157,6 +182,35 @@ test "basic ArrayList test" {
157 assert(list.len == 9);182 assert(list.len == 9);
158}183}
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
160test "insert ArrayList test" {214test "insert ArrayList test" {
161 var list = ArrayList(i32).init(debug.global_allocator);215 var list = ArrayList(i32).init(debug.global_allocator);
162 defer list.deinit();216 defer list.deinit();
...@@ -174,4 +228,4 @@ test "insert ArrayList test" {...@@ -174,4 +228,4 @@ test "insert ArrayList test" {
174 const items = []const i32 { 1 };228 const items = []const i32 { 1 };
175 try list.insertSlice(0, items[0..0]);229 try list.insertSlice(0, items[0..0]);
176 assert(list.items[0] == 5);230 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 {...@@ -50,7 +50,7 @@ pub const BufMap = struct {
50 }50 }
5151
52 pub fn count(self: &const BufMap) usize {52 pub fn count(self: &const BufMap) usize {
53 return self.hash_map.size;53 return self.hash_map.count();
54 }54 }
5555
56 pub fn iterator(self: &const BufMap) BufMapHashMap.Iterator {56 pub fn iterator(self: &const BufMap) BufMapHashMap.Iterator {
...@@ -87,4 +87,4 @@ test "BufMap" {...@@ -87,4 +87,4 @@ test "BufMap" {
8787
88 bufmap.delete("x");88 bufmap.delete("x");
89 assert(0 == bufmap.count());89 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 {...@@ -38,7 +38,7 @@ pub const BufSet = struct {
38 }38 }
3939
40 pub fn count(self: &const BufSet) usize {40 pub fn count(self: &const BufSet) usize {
41 return self.hash_map.size;41 return self.hash_map.count();
42 }42 }
4343
44 pub fn iterator(self: &const BufSet) BufSetHashMap.Iterator {44 pub fn iterator(self: &const BufSet) BufSetHashMap.Iterator {
...@@ -59,4 +59,3 @@ pub const BufSet = struct {...@@ -59,4 +59,3 @@ pub const BufSet = struct {
59 return result;59 return result;
60 }60 }
61};61};
62
std/hash_map.zig+52-1
...@@ -54,6 +54,14 @@ pub fn HashMap(comptime K: type, comptime V: type,...@@ -54,6 +54,14 @@ pub fn HashMap(comptime K: type, comptime V: type,
54 }54 }
55 unreachable; // no next item55 unreachable; // no next item
56 }56 }
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 }
57 };65 };
5866
59 pub fn init(allocator: &Allocator) Self {67 pub fn init(allocator: &Allocator) Self {
...@@ -79,6 +87,10 @@ pub fn HashMap(comptime K: type, comptime V: type,...@@ -79,6 +87,10 @@ pub fn HashMap(comptime K: type, comptime V: type,
79 hm.incrementModificationCount();87 hm.incrementModificationCount();
80 }88 }
8189
90 pub fn count(hm: &const Self) usize {
91 return hm.size;
92 }
93
82 /// Returns the value that was already there.94 /// Returns the value that was already there.
83 pub fn put(hm: &Self, key: K, value: &const V) !?V {95 pub fn put(hm: &Self, key: K, value: &const V) !?V {
84 if (hm.entries.len == 0) {96 if (hm.entries.len == 0) {
...@@ -258,10 +270,49 @@ test "basic hash map usage" {...@@ -258,10 +270,49 @@ test "basic hash map usage" {
258 assert(map.get(2) == null);270 assert(map.get(2) == null);
259}271}
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
261fn hash_i32(x: i32) u32 {312fn hash_i32(x: i32) u32 {
262 return @bitCast(u32, x);313 return @bitCast(u32, x);
263}314}
264315
265fn eql_i32(a: i32, b: i32) bool {316fn eql_i32(a: i32, b: i32) bool {
266 return a == b;317 return a == b;
267}318}
\ No newline at end of file