aboutsummaryrefslogtreecommitdiff
path: root/examples/arc.ct
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2023-03-07 02:18:26 +0200
committerKimplul <kimi.h.kuparinen@gmail.com>2023-03-07 02:18:26 +0200
commitae5fee63f160643a397d18e9e0658275606bc4d4 (patch)
treef68af302374f9ae3c9dbb28dab5547036252d559 /examples/arc.ct
downloadek-ae5fee63f160643a397d18e9e0658275606bc4d4.tar.gz
ek-ae5fee63f160643a397d18e9e0658275606bc4d4.zip
initial commit
Diffstat (limited to 'examples/arc.ct')
-rw-r--r--examples/arc.ct53
1 files changed, 53 insertions, 0 deletions
diff --git a/examples/arc.ct b/examples/arc.ct
new file mode 100644
index 0000000..8869b42
--- /dev/null
+++ b/examples/arc.ct
@@ -0,0 +1,53 @@
+/* could be non-null instead of raw pointer? */
+typedef atomic_rc [t any] {
+ count *usize;
+ data *t;
+}
+
+/* macros must be 'called' with () */
+pub define arc(t) { struct (atomic_rc[t]) };
+
+pub dereference(a *arc) *#a.data
+{
+ return a.t;
+}
+
+pub init(mut a *arc, e #a.data)
+{
+ new(a.count, 0);
+ a.data = e;
+}
+
+pub init(mut a *arc, b *arc<#a.data>)
+{
+ copy(a, b);
+}
+
+pub deinit(mut a *arc)
+{
+ if atomic_fetch_add(a.count, -1) == 1 {
+ dealloc(a.data);
+ dealloc(a.count);
+ }
+
+ a.count = null;
+ a.data = null;
+}
+
+pub copy(mut a *arc, b *arc<#a.data>)
+{
+ deinit(a);
+ a.count = b.count;
+ a.data = b.data;
+ atomic_fetch_add(b.count, 1);
+}
+
+pub move(mut a *arc, mut b *arc<#a.data>)
+{
+ deinit(a);
+ a.count = b.count;
+ a.data = b.data;
+ /* reference count stays the same */
+ b.count = null;
+ a.count = null;
+}