2024-11-06 15:44:28 +01:00
|
|
|
const std = @import("std");
|
2024-11-09 01:13:32 +01:00
|
|
|
const Allocator = std.mem.Allocator;
|
2024-11-09 22:28:42 +01:00
|
|
|
const expect = std.testing.expect;
|
|
|
|
const testingAllocator = std.testing.allocator;
|
|
|
|
|
2024-11-06 15:44:28 +01:00
|
|
|
|
2024-11-09 01:13:32 +01:00
|
|
|
pub fn LList(comptime T: type) type {
|
2024-11-06 15:44:28 +01:00
|
|
|
return struct {
|
|
|
|
const Self = @This();
|
2024-11-08 20:26:58 +01:00
|
|
|
first: ?*Node(T),
|
2024-11-09 01:13:32 +01:00
|
|
|
alloc: Allocator,
|
2024-11-09 22:28:42 +01:00
|
|
|
counter: u64,
|
2024-11-08 20:26:58 +01:00
|
|
|
|
2024-11-09 19:32:04 +01:00
|
|
|
|
2024-11-09 01:13:32 +01:00
|
|
|
pub fn init(this: *Self, allocator: Allocator) !void {
|
|
|
|
this.alloc = allocator;
|
2024-11-09 19:32:04 +01:00
|
|
|
this.first = null;
|
2024-11-09 22:28:42 +01:00
|
|
|
this.counter = 0;
|
2024-11-06 15:44:28 +01:00
|
|
|
}
|
|
|
|
|
2024-11-09 19:32:04 +01:00
|
|
|
pub fn deinit(this: *Self) !void {
|
|
|
|
|
|
|
|
//? If there is no created Node
|
|
|
|
if (this.first == null) {
|
|
|
|
//? Nothing to do
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
var currentNode: *Node(T) = this.first orelse unreachable;
|
|
|
|
|
|
|
|
while (true) {
|
2024-11-09 22:28:42 +01:00
|
|
|
if (currentNode.next == null){
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2024-11-09 19:32:04 +01:00
|
|
|
const nextNode = currentNode.next orelse unreachable;
|
|
|
|
var breakNext = false;
|
|
|
|
|
|
|
|
if (nextNode.next == null) {
|
|
|
|
breakNext = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
try currentNode.deinit();
|
|
|
|
|
|
|
|
currentNode = nextNode;
|
|
|
|
|
|
|
|
if (breakNext == true) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
try currentNode.deinit();
|
2024-11-09 22:28:42 +01:00
|
|
|
this.counter = 0;
|
2024-11-09 19:32:04 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn add(this: *Self, value: T ) !*Node(T){
|
|
|
|
|
|
|
|
const newNode: *Node(T) = try this.alloc.create(Node(T));
|
|
|
|
try newNode.init(this.alloc, value, this.first);
|
|
|
|
this.first = newNode;
|
|
|
|
|
2024-11-09 22:28:42 +01:00
|
|
|
this.counter = this.counter + 1;
|
|
|
|
|
2024-11-09 19:32:04 +01:00
|
|
|
return newNode;
|
2024-11-09 01:13:32 +01:00
|
|
|
}
|
|
|
|
|
2024-11-09 22:28:42 +01:00
|
|
|
pub fn size(this: *Self) !u64{
|
2024-11-09 01:13:32 +01:00
|
|
|
|
2024-11-09 22:28:42 +01:00
|
|
|
return this.counter;
|
2024-11-06 15:44:28 +01:00
|
|
|
}
|
2024-11-09 22:28:42 +01:00
|
|
|
|
2024-11-06 15:44:28 +01:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2024-11-09 19:32:04 +01:00
|
|
|
|
2024-11-09 01:13:32 +01:00
|
|
|
pub fn Node(comptime T: type) type {
|
2024-11-06 15:44:28 +01:00
|
|
|
return struct {
|
|
|
|
const Self = @This();
|
2024-11-09 19:32:04 +01:00
|
|
|
alloc: Allocator,
|
2024-11-09 22:28:42 +01:00
|
|
|
next: ?*Self,
|
2024-11-09 19:32:04 +01:00
|
|
|
value: *T,
|
2024-11-06 15:44:28 +01:00
|
|
|
|
2024-11-09 19:32:04 +01:00
|
|
|
pub fn init(this: *Self, allocator: Allocator, value: T, next: ?*Self) !void {
|
|
|
|
this.alloc = allocator;
|
2024-11-09 01:13:32 +01:00
|
|
|
this.next = next;
|
2024-11-09 19:32:04 +01:00
|
|
|
|
|
|
|
this.value = try this.alloc.create(T);
|
|
|
|
this.value.* = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn deinit(this: *Self) !void {
|
|
|
|
this.alloc.destroy(this.value);
|
|
|
|
this.alloc.destroy(this);
|
2024-11-06 16:07:42 +01:00
|
|
|
}
|
|
|
|
|
2024-11-09 19:32:04 +01:00
|
|
|
|
2024-11-06 15:44:28 +01:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2024-11-10 20:24:27 +01:00
|
|
|
test "init()" {
|
|
|
|
|
|
|
|
var testList: LList(u64) = undefined;
|
|
|
|
try testList.init(testingAllocator);
|
|
|
|
|
|
|
|
try expect(testList.first == null);
|
|
|
|
try expect(testList.counter == 0);
|
|
|
|
|
|
|
|
try testList.deinit();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
test "deinit()" {
|
2024-11-09 22:28:42 +01:00
|
|
|
|
|
|
|
var testList: LList(u64) = undefined;
|
|
|
|
try testList.init(testingAllocator);
|
|
|
|
|
|
|
|
_ = try testList.add(1);
|
|
|
|
_ = try testList.add(2);
|
|
|
|
|
|
|
|
|
|
|
|
try testList.deinit();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2024-11-10 20:24:27 +01:00
|
|
|
test "add()" {
|
|
|
|
|
|
|
|
var testList: LList(u64) = undefined;
|
|
|
|
try testList.init(testingAllocator);
|
|
|
|
|
|
|
|
const firstNode = try testList.add(1);
|
|
|
|
const secondNode = try testList.add(2);
|
|
|
|
const thirdNode = try testList.add(3);
|
|
|
|
const fourtNode = try testList.add(4);
|
|
|
|
|
|
|
|
try expect(firstNode.value.* == 1);
|
|
|
|
try expect(secondNode.value.* == 2);
|
|
|
|
try expect(thirdNode.value.* == 3);
|
|
|
|
try expect(fourtNode.value.* == 4);
|
|
|
|
|
|
|
|
try testList.deinit();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2024-11-09 22:28:42 +01:00
|
|
|
|
2024-11-10 20:24:27 +01:00
|
|
|
test "size()" {
|
2024-11-08 21:03:04 +01:00
|
|
|
|
|
|
|
var testList: LList(u64) = undefined;
|
2024-11-09 22:28:42 +01:00
|
|
|
try testList.init(testingAllocator);
|
|
|
|
|
2024-11-09 19:32:04 +01:00
|
|
|
_ = try testList.add(1);
|
|
|
|
_ = try testList.add(2);
|
|
|
|
_ = try testList.add(3);
|
|
|
|
_ = try testList.add(4);
|
|
|
|
|
2024-11-09 22:28:42 +01:00
|
|
|
try expect(try testList.size() == 4);
|
2024-11-09 01:13:32 +01:00
|
|
|
|
2024-11-09 19:32:04 +01:00
|
|
|
try testList.deinit();
|
2024-11-09 22:28:42 +01:00
|
|
|
|
2024-11-09 01:13:32 +01:00
|
|
|
}
|