remove the extra heap allocation
This commit is contained in:
+38
-33
@@ -12,6 +12,13 @@ pub const Point = struct {
|
||||
pub fn index(self: *const Point, width: usize) usize {
|
||||
return (self.y * width) + self.x;
|
||||
}
|
||||
|
||||
pub fn bottom_right(self: *const Point, area: Rect) Point {
|
||||
return .{
|
||||
.x = self.x + area.width,
|
||||
.y = self.y + area.height,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/// Rect is a rectangle
|
||||
@@ -69,8 +76,8 @@ pub fn Matrix(comptime T: type) type {
|
||||
}
|
||||
|
||||
/// submatrix returns a [SubMatrix]
|
||||
pub fn submatrix(self: *@This(), gpa: Allocator, loc: Point, area: Rect) !SubMatrix(T) {
|
||||
return SubMatrix(T).init(gpa, self, loc, area);
|
||||
pub fn submatrix(self: *@This(), loc: Point, area: Rect) SubMatrix(T) {
|
||||
return SubMatrix(T).init(self, loc, area);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -135,37 +142,35 @@ test "TestRowIterator" {
|
||||
pub fn SubMatrix(comptime T: type) type {
|
||||
return struct {
|
||||
// Data is made up of different sections of the
|
||||
_data: [][]T,
|
||||
_m: *Matrix(T),
|
||||
// the width of the submatrix
|
||||
_width: usize,
|
||||
// _index defines where we are in the byte slice
|
||||
_index: usize,
|
||||
// Where we stop iterating
|
||||
_endingIndex: usize,
|
||||
|
||||
/// init takes the underlying data from the upstream matrix and creates
|
||||
/// a submatrix of it
|
||||
pub fn init(gpa: Allocator, m: *Matrix(T), loc: Point, size: Rect) !@This() {
|
||||
var subData = try gpa.alloc([]T, size.height);
|
||||
var index = loc.index(m.size.width);
|
||||
pub fn init(m: *Matrix(T), loc: Point, size: Rect) @This() {
|
||||
return .{ ._m = m, ._index = loc.index(m.size.width), ._endingIndex = loc.bottom_right(size).index(m.size.width), ._width = size.width };
|
||||
}
|
||||
|
||||
for (0..size.height) |x| {
|
||||
const ending_index = index + size.width;
|
||||
subData[x] = m.data[index..ending_index];
|
||||
index += m.size.width;
|
||||
// jump moves the pointer forward
|
||||
pub fn skip(self: *@This(), rows: usize) void {
|
||||
self._index += self._m.size.width * rows;
|
||||
}
|
||||
|
||||
pub fn next(self: *@This()) ?[]T {
|
||||
if (self._endingIndex <= self._index) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return .{
|
||||
._data = subData,
|
||||
};
|
||||
}
|
||||
defer {
|
||||
self._index += self._m.size.width;
|
||||
}
|
||||
|
||||
pub fn deinit(self: *@This(), gpa: Allocator) void {
|
||||
gpa.free(self._data);
|
||||
}
|
||||
|
||||
/// get returns the type in the specified point
|
||||
pub fn get(self: *const @This(), loc: Point) T {
|
||||
return self._data[loc.y][loc.x];
|
||||
}
|
||||
|
||||
/// set sets the value of the specified point
|
||||
pub fn set(self: *@This(), loc: Point, val: T) void {
|
||||
self._data[loc.y][loc.x] = val;
|
||||
return self._m.data[self._index .. self._index + self._width];
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -174,15 +179,15 @@ test "SubMatrix" {
|
||||
const testing = std.testing;
|
||||
|
||||
// create our matrix and submatrix
|
||||
var m = try Matrix(u64).initZero(testing.allocator, .{ .height = 10, .width = 10 });
|
||||
var m = try Matrix(u8).initZero(testing.allocator, .{ .height = 10, .width = 10 });
|
||||
defer m.deinit(testing.allocator);
|
||||
var sub = try m.submatrix(testing.allocator, .{ .x = 4, .y = 4 }, .{ .height = 5, .width = 5 });
|
||||
defer sub.deinit(testing.allocator);
|
||||
var sub = m.submatrix(.{ .x = 4, .y = 4 }, .{ .height = 5, .width = 5 });
|
||||
|
||||
// set the value
|
||||
sub.set(.{ .x = 0, .y = 0 }, 100);
|
||||
if (sub.next()) |row| {
|
||||
row[0] = 'a';
|
||||
}
|
||||
|
||||
// it should be set in both locations
|
||||
try testing.expectEqual(100, sub.get(.{ .x = 0, .y = 0 }));
|
||||
try testing.expectEqual(100, m.get(.{ .x = 4, .y = 4 }));
|
||||
// we should see the value updated in the Matrix
|
||||
try testing.expectEqual('a', m.get(.{ .x = 4, .y = 4 }));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user