Commit e907c5cab9

Braedon <braedonww@gmail.com>
2018-05-03 15:54:33
Unified API
1 parent 0bb054e
std/array_list.zig
@@ -44,6 +44,10 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type{
             return l.toSliceConst()[n];
         }
 
+        pub fn count(self: &const Self) usize {
+            return self.len;
+        }
+
         /// ArrayList takes ownership of the passed in slice. The slice must have been
         /// allocated with `allocator`.
         /// Deinitialize with `deinit` or use `toOwnedSlice`.
@@ -128,6 +132,27 @@ pub fn AlignedArrayList(comptime T: type, comptime A: u29) type{
                 return null;
             return self.pop();
         }
+
+        pub const Iterator = struct {
+            list: &const Self,
+            // how many items have we returned
+            count: usize,
+
+            pub fn next(it: &Iterator) ?T {
+                if (it.count >= it.list.len) return null;
+                const val = it.list.at(it.count);
+                it.count += 1;
+                return val;
+            }
+
+            pub fn reset(it: &Iterator) void {
+                it.count = 0;
+            }
+        };
+
+        pub fn iterator(self: &Self) Iterator {
+            return Iterator { .list = self, .count = 0 };
+        }
     };
 }
 
@@ -157,6 +182,35 @@ test "basic ArrayList test" {
     assert(list.len == 9);
 }
 
+test "iterator ArrayList test" {
+    var list = ArrayList(i32).init(debug.global_allocator);
+    defer list.deinit();
+
+    try list.append(1);
+    try list.append(2);
+    try list.append(3);
+
+    var count : i32 = 0;
+    var it = list.iterator();
+    while (it.next()) |next| {
+        assert(next == count + 1);
+        count += 1;
+    }
+
+    assert(count == 3);
+    assert(it.next() == null);
+    it.reset();
+    count = 0;
+    while (it.next()) |next| {
+        assert(next == count + 1);
+        count += 1;
+        if (count == 2) break;
+    }
+
+    it.reset();
+    assert(?? it.next() == 1);
+}
+
 test "insert ArrayList test" {
     var list = ArrayList(i32).init(debug.global_allocator);
     defer list.deinit();
@@ -174,4 +228,4 @@ test "insert ArrayList test" {
     const items = []const i32 { 1 };
     try list.insertSlice(0, items[0..0]);
     assert(list.items[0] == 5);
-}
+}
\ No newline at end of file
std/buf_map.zig
@@ -50,7 +50,7 @@ pub const BufMap = struct {
     }
 
     pub fn count(self: &const BufMap) usize {
-        return self.hash_map.size;
+        return self.hash_map.count();
     }
 
     pub fn iterator(self: &const BufMap) BufMapHashMap.Iterator {
@@ -87,4 +87,4 @@ test "BufMap" {
 
     bufmap.delete("x");
     assert(0 == bufmap.count());
-}
+}
\ No newline at end of file
std/buf_set.zig
@@ -38,7 +38,7 @@ pub const BufSet = struct {
     }
 
     pub fn count(self: &const BufSet) usize {
-        return self.hash_map.size;
+        return self.hash_map.count();
     }
 
     pub fn iterator(self: &const BufSet) BufSetHashMap.Iterator {
@@ -59,4 +59,3 @@ pub const BufSet = struct {
         return result;
     }
 };
-
std/hash_map.zig
@@ -54,6 +54,14 @@ pub fn HashMap(comptime K: type, comptime V: type,
                 }
                 unreachable; // no next item
             }
+
+            // Reset the iterator to the initial index
+            pub fn reset(it: &Iterator) void {
+                it.count = 0;
+                it.index = 0;
+                // Resetting the modification count too
+                it.initial_modification_count = it.hm.modification_count;
+            }
         };
 
         pub fn init(allocator: &Allocator) Self {
@@ -79,6 +87,10 @@ pub fn HashMap(comptime K: type, comptime V: type,
             hm.incrementModificationCount();
         }
 
+        pub fn count(hm: &const Self) usize {
+            return hm.size;
+        }
+
         /// Returns the value that was already there.
         pub fn put(hm: &Self, key: K, value: &const V) !?V {
             if (hm.entries.len == 0) {
@@ -258,10 +270,49 @@ test "basic hash map usage" {
     assert(map.get(2) == null);
 }
 
+test "iterator hash map" {
+    var direct_allocator = std.heap.DirectAllocator.init();
+    defer direct_allocator.deinit();
+    
+    var reset_map = HashMap(i32, i32, hash_i32, eql_i32).init(&direct_allocator.allocator);
+    defer reset_map.deinit();
+
+    assert((reset_map.put(1, 11) catch unreachable) == null);
+    assert((reset_map.put(2, 22) catch unreachable) == null);
+    assert((reset_map.put(3, 33) catch unreachable) == null);
+
+    var keys = []i32 { 1, 2, 3 };
+    var values = []i32 { 11, 22, 33 };
+
+    var it = reset_map.iterator();
+    var count : usize = 0;
+    while (it.next()) |next| {
+        assert(next.key == keys[count]);
+        assert(next.value == values[count]);
+        count += 1;
+    }
+
+    assert(count == 3);
+    assert(it.next() == null);
+    it.reset();
+    count = 0;
+    while (it.next()) |next| {
+        assert(next.key == keys[count]);
+        assert(next.value == values[count]);
+        count += 1;
+        if (count == 2) break;
+    }
+
+    it.reset();
+    var entry = ?? it.next();
+    assert(entry.key == keys[0]);
+    assert(entry.value == values[0]);
+}
+
 fn hash_i32(x: i32) u32 {
     return @bitCast(u32, x);
 }
 
 fn eql_i32(a: i32, b: i32) bool {
     return a == b;
-}
+}
\ No newline at end of file