Merge pull request #981 from BraedonWooding/ArrayIteratorUnifiedSyntax

ArrayList iterator, unifying API of HashMap and its derivatives
This commit is contained in:
Andrew Kelley 2018-05-03 23:15:17 -04:00 committed by GitHub
commit 33fa87a9d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 110 additions and 6 deletions

View File

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

View File

@ -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());
}
}

View File

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

View File

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