|
| 1 | +// ┌─────────────────────────────────────────────────┐ |
| 2 | +// │ (c) 2026 Linuxperoxo • FILE: allocator.zig │ |
| 3 | +// │ Author: Linuxperoxo │ |
| 4 | +// └─────────────────────────────────────────────────┘ |
| 5 | + |
| 6 | +pub const Err_T: type = error { |
| 7 | + InitFailed, |
| 8 | + IndexOutBounds, |
| 9 | + WithoutMemory, |
| 10 | + AlreadyInitialized, |
| 11 | + NoNInitialized, |
| 12 | + InternalError, |
| 13 | +}; |
| 14 | + |
| 15 | +pub const VTable_T: type = struct { |
| 16 | + alloc: *const fn(alloc_self: *anyopaque, len: usize) Err_T![]u8, |
| 17 | + free: *const fn(alloc_self: *anyopaque, ptr: []u8) Err_T!void, |
| 18 | + init: *const fn(alloc_self: *anyopaque) Err_T!void, |
| 19 | + deinit: *const fn(alloc_self: *anyopaque) Err_T!void, |
| 20 | + is_initialized: *const fn(alloc_self: *anyopaque) bool, |
| 21 | +}; |
| 22 | + |
| 23 | +pub const Allocator_T: type = struct { |
| 24 | + vtable: *const VTable_T, |
| 25 | + private: *anyopaque, |
| 26 | + |
| 27 | + pub fn alloc(self: Allocator_T, comptime T: type, num: usize) Err_T![]T { |
| 28 | + return @alignCast(@ptrCast( |
| 29 | + (try self.vtable.alloc(self.private, num))[0..(@sizeOf(T) * num)] |
| 30 | + )); |
| 31 | + } |
| 32 | + |
| 33 | + pub fn free(self: Allocator_T, ptr: anytype) Err_T!void { |
| 34 | + const ptr_size, const ptr_child = comptime sw: switch(@typeInfo(@TypeOf(ptr))) { |
| 35 | + .pointer => |ptr_info| { |
| 36 | + if(ptr_info.size == .c or ptr_info.size == .many) |
| 37 | + continue :sw @typeInfo(void); |
| 38 | + break :sw .{ |
| 39 | + ptr_info.size, |
| 40 | + ptr_info.child |
| 41 | + }; |
| 42 | + }, |
| 43 | + else => @compileError("expect slice or single pointer to free. Found \"" ++ @typeName(@TypeOf(ptr)) ++ "\""), |
| 44 | + }; |
| 45 | + const slice = ptr[0..@sizeOf(ptr_child) * ( |
| 46 | + if(comptime ptr_size == .one) 1 else ptr.len |
| 47 | + )]; |
| 48 | + return self.vtable.free(self.private, slice); |
| 49 | + } |
| 50 | + |
| 51 | + pub fn init(self: Allocator_T) Err_T!void { |
| 52 | + return self.vtable.init(self.private); |
| 53 | + } |
| 54 | + |
| 55 | + pub fn deinit(self: Allocator_T) void { |
| 56 | + return self.vtable.deinit(self.private); |
| 57 | + } |
| 58 | + |
| 59 | + pub fn is_initialized(self: Allocator_T) bool { |
| 60 | + return self.vtable.is_initialized(self.private); |
| 61 | + } |
| 62 | +}; |
0 commit comments