126 lines
2.5 KiB
Zig
126 lines
2.5 KiB
Zig
pub const ascii = @import("./ascii.zig");
|
|
|
|
pub const asyncio = @import("./asyncio.zig");
|
|
|
|
pub const files = @import("./files.zig");
|
|
|
|
pub const hashes = @import("./hashes.zig");
|
|
|
|
pub const heap = @import("./heap.zig");
|
|
|
|
pub const io = @import("./io.zig");
|
|
|
|
pub const lina = @import("./lina.zig");
|
|
|
|
pub const map = @import("./map.zig");
|
|
|
|
pub const scalars = @import("./scalars.zig");
|
|
|
|
pub const slices = @import("./slices.zig");
|
|
|
|
pub const stack = @import("./stack.zig");
|
|
|
|
const std = @import("std");
|
|
|
|
pub const utf8 = @import("./utf8.zig");
|
|
|
|
pub fn Pool(comptime Value: type) type {
|
|
return struct {
|
|
entries: stack.Sequential(Entry),
|
|
first_free_index: usize = 0,
|
|
|
|
const Entry = union (enum) {
|
|
free_index: usize,
|
|
occupied: Value,
|
|
};
|
|
|
|
pub const Values = struct {
|
|
cursor: usize = 0,
|
|
pool: *const Self,
|
|
|
|
pub fn next(self: *Values) ?*Value {
|
|
while (self.cursor < self.pool.entries.len()) {
|
|
defer self.cursor += 1;
|
|
|
|
switch (self.pool.entries.values[self.cursor]) {
|
|
.free_index => {
|
|
continue;
|
|
},
|
|
|
|
.occupied => |*occupied| {
|
|
return occupied;
|
|
},
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
};
|
|
|
|
const Self = @This();
|
|
|
|
pub fn deinit(self: *Self) void {
|
|
self.entries.deinit();
|
|
|
|
self.* = undefined;
|
|
}
|
|
|
|
pub fn get(self: *Self, key: usize) ?*Value {
|
|
return switch (self.entries.values[key]) {
|
|
.free_index => null,
|
|
.occupied => |*occupied| occupied,
|
|
};
|
|
}
|
|
|
|
pub fn init(allocator: std.mem.Allocator) Self {
|
|
return .{
|
|
.entries = .{.allocator = allocator},
|
|
};
|
|
}
|
|
|
|
pub fn insert(self: *Self, value: Value) std.mem.Allocator.Error!usize {
|
|
const entries_count = self.entries.len();
|
|
|
|
if (self.first_free_index == entries_count) {
|
|
try self.entries.push_grow(.{.occupied = value});
|
|
|
|
self.first_free_index += 1;
|
|
|
|
return entries_count;
|
|
}
|
|
|
|
const insersion_index = self.first_free_index;
|
|
|
|
self.first_free_index = self.entries.values[self.first_free_index].free_index;
|
|
self.entries.values[insersion_index] = .{.occupied = value};
|
|
|
|
return insersion_index;
|
|
}
|
|
|
|
pub fn remove(self: *Self, key: usize) ?Value {
|
|
if (key >= self.entries.len()) {
|
|
return null;
|
|
}
|
|
|
|
switch (self.entries.values[key]) {
|
|
.free_index => {
|
|
return null;
|
|
},
|
|
|
|
.occupied => |occupied| {
|
|
self.entries.values[key] = .{.free_index = self.first_free_index};
|
|
self.first_free_index = key;
|
|
|
|
return occupied;
|
|
},
|
|
}
|
|
}
|
|
|
|
pub fn values(self: *const Self) Values {
|
|
return .{
|
|
.pool = self,
|
|
};
|
|
}
|
|
};
|
|
}
|