reference_box/
reference_box.rs1pub unsafe fn from_raw<T>(pointer: *mut T) -> Box<T> {
4 assert_eq!(
5 pointer.is_null(),
6 false,
7 "from_raw(): Pointer must not be null!"
8 );
9 assert_eq!(
10 std::mem::size_of::<*mut T>(),
11 std::mem::size_of::<*mut std::ffi::c_void>(),
12 "The pointer must be compatible with void*"
13 );
14 Box::from_raw(pointer)
15}
16
17pub fn into_raw<T>(_box: Box<T>) -> *mut T {
18 assert_eq!(
19 std::mem::size_of::<*mut T>(),
20 std::mem::size_of::<*mut std::ffi::c_void>(),
21 "The pointer must be compatible with void*"
22 );
23 Box::into_raw(_box)
24}
25
26#[derive(Debug)]
27#[repr(C)]
28pub struct ReferenceBoxMut<T> {
29 referenced: *mut T,
30}
31
32impl<T> ReferenceBoxMut<T> {
33 pub fn new(_reference: &mut T) -> Self {
34 let pointer: *mut T = unsafe { std::mem::transmute(_reference) };
35 ReferenceBoxMut {
36 referenced: pointer,
37 }
38 }
39
40 pub fn into_raw(self) -> *mut Self {
41 into_raw(Box::new(self))
42 }
43
44 pub fn boxed(&self) -> *mut T {
45 self.referenced
46 }
47
48 pub fn as_ref(&self) -> &T {
49 unsafe { std::mem::transmute(self.referenced) }
50 }
51
52 pub fn as_mut(&self) -> &mut T {
53 unsafe { std::mem::transmute(self.referenced) }
54 }
55}
56
57pub trait ReferenceBoxMutPointer<T> {
58 fn with<Block, Return>(&self, block: Block) -> Return
59 where
60 Block: FnOnce(&mut T) -> Return;
61 fn with_value<Block, Return>(&self, block: Block) -> Return
62 where
63 Block: FnOnce(T) -> Return,
64 T: Copy;
65 fn with_not_null<Block>(&self, block: Block)
66 where
67 Block: FnOnce(&mut T);
68 fn with_not_null_return<Block, Return>(&self, default: Return, block: Block) -> Return
69 where
70 Block: FnOnce(&mut T) -> Return;
71 fn with_not_null_return_block<DefaultBlock, Block, Return>(
72 &self,
73 default: DefaultBlock,
74 block: Block,
75 ) -> Return
76 where
77 DefaultBlock: FnOnce() -> Return,
78 Block: FnOnce(&mut T) -> Return;
79 fn drop(self);
80}
81
82impl<T> ReferenceBoxMutPointer<T> for *mut ReferenceBoxMut<T> {
83 fn with<Block, Return>(&self, block: Block) -> Return
84 where
85 Block: FnOnce(&mut T) -> Return,
86 {
87 assert_eq!(self.is_null(), false, "Pointer must not be null!");
88
89 let mut reference_box = unsafe { from_raw(*self) };
90 let referenced_object: &mut T = unsafe { std::mem::transmute(reference_box.referenced) };
91 let result: Return = block(referenced_object);
92
93 let referenced_object_pointer: *mut T = unsafe { std::mem::transmute(referenced_object) };
94 reference_box.referenced = referenced_object_pointer;
95
96 let new_pointer = into_raw(reference_box);
97 assert_eq!(new_pointer, *self, "The pointer must not change");
98
99 result
100 }
101
102 fn with_value<Block, Return>(&self, block: Block) -> Return
103 where
104 Block: FnOnce(T) -> Return,
105 T: Copy,
106 {
107 assert_eq!(self.is_null(), false, "Pointer must not be null!");
108
109 let reference_box = unsafe { from_raw(*self) };
110 let referenced_object = *&mut unsafe { *reference_box.referenced };
111 let result: Return = block(referenced_object);
112
113 let new_pointer = into_raw(reference_box);
114 assert_eq!(new_pointer, *self, "The pointer must not change");
115
116 result
117 }
118
119 fn with_not_null<Block>(&self, block: Block)
120 where
121 Block: FnOnce(&mut T),
122 {
123 if self.is_null() {
124 return;
125 }
126 self.with(|boxed_object| {
127 block(boxed_object);
128 });
129 }
130
131 fn with_not_null_return<Block, Return>(&self, default: Return, block: Block) -> Return
132 where
133 Block: FnOnce(&mut T) -> Return,
134 {
135 if self.is_null() {
136 return default;
137 }
138 self.with(block)
139 }
140
141 fn with_not_null_return_block<DefaultBlock, Block, Return>(
142 &self,
143 default: DefaultBlock,
144 block: Block,
145 ) -> Return
146 where
147 DefaultBlock: FnOnce() -> Return,
148 Block: FnOnce(&mut T) -> Return,
149 {
150 if self.is_null() {
151 return default();
152 }
153 self.with(block)
154 }
155
156 fn drop(self) {
157 let reference_box = unsafe { from_raw(self) };
158 std::mem::drop(reference_box);
159 }
160}
161
162#[derive(Debug)]
163#[repr(C)]
164pub struct ReferenceBox<T> {
165 referenced: *const T,
166}
167
168impl<T> ReferenceBox<T> {
169 pub fn new(_reference: &T) -> Self {
170 let pointer: *const T = unsafe { std::mem::transmute(_reference) };
171 Self {
172 referenced: pointer,
173 }
174 }
175
176 pub fn into_raw(self) -> *mut Self {
177 into_raw(Box::new(self))
178 }
179
180 pub fn boxed(&self) -> *const T {
181 self.referenced
182 }
183
184 pub fn as_ref(&self) -> &T {
185 unsafe { std::mem::transmute(self.referenced) }
186 }
187}
188
189pub trait ReferenceBoxPointer<T> {
190 fn with<Block, Return>(&self, block: Block) -> Return
191 where
192 Block: FnOnce(&T) -> Return;
193 fn with_not_null<Block>(&self, block: Block)
194 where
195 Block: FnOnce(&T);
196 fn with_not_null_return<Block, Return>(&self, default: Return, block: Block) -> Return
197 where
198 Block: FnOnce(&T) -> Return;
199 fn with_not_null_return_block<DefaultBlock, Block, Return>(
200 &self,
201 default: DefaultBlock,
202 block: Block,
203 ) -> Return
204 where
205 DefaultBlock: FnOnce() -> Return,
206 Block: FnOnce(&T) -> Return;
207 fn drop(self);
208}
209
210impl<T> ReferenceBoxPointer<T> for *mut ReferenceBox<T> {
211 fn with<Block, Return>(&self, block: Block) -> Return
212 where
213 Block: FnOnce(&T) -> Return,
214 {
215 assert_eq!(self.is_null(), false, "Pointer must not be null!");
216
217 let mut reference_box = unsafe { from_raw(*self) };
218 let referenced_object: &mut T = unsafe { std::mem::transmute(reference_box.referenced) };
219 let result: Return = block(referenced_object);
220
221 let referenced_object_pointer: *const T = unsafe { std::mem::transmute(referenced_object) };
222 reference_box.referenced = referenced_object_pointer;
223
224 let new_pointer = into_raw(reference_box);
225 assert_eq!(new_pointer, *self, "The pointer must not change");
226
227 result
228 }
229
230 fn with_not_null<Block>(&self, block: Block)
231 where
232 Block: FnOnce(&T),
233 {
234 if self.is_null() {
235 return;
236 }
237 self.with(|boxed_object| {
238 block(boxed_object);
239 });
240 }
241
242 fn with_not_null_return<Block, Return>(&self, default: Return, block: Block) -> Return
243 where
244 Block: FnOnce(&T) -> Return,
245 {
246 if self.is_null() {
247 return default;
248 }
249 self.with(block)
250 }
251
252 fn with_not_null_return_block<DefaultBlock, Block, Return>(
253 &self,
254 default: DefaultBlock,
255 block: Block,
256 ) -> Return
257 where
258 DefaultBlock: FnOnce() -> Return,
259 Block: FnOnce(&T) -> Return,
260 {
261 if self.is_null() {
262 return default();
263 }
264 self.with(block)
265 }
266
267 fn drop(self) {
268 let reference_box = unsafe { from_raw(self) };
269 std::mem::drop(reference_box);
270 }
271}