Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 55 additions & 1 deletion std/array_list.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand Down Expand Up @@ -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);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andrewrk Currently this seems like the best way to do it? Though I think I could also just index the .items property since I do check bounds.

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 };
}
};
}

Expand Down Expand Up @@ -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();
Expand All @@ -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);
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The newlines were removed from the end of all the files you modified.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't remember having them be part of a standard, if they are I'll add them back; just my visual studio code having its own mind :).

4 changes: 2 additions & 2 deletions std/buf_map.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -87,4 +87,4 @@ test "BufMap" {

bufmap.delete("x");
assert(0 == bufmap.count());
}
}
3 changes: 1 addition & 2 deletions std/buf_set.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -59,4 +59,3 @@ pub const BufSet = struct {
return result;
}
};

53 changes: 52 additions & 1 deletion std/hash_map.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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) {
Expand Down Expand Up @@ -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;
}
}