Allocator/manager for shared objects?

I think there’s no good solution for preventing copy until Proposal: Pinned Structs · Issue #7769 · ziglang/zig · GitHub or something similar is in the language.

The closest I can do right now is

const std = @import("std");

fn Shared(comptime T: type, comptime Src: std.builtin.SourceLocation) type {
    return struct {
        comptime uniq: std.builtin.SourceLocation = Src,
        ref_count: usize = 0,
        value: *T,

        fn init(value: *T) @This() {
            return .{ .value = value };
        }

        fn deinit(self: *@This()) void {
            if (self.ref_count >= 1) {
                self.ref_count -= 1;
                return;
            }
            self.value.deinit();
            self.* = undefined;
        }

        fn ref(self: *@This()) @This() {
            self.ref_count += 1;
            return self.*;
        }
    };
}

pub fn main() !void {
    var a: u32 = 1;
    var b: u32 = 1;

    var shared = Shared(u32, @src()).init(&a);
    const shared2 = Shared(u32, @src()).init(&b);
    const cpy = shared;
    shared = shared2;

    std.debug.print("{}, {}, {}", .{ a, shared, cpy });
}

Which at least prevents another shared object declaration being copied to another one, but still allows the same declarations copied over each other.

1 Like