mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 18:38:55 +00:00
81 lines
2.1 KiB
Zig
81 lines
2.1 KiB
Zig
const std = @import("std");
|
|
|
|
pub fn RefCount(comptime Type: type, comptime deinit_on_zero: bool) type {
|
|
return struct {
|
|
const AllocatorType = if (deinit_on_zero) std.mem.Allocator else void;
|
|
|
|
value: Type,
|
|
count: i32 = 1,
|
|
allocator: AllocatorType = undefined,
|
|
|
|
pub inline fn ref(this: *@This()) void {
|
|
this.count += 1;
|
|
}
|
|
|
|
/// Create a new reference counted value.
|
|
pub inline fn init(
|
|
value: Type,
|
|
allocator: std.mem.Allocator,
|
|
) !*@This() {
|
|
var ptr = try allocator.create(@This());
|
|
ptr.create(value, allocator);
|
|
return ptr;
|
|
}
|
|
|
|
/// Get the value & increment the reference count.
|
|
pub inline fn get(this: *@This()) *Type {
|
|
std.debug.assert(this.count >= 0);
|
|
|
|
this.count += 1;
|
|
return this.leak();
|
|
}
|
|
|
|
/// Get the value without incrementing the reference count.
|
|
pub inline fn leak(this: *@This()) *Type {
|
|
return &this.value;
|
|
}
|
|
|
|
pub inline fn getRef(this: *@This()) *@This() {
|
|
this.count += 1;
|
|
return this;
|
|
}
|
|
|
|
pub inline fn create(
|
|
this: *@This(),
|
|
value: Type,
|
|
allocator: AllocatorType,
|
|
) void {
|
|
this.* = .{
|
|
.value = value,
|
|
.allocator = allocator,
|
|
.count = 1,
|
|
};
|
|
}
|
|
|
|
pub inline fn deinit(this: *@This()) void {
|
|
if (comptime @hasDecl(Type, "deinit")) {
|
|
this.value.deinit();
|
|
}
|
|
|
|
if (comptime deinit_on_zero) {
|
|
var allocator = this.allocator;
|
|
allocator.destroy(this);
|
|
}
|
|
}
|
|
|
|
pub inline fn deref(this: *@This()) void {
|
|
this.count -= 1;
|
|
|
|
std.debug.assert(this.count >= 0);
|
|
|
|
if (comptime deinit_on_zero) {
|
|
if (this.count <= 0) {
|
|
this.deinit();
|
|
}
|
|
}
|
|
}
|
|
|
|
pub const Type = Type;
|
|
};
|
|
}
|