aboutsummaryrefslogtreecommitdiff
path: root/examples/arc.ct
blob: 8869b42e141be3dc592512815fb166a0069ffe05 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
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;
}