unique_pointer/
refcounter.rs1use std::alloc::Layout;
2use std::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
3use std::convert::{AsMut, AsRef};
4use std::marker::PhantomData;
5use std::ops::{AddAssign, Deref, DerefMut, SubAssign};
6pub struct RefCounter {
15 data: *mut usize,
16}
17
18impl RefCounter {
19 pub fn null() -> RefCounter {
22 RefCounter {
23 data: std::ptr::null_mut::<usize>(),
24 }
25 }
26
27 pub fn new() -> RefCounter {
29 let mut ref_counter = RefCounter::null();
30 ref_counter.incr();
31 ref_counter
32 }
33
34 pub fn reset(&mut self) {
37 self.write(1);
38 }
39
40 pub fn incr(&mut self) {
42 self.incr_by(1);
43 }
44
45 pub fn incr_by(&mut self, by: usize) {
47 self.write(self.read() + by);
48 }
49
50 pub fn decr(&mut self) {
52 self.decr_by(1);
53 }
54
55 pub fn decr_by(&mut self, by: usize) {
57 let data = self.read();
58 if data >= by {
59 self.write(data - by);
60 }
61 }
62
63 pub fn drain(&mut self) {
67 if !self.data.is_null() {
68 unsafe {
69 self.data.drop_in_place();
70 }
71 }
72 }
73
74 pub fn read(&self) -> usize {
75 if self.data.is_null() {
76 0
77 } else {
78 let mut ptr = self.cast_const();
79 unsafe { ptr.read() }
80 }
81 }
82
83 fn alloc(&self) {
84 if !self.data.is_null() {
85 return;
86 }
87
88 let layout = Layout::new::<usize>();
89 let ptr = unsafe {
90 let ptr = std::alloc::alloc(layout);
91 if ptr.is_null() {
92 std::alloc::handle_alloc_error(layout);
93 }
94 ptr as *mut usize
95 };
96 let mut up = unsafe { self.meta_mut() };
97 up.data = ptr;
98 up.write(1);
99 }
100
101 pub fn write(&self, data: usize) {
104 let mut up = unsafe { self.meta_mut() };
105 up.alloc();
106 let mut ptr = up.cast_mut();
107 unsafe {
108 ptr.write(data);
109 }
110 }
111
112 pub fn inner_ref<'c>(&self) -> &'c usize {
116 if self.data.is_null() {
117 &0
118 } else {
119 let ptr = self.cast_const();
120 unsafe { &*ptr }
121 }
122 }
123
124 pub fn inner_mut<'c>(&self) -> &'c mut usize {
128 if self.data.is_null() {
129 self.write(0);
130 }
131 let mut ptr = self.cast_mut();
132 unsafe { &mut *ptr }
133 }
134}
135impl RefCounter {
136 fn cast_mut(&self) -> *mut usize {
138 self.data
139 }
140
141 fn cast_const(&self) -> *const usize {
142 self.data.cast_const()
143 }
144}
145impl From<usize> for RefCounter {
146 fn from(refs: usize) -> RefCounter {
147 let mut ref_counter = RefCounter::new();
148 ref_counter.write(refs);
149 ref_counter
150 }
151}
152impl AsRef<usize> for RefCounter {
153 fn as_ref(&self) -> &usize {
154 self.inner_ref()
155 }
156}
157impl AsMut<usize> for RefCounter {
158 fn as_mut(&mut self) -> &mut usize {
159 if self.data.is_null() {
160 self.write(0);
161 }
162 let mut ptr = self.cast_mut();
163 unsafe { &mut *ptr }
164 }
165}
166impl Deref for RefCounter {
167 type Target = usize;
168
169 fn deref(&self) -> &usize {
170 self.inner_ref()
171 }
172}
173impl DerefMut for RefCounter {
174 fn deref_mut(&mut self) -> &mut usize {
175 self.inner_mut()
176 }
177}
178
179impl Drop for RefCounter {
180 fn drop(&mut self) {
181 self.drain()
182 }
183}
184
185impl Clone for RefCounter {
186 fn clone(&self) -> RefCounter {
187 let mut clone = RefCounter::new();
188 clone.data = self.data;
189 clone
190 }
191}
192
193impl std::fmt::Debug for RefCounter {
194 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
195 write!(
196 f,
197 "{}",
198 [
199 format!("RefCounter@"),
200 format!("{:016x}", self.data.addr()),
201 format!("[data={}]", self.read()),
202 ]
203 .join("")
204 )
205 }
206}
207impl std::fmt::Display for RefCounter {
208 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
209 write!(f, "{}", self.read())
210 }
211}
212
213#[allow(invalid_reference_casting)]
214impl<'c> RefCounter {
215 unsafe fn meta_mut(&'c self) -> &'c mut RefCounter {
218 unsafe {
219 let ptr = self.meta_mut_ptr();
220 let mut up = &mut *ptr;
221 std::mem::transmute::<&mut RefCounter, &'c mut RefCounter>(up)
222 }
223 }
224
225 unsafe fn meta_mut_ptr(&self) -> *mut RefCounter {
227 let ptr = self as *const RefCounter;
228 unsafe {
229 let ptr: *mut RefCounter =
230 std::mem::transmute::<*const RefCounter, *mut RefCounter>(ptr);
231 ptr
232 }
233 }
234}
235
236impl AddAssign<usize> for RefCounter {
237 fn add_assign(&mut self, other: usize) {
238 self.incr_by(other)
239 }
240}
241
242impl SubAssign<usize> for RefCounter {
243 fn sub_assign(&mut self, other: usize) {
244 self.decr_by(other)
245 }
246}
247
248impl PartialOrd<usize> for RefCounter {
249 fn partial_cmp(&self, other: &usize) -> Option<Ordering> {
250 self.read().partial_cmp(other)
251 }
252}
253
254impl PartialEq<usize> for RefCounter {
255 fn eq(&self, other: &usize) -> bool {
256 self.read().eq(other)
257 }
258}
259
260impl PartialOrd for RefCounter {
261 fn partial_cmp(&self, other: &RefCounter) -> Option<Ordering> {
262 self.read().partial_cmp(other.inner_ref())
263 }
264}
265
266impl Ord for RefCounter {
267 fn cmp(&self, other: &RefCounter) -> Ordering {
268 self.read().cmp(other.inner_ref())
269 }
270}
271
272impl PartialEq for RefCounter {
273 fn eq(&self, other: &RefCounter) -> bool {
274 self.read().eq(other.inner_ref())
275 }
276}
277
278impl Eq for RefCounter {}