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.