| author | |
| committer | |
| log | 33fa87a9d8ffb824a0c7d2434849ccfdf482ed83 |
| tree | f6b98520630e28d19377b7b54024f5db3cd29d28 |
| parent | b9e320dd521751663db7b040e65c8ff5420c824a |
| parent | e907c5cab971428607f85b6df4b4f7dc555775d3 |
| signature |
ArrayList iterator, unifying API of HashMap and its derivatives4 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 | } |
| 46 | 46 | ||
| 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 been | 51 | /// 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 | } |
| 133 | 158 | ||
| ... | @@ -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 | } |
| 159 | 184 | ||
| 185 | test "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 | |||
| 160 | test "insert ArrayList test" { | 214 | test "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 | } |
| 51 | 51 | ||
| 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 | } |
| 55 | 55 | ||
| 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" { |
| 87 | 87 | ||
| 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 | } |
| 39 | 39 | ||
| 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 | } |
| 43 | 43 | ||
| 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 item | 55 | 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 | }; |
| 58 | 66 | ||
| 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 | } |
| 81 | 89 | ||
| 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 | } |
| 260 | 272 | ||
| 273 | test "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 | |||
| 261 | fn hash_i32(x: i32) u32 { | 312 | fn hash_i32(x: i32) u32 { |
| 262 | return @bitCast(u32, x); | 313 | return @bitCast(u32, x); |
| 263 | } | 314 | } |
| 264 | 315 | ||
| 265 | fn eql_i32(a: i32, b: i32) bool { | 316 | fn eql_i32(a: i32, b: i32) bool { |
| 266 | return a == b; | 317 | return a == b; |
| 267 | } | 318 | } |
| \ No newline at end of file | |||