aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/jv/rc.zig
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2026-01-31 15:31:15 +0900
committernsfisis <nsfisis@gmail.com>2026-01-31 15:47:23 +0900
commit617ddc62aa4d3153850362526069b85bfaf5e59e (patch)
tree6940c577bbecdbf7856ef3c37ab43b256d33da59 /src/jv/rc.zig
parent6be43138338fbe4623c1cd62cf71138873af3a7a (diff)
downloadzgjq-617ddc62aa4d3153850362526069b85bfaf5e59e.tar.gz
zgjq-617ddc62aa4d3153850362526069b85bfaf5e59e.tar.zst
zgjq-617ddc62aa4d3153850362526069b85bfaf5e59e.zip
use reference counting to manage JSON value lifetime
Diffstat (limited to 'src/jv/rc.zig')
-rw-r--r--src/jv/rc.zig40
1 files changed, 40 insertions, 0 deletions
diff --git a/src/jv/rc.zig b/src/jv/rc.zig
new file mode 100644
index 0000000..62a4feb
--- /dev/null
+++ b/src/jv/rc.zig
@@ -0,0 +1,40 @@
+const std = @import("std");
+
+pub fn Rc(comptime T: type) type {
+ const Cell = struct {
+ value: T,
+ ref_count: usize,
+ };
+
+ return struct {
+ const Self = @This();
+
+ cell: *Cell,
+
+ pub fn init(allocator: std.mem.Allocator, value: T) std.mem.Allocator.Error!Self {
+ const cell = try allocator.create(Cell);
+ cell.* = .{ .value = value, .ref_count = 1 };
+ return .{ .cell = cell };
+ }
+
+ pub fn release(self: Self, allocator: std.mem.Allocator) void {
+ self.cell.ref_count -= 1;
+ if (self.cell.ref_count == 0) {
+ allocator.destroy(self.cell);
+ }
+ }
+
+ pub fn retain(self: Self) Self {
+ self.cell.ref_count += 1;
+ return .{ .cell = self.cell };
+ }
+
+ pub fn isUnique(self: Self) bool {
+ return self.cell.ref_count == 1;
+ }
+
+ pub fn get(self: Self) *T {
+ return &self.cell.value;
+ }
+ };
+}