Fixed a misunderstanding about allocations (I did too much go and nim!)
This commit is contained in:
parent
644e626399
commit
582bfc893c
4 changed files with 106 additions and 58 deletions
120
src/field.zig
120
src/field.zig
|
@ -1,6 +1,7 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
|
||||||
const Line = struct {
|
const Line = struct {
|
||||||
|
allocator: std.mem.Allocator,
|
||||||
x: i64 = 0,
|
x: i64 = 0,
|
||||||
data: std.ArrayList(i64),
|
data: std.ArrayList(i64),
|
||||||
fn blank(l: *Line, x: i64) void {
|
fn blank(l: *Line, x: i64) void {
|
||||||
|
@ -24,7 +25,7 @@ const Line = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
test "blank" {
|
test "blank" {
|
||||||
var l = Line.init(std.testing.allocator);
|
var l = try Line.init(std.testing.allocator);
|
||||||
defer l.deinit();
|
defer l.deinit();
|
||||||
const initial = [_]i64{ 'b', 'a', '@', 'c', 'd', 'e', 'f' };
|
const initial = [_]i64{ 'b', 'a', '@', 'c', 'd', 'e', 'f' };
|
||||||
try l.data.appendSlice(initial[0..]);
|
try l.data.appendSlice(initial[0..]);
|
||||||
|
@ -62,16 +63,17 @@ const Line = struct {
|
||||||
}
|
}
|
||||||
fn deinit(self: *Line) void {
|
fn deinit(self: *Line) void {
|
||||||
self.data.deinit();
|
self.data.deinit();
|
||||||
|
self.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
fn get(l: *Line, x: i64) i64 {
|
fn get(l: *Line, x: i64) i64 {
|
||||||
if (x >= l.x and x < l.x + @intCast(i64, l.len())) return l.data.items[@intCast(usize, x - @intCast(i64, l.x))];
|
if (x >= l.x and x < l.x + @intCast(i64, l.len())) return l.data.items[@intCast(usize, x - @intCast(i64, l.x))];
|
||||||
return ' ';
|
return ' ';
|
||||||
}
|
}
|
||||||
fn init(allocator: std.mem.Allocator) Line {
|
fn init(allocator: std.mem.Allocator) !*Line {
|
||||||
const c = std.ArrayList(i64).init(allocator);
|
var l = try allocator.create(Line);
|
||||||
return Line{
|
l.allocator = allocator;
|
||||||
.data = c,
|
l.data = std.ArrayList(i64).init(allocator);
|
||||||
};
|
return l;
|
||||||
}
|
}
|
||||||
inline fn len(l: Line) usize {
|
inline fn len(l: Line) usize {
|
||||||
return l.data.items.len;
|
return l.data.items.len;
|
||||||
|
@ -107,7 +109,7 @@ const Line = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
test "set" {
|
test "set" {
|
||||||
var l = Line.init(std.testing.allocator);
|
var l = try Line.init(std.testing.allocator);
|
||||||
defer l.deinit();
|
defer l.deinit();
|
||||||
try l.set(-1, '@');
|
try l.set(-1, '@');
|
||||||
const zero = [_]i64{'@'};
|
const zero = [_]i64{'@'};
|
||||||
|
@ -141,22 +143,22 @@ const Line = struct {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const Field = struct {
|
pub const Field = struct {
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
x: i64 = 0,
|
x: i64 = 0,
|
||||||
y: i64 = 0,
|
y: i64 = 0,
|
||||||
lines: std.ArrayList(Line),
|
lines: std.ArrayList(*Line),
|
||||||
lx: usize = 0,
|
lx: usize = 0,
|
||||||
pub fn blank(f: *Field, x: i64, y: i64) !void {
|
pub fn blank(f: *Field, x: i64, y: i64) void {
|
||||||
const ly = @intCast(i64, f.lines.items.len);
|
const ly = @intCast(i64, f.lines.items.len);
|
||||||
if (ly == 0) return error.EmptyFieldError;
|
if (ly == 0) return;
|
||||||
if (y < f.y or y >= f.y + ly) return; // outside the field
|
if (y < f.y or y >= f.y + ly) return; // outside the field
|
||||||
var l = &f.lines.items[@intCast(usize, y - f.y)];
|
var l = f.lines.items[@intCast(usize, y - f.y)];
|
||||||
if (l.len() == 0) return; // the line is already empty
|
if (l.len() == 0) return; // the line is already empty
|
||||||
l.blank(x);
|
l.blank(x);
|
||||||
if (l.len() == 0) {
|
if (l.len() == 0) {
|
||||||
if (ly == 1) {
|
if (ly == 1) {
|
||||||
return error.EmptyFieldError;
|
return;
|
||||||
} else if (y == f.y) { // we need to remove leading lines
|
} else if (y == f.y) { // we need to remove leading lines
|
||||||
l.deinit();
|
l.deinit();
|
||||||
var i: usize = 1;
|
var i: usize = 1;
|
||||||
|
@ -164,7 +166,7 @@ const Field = struct {
|
||||||
f.lines.items[i].deinit();
|
f.lines.items[i].deinit();
|
||||||
}
|
}
|
||||||
f.y += @intCast(i64, i);
|
f.y += @intCast(i64, i);
|
||||||
std.mem.copy(Line, f.lines.items[0 .. f.lines.items.len - i], f.lines.items[i..]);
|
std.mem.copy(*Line, f.lines.items[0 .. f.lines.items.len - i], f.lines.items[i..]);
|
||||||
f.lines.items.len -= i;
|
f.lines.items.len -= i;
|
||||||
} else if (y == f.y + ly - 1) { // we need to remove trailing lines
|
} else if (y == f.y + ly - 1) { // we need to remove trailing lines
|
||||||
l.deinit();
|
l.deinit();
|
||||||
|
@ -189,62 +191,63 @@ const Field = struct {
|
||||||
test "blank" {
|
test "blank" {
|
||||||
var f = try Field.init(std.testing.allocator);
|
var f = try Field.init(std.testing.allocator);
|
||||||
defer f.deinit();
|
defer f.deinit();
|
||||||
try std.testing.expectEqual(f.blank(1, 0), error.EmptyFieldError);
|
var moins2 = try Line.init(std.testing.allocator);
|
||||||
var moins2 = Line.init(std.testing.allocator);
|
|
||||||
try moins2.set(-3, 'a');
|
try moins2.set(-3, 'a');
|
||||||
var moins1 = Line.init(std.testing.allocator);
|
var moins1 = try Line.init(std.testing.allocator);
|
||||||
try moins1.set(6, 'b');
|
try moins1.set(6, 'b');
|
||||||
var zero = Line.init(std.testing.allocator);
|
var zero = try Line.init(std.testing.allocator);
|
||||||
try zero.set(-4, 'c');
|
try zero.set(-4, 'c');
|
||||||
var un = Line.init(std.testing.allocator);
|
var un = try Line.init(std.testing.allocator);
|
||||||
try un.set(-8, 'd');
|
try un.set(-8, 'd');
|
||||||
var deux = Line.init(std.testing.allocator);
|
var deux = try Line.init(std.testing.allocator);
|
||||||
try deux.set(12, 'e');
|
try deux.set(12, 'e');
|
||||||
const initial = [_]Line{ moins2, moins1, zero, un, deux };
|
const initial = [_]*Line{ moins2, moins1, zero, un, deux };
|
||||||
try f.lines.appendSlice(initial[0..]);
|
try f.lines.appendSlice(initial[0..]);
|
||||||
f.x = -8;
|
f.x = -8;
|
||||||
f.lx = 21;
|
f.lx = 21;
|
||||||
f.y = -2;
|
f.y = -2;
|
||||||
try f.blank(6, -1);
|
f.blank(6, -1);
|
||||||
try std.testing.expectEqual(f.x, -8);
|
try std.testing.expectEqual(f.x, -8);
|
||||||
try std.testing.expectEqual(f.lx, 21);
|
try std.testing.expectEqual(f.lx, 21);
|
||||||
try std.testing.expectEqual(f.y, -2);
|
try std.testing.expectEqual(f.y, -2);
|
||||||
try std.testing.expectEqual(f.lines.items.len, 5);
|
try std.testing.expectEqual(f.lines.items.len, 5);
|
||||||
try std.testing.expectEqual(f.lines.items[1].len(), 0);
|
try std.testing.expectEqual(f.lines.items[1].len(), 0);
|
||||||
try f.blank(-3, -2);
|
f.blank(-3, -2);
|
||||||
try std.testing.expectEqual(f.x, -8);
|
try std.testing.expectEqual(f.x, -8);
|
||||||
try std.testing.expectEqual(f.lx, 21);
|
try std.testing.expectEqual(f.lx, 21);
|
||||||
try std.testing.expectEqual(f.y, 0);
|
try std.testing.expectEqual(f.y, 0);
|
||||||
try std.testing.expectEqual(f.lines.items.len, 3);
|
try std.testing.expectEqual(f.lines.items.len, 3);
|
||||||
try f.blank(-8, 1);
|
f.blank(-8, 1);
|
||||||
try std.testing.expectEqual(f.x, -4);
|
try std.testing.expectEqual(f.x, -4);
|
||||||
try std.testing.expectEqual(f.lx, 17);
|
try std.testing.expectEqual(f.lx, 17);
|
||||||
try std.testing.expectEqual(f.y, 0);
|
try std.testing.expectEqual(f.y, 0);
|
||||||
try std.testing.expectEqual(f.lines.items.len, 3);
|
try std.testing.expectEqual(f.lines.items.len, 3);
|
||||||
try std.testing.expectEqual(f.lines.items[1].len(), 0);
|
try std.testing.expectEqual(f.lines.items[1].len(), 0);
|
||||||
try f.blank(12, 2);
|
f.blank(12, 2);
|
||||||
try std.testing.expectEqual(f.x, -4);
|
try std.testing.expectEqual(f.x, -4);
|
||||||
try std.testing.expectEqual(f.lx, 1);
|
try std.testing.expectEqual(f.lx, 1);
|
||||||
try std.testing.expectEqual(f.y, 0);
|
try std.testing.expectEqual(f.y, 0);
|
||||||
try std.testing.expectEqual(f.lines.items.len, 1);
|
try std.testing.expectEqual(f.lines.items.len, 1);
|
||||||
try std.testing.expectEqual(f.blank(-4, 0), error.EmptyFieldError);
|
|
||||||
}
|
}
|
||||||
pub fn deinit(self: *Field) void {
|
pub fn deinit(self: *Field) void {
|
||||||
for (self.lines.items) |*l| {
|
for (self.lines.items) |*l| {
|
||||||
l.deinit();
|
l.*.deinit();
|
||||||
}
|
}
|
||||||
self.lines.deinit();
|
self.lines.deinit();
|
||||||
|
self.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
pub fn get(f: *Field, x: i64, y: i64) i64 {
|
pub fn get(f: *Field, x: i64, y: i64) i64 {
|
||||||
if (y >= f.y and y < f.y + @intCast(i64, f.lines.items.len)) return f.lines.items[@intCast(usize, y - @intCast(i64, f.y))].get(x);
|
if (y >= f.y and y < f.y + @intCast(i64, f.lines.items.len)) return f.lines.items[@intCast(usize, y - @intCast(i64, f.y))].get(x);
|
||||||
return ' ';
|
return ' ';
|
||||||
}
|
}
|
||||||
pub fn init(allocator: std.mem.Allocator) !Field {
|
pub fn init(allocator: std.mem.Allocator) !*Field {
|
||||||
var lines = std.ArrayList(Line).init(allocator);
|
var f = try allocator.create(Field);
|
||||||
return Field{
|
f.allocator = allocator;
|
||||||
.allocator = allocator,
|
f.lines = std.ArrayList(*Line).init(allocator);
|
||||||
.lines = lines,
|
return f;
|
||||||
};
|
}
|
||||||
|
inline fn isIn(f: *Field, x: i64, y: i64) bool {
|
||||||
|
return x >= f.x and y >= f.y and x < f.x + @intCast(i64, f.lx) and y < f.y + @intCast(i64, f.lines.items.len);
|
||||||
}
|
}
|
||||||
pub fn load(f: *Field, reader: anytype) !void {
|
pub fn load(f: *Field, reader: anytype) !void {
|
||||||
if (f.lines.items.len > 0) return error.FIELD_NOT_EMPTY;
|
if (f.lines.items.len > 0) return error.FIELD_NOT_EMPTY;
|
||||||
|
@ -252,10 +255,10 @@ const Field = struct {
|
||||||
var x: i64 = 0;
|
var x: i64 = 0;
|
||||||
var y: i64 = 0;
|
var y: i64 = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
var i: usize = 0;
|
|
||||||
var buffer: [4096]u8 = undefined;
|
var buffer: [4096]u8 = undefined;
|
||||||
var l = try reader.read(buffer[0..]);
|
var l = try reader.read(buffer[0..]);
|
||||||
if (l == 0) return;
|
if (l == 0) return;
|
||||||
|
var i: usize = 0;
|
||||||
while (i < l) : (i += 1) {
|
while (i < l) : (i += 1) {
|
||||||
if (lastIsCR) {
|
if (lastIsCR) {
|
||||||
lastIsCR = false;
|
lastIsCR = false;
|
||||||
|
@ -303,6 +306,15 @@ const Field = struct {
|
||||||
try std.testing.expectEqual(f2.load(cr2), error.GOT_CR_WITHOUT_LF);
|
try std.testing.expectEqual(f2.load(cr2), error.GOT_CR_WITHOUT_LF);
|
||||||
}
|
}
|
||||||
pub fn set(f: *Field, x: i64, y: i64, v: i64) !void {
|
pub fn set(f: *Field, x: i64, y: i64, v: i64) !void {
|
||||||
|
if (f.lines.items.len == 0) {
|
||||||
|
f.x = x;
|
||||||
|
f.y = y;
|
||||||
|
var l = try f.lines.addOne();
|
||||||
|
l.* = try Line.init(f.allocator);
|
||||||
|
try l.*.set(x, v);
|
||||||
|
f.lx = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (v == ' ') return f.blank(x, y);
|
if (v == ' ') return f.blank(x, y);
|
||||||
if (y >= f.y) {
|
if (y >= f.y) {
|
||||||
if (y < f.y + @intCast(i64, f.lines.items.len)) { // the line exists
|
if (y < f.y + @intCast(i64, f.lines.items.len)) { // the line exists
|
||||||
|
@ -310,9 +322,9 @@ const Field = struct {
|
||||||
} else { // append lines
|
} else { // append lines
|
||||||
var i: usize = f.lines.items.len;
|
var i: usize = f.lines.items.len;
|
||||||
while (i < y - f.y) : (i += 1) {
|
while (i < y - f.y) : (i += 1) {
|
||||||
try f.lines.append(Line.init(f.allocator));
|
try f.lines.append(try Line.init(f.allocator));
|
||||||
}
|
}
|
||||||
var l = Line.init(f.allocator);
|
var l = try Line.init(f.allocator);
|
||||||
try l.set(x, v);
|
try l.set(x, v);
|
||||||
try f.lines.append(l);
|
try f.lines.append(l);
|
||||||
}
|
}
|
||||||
|
@ -320,13 +332,13 @@ const Field = struct {
|
||||||
const oldLen = f.lines.items.len;
|
const oldLen = f.lines.items.len;
|
||||||
f.lines.items.len += @intCast(usize, f.y - y);
|
f.lines.items.len += @intCast(usize, f.y - y);
|
||||||
try f.lines.ensureUnusedCapacity(f.lines.items.len);
|
try f.lines.ensureUnusedCapacity(f.lines.items.len);
|
||||||
std.mem.copyBackwards(Line, f.lines.items[@intCast(usize, f.y - y)..], f.lines.items[0..oldLen]);
|
std.mem.copyBackwards(*Line, f.lines.items[@intCast(usize, f.y - y)..], f.lines.items[0..oldLen]);
|
||||||
var l = Line.init(f.allocator);
|
var l = try Line.init(f.allocator);
|
||||||
try l.set(x, v);
|
try l.set(x, v);
|
||||||
f.lines.items[0] = l;
|
f.lines.items[0] = l;
|
||||||
var i: usize = 1;
|
var i: usize = 1;
|
||||||
while (i < @intCast(usize, f.y - y)) : (i += 1) {
|
while (i < @intCast(usize, f.y - y)) : (i += 1) {
|
||||||
f.lines.items[i] = Line.init(f.allocator);
|
f.lines.items[i] = try Line.init(f.allocator);
|
||||||
}
|
}
|
||||||
f.y = y;
|
f.y = y;
|
||||||
}
|
}
|
||||||
|
@ -371,6 +383,36 @@ const Field = struct {
|
||||||
try std.testing.expectEqual(f.get(8, 2), '2');
|
try std.testing.expectEqual(f.get(8, 2), '2');
|
||||||
try std.testing.expectEqual(f.get(9, 2), ' ');
|
try std.testing.expectEqual(f.get(9, 2), ' ');
|
||||||
}
|
}
|
||||||
|
pub fn step(f: *Field, x: i64, y: i64, dx: i64, dy: i64) struct { x: i64, y: i64 } {
|
||||||
|
var a = x + dx;
|
||||||
|
var b = y + dy;
|
||||||
|
if (f.isIn(a, b)) return .{ .x = a, .y = b };
|
||||||
|
// # We are stepping outside, we need to wrap the Lahey-space
|
||||||
|
a = x;
|
||||||
|
b = y;
|
||||||
|
while (true) {
|
||||||
|
var c = a - dx;
|
||||||
|
var d = b - dy;
|
||||||
|
if (!f.isIn(c, d)) return .{ .x = a, .y = b };
|
||||||
|
a = c;
|
||||||
|
b = d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
test "step" {
|
||||||
|
const minimal = std.io.fixedBufferStream("@").reader();
|
||||||
|
var f = try Field.init(std.testing.allocator);
|
||||||
|
defer f.deinit();
|
||||||
|
try f.load(minimal);
|
||||||
|
try std.testing.expectEqual(f.step(0, 0, 0, 0), .{ .x = 0, .y = 0 });
|
||||||
|
try std.testing.expectEqual(f.step(0, 0, 1, 0), .{ .x = 0, .y = 0 });
|
||||||
|
const hello = std.io.fixedBufferStream("64+\"!dlroW ,olleH\">:#,_@\n").reader();
|
||||||
|
var fHello = try Field.init(std.testing.allocator);
|
||||||
|
defer fHello.deinit();
|
||||||
|
try fHello.load(hello);
|
||||||
|
try std.testing.expectEqual(fHello.step(3, 0, 0, 0), .{ .x = 3, .y = 0 });
|
||||||
|
try std.testing.expectEqual(fHello.step(3, 0, 1, 0), .{ .x = 4, .y = 0 });
|
||||||
|
try std.testing.expectEqual(fHello.step(0, 0, -1, 0), .{ .x = 23, .y = 0 });
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
test "all" {
|
test "all" {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const field = @import("field.zig");
|
const field = @import("field.zig");
|
||||||
|
const pointer = @import("pointer.zig");
|
||||||
const stackStack = @import("stackStack.zig");
|
const stackStack = @import("stackStack.zig");
|
||||||
|
|
||||||
pub fn main() anyerror!void {
|
pub fn main() anyerror!void {
|
||||||
|
|
|
@ -2,12 +2,14 @@ const std = @import("std");
|
||||||
const vector = std.meta.Vector(2, i64);
|
const vector = std.meta.Vector(2, i64);
|
||||||
|
|
||||||
pub const Stack = struct {
|
pub const Stack = struct {
|
||||||
|
allocator: std.mem.Allocator,
|
||||||
data: std.ArrayList(i64),
|
data: std.ArrayList(i64),
|
||||||
pub fn clear(self: *Stack) void {
|
pub fn clear(self: *Stack) void {
|
||||||
self.data.clearRetainingCapacity();
|
self.data.clearRetainingCapacity();
|
||||||
}
|
}
|
||||||
pub fn deinit(self: *Stack) void {
|
pub fn deinit(self: *Stack) void {
|
||||||
self.data.deinit();
|
self.data.deinit();
|
||||||
|
self.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
pub fn duplicate(self: *Stack) !void {
|
pub fn duplicate(self: *Stack) !void {
|
||||||
if (self.data.items.len > 0) {
|
if (self.data.items.len > 0) {
|
||||||
|
@ -15,7 +17,7 @@ pub const Stack = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
test "duplicate" {
|
test "duplicate" {
|
||||||
var s = Stack.init(std.testing.allocator);
|
var s = try Stack.init(std.testing.allocator);
|
||||||
defer s.deinit();
|
defer s.deinit();
|
||||||
try s.duplicate();
|
try s.duplicate();
|
||||||
try std.testing.expectEqual(s.popVector(), @as(vector, [2]i64{ 0, 0 }));
|
try std.testing.expectEqual(s.popVector(), @as(vector, [2]i64{ 0, 0 }));
|
||||||
|
@ -25,10 +27,11 @@ pub const Stack = struct {
|
||||||
try std.testing.expectEqual(s.popVector(), @as(vector, [2]i64{ 2, 2 }));
|
try std.testing.expectEqual(s.popVector(), @as(vector, [2]i64{ 2, 2 }));
|
||||||
try std.testing.expectEqual(s.popVector(), @as(vector, [2]i64{ 1, 2 }));
|
try std.testing.expectEqual(s.popVector(), @as(vector, [2]i64{ 1, 2 }));
|
||||||
}
|
}
|
||||||
pub fn init(allocator: std.mem.Allocator) Stack {
|
pub fn init(allocator: std.mem.Allocator) !*Stack {
|
||||||
return Stack{
|
var s = try allocator.create(Stack);
|
||||||
.data = std.ArrayList(i64).init(allocator),
|
s.allocator = allocator;
|
||||||
};
|
s.data = std.ArrayList(i64).init(allocator);
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
pub fn pop(self: *Stack) i64 {
|
pub fn pop(self: *Stack) i64 {
|
||||||
return if (self.data.popOrNull()) |v| v else 0;
|
return if (self.data.popOrNull()) |v| v else 0;
|
||||||
|
@ -45,7 +48,7 @@ pub const Stack = struct {
|
||||||
try self.data.appendSlice(v[0..]);
|
try self.data.appendSlice(v[0..]);
|
||||||
}
|
}
|
||||||
test "pushVector" {
|
test "pushVector" {
|
||||||
var s = Stack.init(std.testing.allocator);
|
var s = try Stack.init(std.testing.allocator);
|
||||||
defer s.deinit();
|
defer s.deinit();
|
||||||
try s.pushVector([2]i64{ 1, -1 });
|
try s.pushVector([2]i64{ 1, -1 });
|
||||||
try s.pushVector([2]i64{ 2, -2 });
|
try s.pushVector([2]i64{ 2, -2 });
|
||||||
|
@ -60,7 +63,7 @@ pub const Stack = struct {
|
||||||
try self.pushVector([2]i64{ v[1], v[0] });
|
try self.pushVector([2]i64{ v[1], v[0] });
|
||||||
}
|
}
|
||||||
test "swap" {
|
test "swap" {
|
||||||
var s = Stack.init(std.testing.allocator);
|
var s = try Stack.init(std.testing.allocator);
|
||||||
defer s.deinit();
|
defer s.deinit();
|
||||||
try s.swap();
|
try s.swap();
|
||||||
try std.testing.expectEqual(s.popVector(), @as(vector, [2]i64{ 0, 0 }));
|
try std.testing.expectEqual(s.popVector(), @as(vector, [2]i64{ 0, 0 }));
|
||||||
|
|
|
@ -1,25 +1,27 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const stack = @import("stack.zig");
|
const stack = @import("stack.zig");
|
||||||
const vector = std.meta.Vector(2, i64);
|
|
||||||
|
|
||||||
pub const StackStack = struct {
|
pub const StackStack = struct {
|
||||||
data: std.ArrayList(stack.Stack),
|
allocator: std.mem.Allocator,
|
||||||
|
data: std.ArrayList(*stack.Stack),
|
||||||
toss: *stack.Stack,
|
toss: *stack.Stack,
|
||||||
pub fn deinit(self: *StackStack) void {
|
pub fn deinit(self: *StackStack) void {
|
||||||
for (self.data.items) |*s| {
|
for (self.data.items) |s| {
|
||||||
s.deinit();
|
s.deinit();
|
||||||
}
|
}
|
||||||
self.data.deinit();
|
self.data.deinit();
|
||||||
|
self.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
pub fn init(allocator: std.mem.Allocator) !StackStack {
|
pub fn init(allocator: std.mem.Allocator) !*StackStack {
|
||||||
var ss = std.ArrayList(stack.Stack).init(allocator);
|
var ss = try allocator.create(StackStack);
|
||||||
errdefer ss.deinit();
|
errdefer allocator.destroy(ss);
|
||||||
var s = try ss.addOne();
|
ss.allocator = allocator;
|
||||||
s.* = stack.Stack.init(allocator);
|
ss.data = std.ArrayList(*stack.Stack).init(allocator);
|
||||||
return StackStack{
|
errdefer ss.data.deinit();
|
||||||
.data = ss,
|
var s = try ss.data.addOne();
|
||||||
.toss = s,
|
s.* = try stack.Stack.init(allocator);
|
||||||
};
|
ss.toss = s.*;
|
||||||
|
return ss;
|
||||||
}
|
}
|
||||||
pub inline fn toss(self: *StackStack) *stack.Stack {
|
pub inline fn toss(self: *StackStack) *stack.Stack {
|
||||||
return self.toss;
|
return self.toss;
|
||||||
|
|
Loading…
Add table
Reference in a new issue