1use std::{
2 collections::VecDeque,
3 sync::{atomic::AtomicUsize, Arc, Weak},
4};
5
6use crate::traceable::GCTraceable;
7
8pub struct GCWrapper<T: GCTraceable<T> + 'static> {
10 value: T,
11 pub(crate) attached_gc_count: AtomicUsize,
12}
13
14impl<T: GCTraceable<T> + 'static> GCWrapper<T> {
15 pub fn new(value: T) -> Self {
16 Self {
17 value,
18 attached_gc_count: AtomicUsize::new(0),
19 }
20 }
21
22 pub fn value(&self) -> &T {
23 &self.value
24 }
25
26 pub fn value_mut(&mut self) -> &mut T {
27 &mut self.value
28 }
29}
30
31#[allow(dead_code)]
32pub trait GCRef {
33 fn strong_ref(&self) -> usize;
34 fn weak_ref(&self) -> usize;
35}
36
37pub struct GCArc<T: GCTraceable<T> + 'static> {
38 inner: Arc<GCWrapper<T>>,
39}
40
41impl<T: GCTraceable<T> + 'static> Into<GCArc<T>> for Arc<GCWrapper<T>> {
42 fn into(self) -> GCArc<T> {
43 GCArc { inner: self }
44 }
45}
46
47impl<T: GCTraceable<T> + 'static> From<GCArc<T>> for Arc<GCWrapper<T>> {
48 fn from(gc_arc: GCArc<T>) -> Self {
49 gc_arc.inner
50 }
51}
52
53#[allow(dead_code)]
54impl<T> GCArc<T>
55where
56 T: GCTraceable<T> + 'static,
57{
58 pub fn new(obj: T) -> Self {
59 Self {
60 inner: Arc::new(GCWrapper::new(obj)),
61 }
62 }
63 pub fn as_weak(&self) -> GCArcWeak<T> {
64 GCArcWeak {
65 inner: Arc::downgrade(&self.inner),
66 }
67 }
68
69 pub fn as_ref(&self) -> &T {
70 &self.inner.value
71 }
72
73 pub fn get_mut(&mut self) -> &mut T {
74 self.try_as_mut().expect(
75 "Cannot get mutable reference: GCArc is not unique. \
76 Strong count > 1 or weak references exist. \
77 Consider using interior mutability (RefCell, Mutex, etc.) instead.",
78 )
79 }
80
81 pub fn try_as_mut(&mut self) -> Option<&mut T> {
82 Arc::get_mut(&mut self.inner).map(|wrapper| &mut wrapper.value)
83 }
84
85 fn collect(&self, queue: &mut VecDeque<GCArcWeak<T>>) {
86 self.inner.value.collect(queue);
87 }
88
89 pub(crate) fn ptr_eq(a: &GCArc<T>, b: &GCArc<T>) -> bool {
90 Arc::ptr_eq(&a.inner, &b.inner)
91 }
92
93 #[inline(always)]
94 pub(crate) fn inner(&self) -> &GCWrapper<T> {
95 &self.inner
96 }
97}
98
99impl<T> Clone for GCArc<T>
100where
101 T: GCTraceable<T> + 'static,
102{
103 fn clone(&self) -> Self {
104 Self {
105 inner: self.inner.clone(),
106 }
107 }
108}
109
110impl<T> GCRef for GCArc<T>
111where
112 T: GCTraceable<T> + 'static,
113{
114 fn strong_ref(&self) -> usize {
115 Arc::strong_count(&self.inner)
116 }
117
118 fn weak_ref(&self) -> usize {
119 Arc::weak_count(&self.inner)
120 }
121}
122
123pub struct GCArcWeak<T: GCTraceable<T> + 'static> {
124 inner: Weak<GCWrapper<T>>,
125}
126
127impl<T: GCTraceable<T> + 'static> Into<GCArcWeak<T>> for Weak<GCWrapper<T>> {
128 fn into(self) -> GCArcWeak<T> {
129 GCArcWeak { inner: self }
130 }
131}
132
133impl<T: GCTraceable<T> + 'static> From<GCArcWeak<T>> for Weak<GCWrapper<T>> {
134 fn from(gc_arc_weak: GCArcWeak<T>) -> Self {
135 gc_arc_weak.inner
136 }
137}
138
139#[allow(dead_code)]
140impl<T> GCArcWeak<T>
141where
142 T: GCTraceable<T> + 'static,
143{
144 pub fn upgrade(&self) -> Option<GCArc<T>> {
145 self.inner.upgrade().map(|inner| GCArc { inner })
146 }
147
148 pub fn is_valid(&self) -> bool {
149 self.inner.strong_count() > 0
150 }
151}
152
153impl<T> Clone for GCArcWeak<T>
154where
155 T: GCTraceable<T> + 'static,
156{
157 fn clone(&self) -> Self {
158 Self {
159 inner: self.inner.clone(),
160 }
161 }
162}
163
164impl<T> GCRef for GCArcWeak<T>
165where
166 T: GCTraceable<T> + 'static,
167{
168 fn strong_ref(&self) -> usize {
169 self.inner.strong_count()
170 }
171
172 fn weak_ref(&self) -> usize {
173 self.inner.weak_count()
174 }
175}